diff options
author | Christian Grothoff <christian@grothoff.org> | 2015-01-17 23:30:08 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2015-01-17 23:30:08 +0000 |
commit | 67733608f6251367c11277b2f2fe0ee9d8281ccc (patch) | |
tree | 42f49e5706ab36e49a25154948b6df303253ecf6 /src/ats | |
parent | f2bbe49b6d6ae46b3981974333f9f60594c3e768 (diff) | |
download | gnunet-67733608f6251367c11277b2f2fe0ee9d8281ccc.tar.gz gnunet-67733608f6251367c11277b2f2fe0ee9d8281ccc.zip |
use modern MQ API, use multipeermap instead of DLL
Diffstat (limited to 'src/ats')
-rw-r--r-- | src/ats/ats_api_scheduling.c | 666 |
1 files changed, 280 insertions, 386 deletions
diff --git a/src/ats/ats_api_scheduling.c b/src/ats/ats_api_scheduling.c index 496a18b12..08155eaef 100644 --- a/src/ats/ats_api_scheduling.c +++ b/src/ats/ats_api_scheduling.c | |||
@@ -27,38 +27,16 @@ | |||
27 | #include "gnunet_ats_service.h" | 27 | #include "gnunet_ats_service.h" |
28 | #include "ats.h" | 28 | #include "ats.h" |
29 | 29 | ||
30 | |||
31 | #define INTERFACE_PROCESSING_INTERVALL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1) | ||
32 | |||
33 | #define NOT_FOUND 0 | ||
34 | |||
35 | /** | 30 | /** |
36 | * Message in linked list we should send to the ATS service. The | 31 | * How frequently do we scan the interfaces for changes to the addresses? |
37 | * actual binary message follows this struct. | ||
38 | */ | 32 | */ |
39 | struct PendingMessage | 33 | #define INTERFACE_PROCESSING_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 2) |
40 | { | ||
41 | |||
42 | /** | ||
43 | * Kept in a DLL. | ||
44 | */ | ||
45 | struct PendingMessage *next; | ||
46 | |||
47 | /** | ||
48 | * Kept in a DLL. | ||
49 | */ | ||
50 | struct PendingMessage *prev; | ||
51 | 34 | ||
52 | /** | ||
53 | * Size of the message. | ||
54 | */ | ||
55 | size_t size; | ||
56 | 35 | ||
57 | /** | 36 | /** |
58 | * Is this the 'ATS_START' message? | 37 | * Session ID we use if there is no session / slot. |
59 | */ | 38 | */ |
60 | int is_init; | 39 | #define NOT_FOUND 0 |
61 | }; | ||
62 | 40 | ||
63 | 41 | ||
64 | /** | 42 | /** |
@@ -83,29 +61,49 @@ struct SessionRecord | |||
83 | }; | 61 | }; |
84 | 62 | ||
85 | 63 | ||
64 | /** | ||
65 | * We keep a list of our local networks so we can answer | ||
66 | * LAN vs. WAN questions. Note: WLAN is not detected yet. | ||
67 | * (maybe we can do that heuristically based on interface | ||
68 | * name in the future?) | ||
69 | */ | ||
86 | struct ATS_Network | 70 | struct ATS_Network |
87 | { | 71 | { |
88 | struct ATS_Network * next; | 72 | /** |
73 | * Kept in a DLL. | ||
74 | */ | ||
75 | struct ATS_Network *next; | ||
89 | 76 | ||
90 | struct ATS_Network * prev; | 77 | /** |
78 | * Kept in a DLL. | ||
79 | */ | ||
80 | struct ATS_Network *prev; | ||
91 | 81 | ||
82 | /** | ||
83 | * Network address. | ||
84 | */ | ||
92 | struct sockaddr *network; | 85 | struct sockaddr *network; |
93 | 86 | ||
87 | /** | ||
88 | * Netmask to determine what is in the LAN. | ||
89 | */ | ||
94 | struct sockaddr *netmask; | 90 | struct sockaddr *netmask; |
95 | 91 | ||
92 | /** | ||
93 | * How long are @e network and @e netmask? | ||
94 | */ | ||
96 | socklen_t length; | 95 | socklen_t length; |
97 | }; | 96 | }; |
98 | 97 | ||
99 | 98 | ||
100 | /** | 99 | /** |
101 | * Handle for address suggestions | 100 | * Handle for ATS address suggestion requests. |
102 | */ | 101 | */ |
103 | struct GNUNET_ATS_SuggestHandle | 102 | struct GNUNET_ATS_SuggestHandle |
104 | { | 103 | { |
105 | struct GNUNET_ATS_SuggestHandle *prev; | 104 | /** |
106 | 105 | * ID of the peer for which address suggestion was requested. | |
107 | struct GNUNET_ATS_SuggestHandle *next; | 106 | */ |
108 | |||
109 | struct GNUNET_PeerIdentity id; | 107 | struct GNUNET_PeerIdentity id; |
110 | }; | 108 | }; |
111 | 109 | ||
@@ -132,14 +130,11 @@ struct GNUNET_ATS_SchedulingHandle | |||
132 | void *suggest_cb_cls; | 130 | void *suggest_cb_cls; |
133 | 131 | ||
134 | /** | 132 | /** |
135 | * DLL for suggestions head | 133 | * Map with the identities of all the peers for which we would |
136 | */ | 134 | * like to have address suggestions. The key is the PID, the |
137 | struct GNUNET_ATS_SuggestHandle *sug_head; | 135 | * value is currently the `struct GNUNET_ATS_SuggestHandle` |
138 | |||
139 | /** | ||
140 | * DLL for suggestions tail | ||
141 | */ | 136 | */ |
142 | struct GNUNET_ATS_SuggestHandle *sug_tail; | 137 | struct GNUNET_CONTAINER_MultiPeerMap *sug_requests; |
143 | 138 | ||
144 | /** | 139 | /** |
145 | * Connection to ATS service. | 140 | * Connection to ATS service. |
@@ -147,27 +142,17 @@ struct GNUNET_ATS_SchedulingHandle | |||
147 | struct GNUNET_CLIENT_Connection *client; | 142 | struct GNUNET_CLIENT_Connection *client; |
148 | 143 | ||
149 | /** | 144 | /** |
150 | * Head of list of messages for the ATS service. | 145 | * Message queue for sending requests to the ATS service. |
151 | */ | ||
152 | struct PendingMessage *pending_head; | ||
153 | |||
154 | /** | ||
155 | * Tail of list of messages for the ATS service | ||
156 | */ | ||
157 | struct PendingMessage *pending_tail; | ||
158 | |||
159 | /** | ||
160 | * Current request for transmission to ATS. | ||
161 | */ | 146 | */ |
162 | struct GNUNET_CLIENT_TransmitHandle *th; | 147 | struct GNUNET_MQ_Handle *mq; |
163 | 148 | ||
164 | /** | 149 | /** |
165 | * Head of network list | 150 | * Head of LAN networks list. |
166 | */ | 151 | */ |
167 | struct ATS_Network *net_head; | 152 | struct ATS_Network *net_head; |
168 | 153 | ||
169 | /** | 154 | /** |
170 | * Tail of network list | 155 | * Tail of LAN networks list. |
171 | */ | 156 | */ |
172 | struct ATS_Network *net_tail; | 157 | struct ATS_Network *net_tail; |
173 | 158 | ||
@@ -185,7 +170,7 @@ struct GNUNET_ATS_SchedulingHandle | |||
185 | struct GNUNET_SCHEDULER_Task *task; | 170 | struct GNUNET_SCHEDULER_Task *task; |
186 | 171 | ||
187 | /** | 172 | /** |
188 | * Task retrieving interfaces from the system | 173 | * Task for periodically refreshing our LAN network list. |
189 | */ | 174 | */ |
190 | struct GNUNET_SCHEDULER_Task *interface_task; | 175 | struct GNUNET_SCHEDULER_Task *interface_task; |
191 | 176 | ||
@@ -194,10 +179,6 @@ struct GNUNET_ATS_SchedulingHandle | |||
194 | */ | 179 | */ |
195 | unsigned int session_array_size; | 180 | unsigned int session_array_size; |
196 | 181 | ||
197 | /** | ||
198 | * Should we reconnect to ATS due to some serious error? | ||
199 | */ | ||
200 | int reconnect; | ||
201 | }; | 182 | }; |
202 | 183 | ||
203 | 184 | ||
@@ -235,101 +216,18 @@ reconnect_task (void *cls, | |||
235 | static void | 216 | static void |
236 | force_reconnect (struct GNUNET_ATS_SchedulingHandle *sh) | 217 | force_reconnect (struct GNUNET_ATS_SchedulingHandle *sh) |
237 | { | 218 | { |
238 | sh->reconnect = GNUNET_NO; | 219 | if (NULL != sh->mq) |
239 | GNUNET_CLIENT_disconnect (sh->client); | ||
240 | sh->client = NULL; | ||
241 | sh->task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, | ||
242 | &reconnect_task, | ||
243 | sh); | ||
244 | } | ||
245 | |||
246 | |||
247 | /** | ||
248 | * Transmit messages from the message queue to the service | ||
249 | * (if there are any, and if we are not already trying). | ||
250 | * | ||
251 | * @param sh handle to use | ||
252 | */ | ||
253 | static void | ||
254 | do_transmit (struct GNUNET_ATS_SchedulingHandle *sh); | ||
255 | |||
256 | |||
257 | /** | ||
258 | * Type of a function to call when we receive a message | ||
259 | * from the service. | ||
260 | * | ||
261 | * @param cls the `struct GNUNET_ATS_SchedulingHandle` | ||
262 | * @param msg message received, NULL on timeout or fatal error | ||
263 | */ | ||
264 | static void | ||
265 | process_ats_message (void *cls, | ||
266 | const struct GNUNET_MessageHeader *msg); | ||
267 | |||
268 | |||
269 | /** | ||
270 | * We can now transmit a message to ATS. Do it. | ||
271 | * | ||
272 | * @param cls the `struct GNUNET_ATS_SchedulingHandle` | ||
273 | * @param size number of bytes we can transmit to ATS | ||
274 | * @param buf where to copy the messages | ||
275 | * @return number of bytes copied into @a buf | ||
276 | */ | ||
277 | static size_t | ||
278 | transmit_message_to_ats (void *cls, | ||
279 | size_t size, | ||
280 | void *buf) | ||
281 | { | ||
282 | struct GNUNET_ATS_SchedulingHandle *sh = cls; | ||
283 | struct PendingMessage *p; | ||
284 | size_t ret; | ||
285 | char *cbuf; | ||
286 | |||
287 | sh->th = NULL; | ||
288 | if ((0 == size) || (NULL == buf)) | ||
289 | { | 220 | { |
290 | force_reconnect (sh); | 221 | GNUNET_MQ_destroy (sh->mq); |
291 | return 0; | 222 | sh->mq = NULL; |
292 | } | 223 | } |
293 | ret = 0; | 224 | if (NULL != sh->client) |
294 | cbuf = buf; | ||
295 | while ((NULL != (p = sh->pending_head)) && (p->size <= size)) | ||
296 | { | 225 | { |
297 | memcpy (&cbuf[ret], | 226 | GNUNET_CLIENT_disconnect (sh->client); |
298 | &p[1], | 227 | sh->client = NULL; |
299 | p->size); | ||
300 | ret += p->size; | ||
301 | size -= p->size; | ||
302 | GNUNET_CONTAINER_DLL_remove (sh->pending_head, | ||
303 | sh->pending_tail, | ||
304 | p); | ||
305 | GNUNET_free (p); | ||
306 | } | 228 | } |
307 | do_transmit (sh); | 229 | sh->task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, |
308 | return ret; | 230 | &reconnect_task, |
309 | } | ||
310 | |||
311 | |||
312 | /** | ||
313 | * Transmit messages from the message queue to the service | ||
314 | * (if there are any, and if we are not already trying). | ||
315 | * | ||
316 | * @param sh handle to use | ||
317 | */ | ||
318 | static void | ||
319 | do_transmit (struct GNUNET_ATS_SchedulingHandle *sh) | ||
320 | { | ||
321 | struct PendingMessage *p; | ||
322 | |||
323 | if (NULL != sh->th) | ||
324 | return; | ||
325 | if (NULL == (p = sh->pending_head)) | ||
326 | return; | ||
327 | if (NULL == sh->client) | ||
328 | return; /* currently reconnecting */ | ||
329 | sh->th = | ||
330 | GNUNET_CLIENT_notify_transmit_ready (sh->client, p->size, | ||
331 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
332 | GNUNET_NO, &transmit_message_to_ats, | ||
333 | sh); | 231 | sh); |
334 | } | 232 | } |
335 | 233 | ||
@@ -371,7 +269,7 @@ find_session (struct GNUNET_ATS_SchedulingHandle *sh, | |||
371 | sizeof (struct GNUNET_PeerIdentity))) | 269 | sizeof (struct GNUNET_PeerIdentity))) |
372 | { | 270 | { |
373 | GNUNET_break (0); | 271 | GNUNET_break (0); |
374 | sh->reconnect = GNUNET_YES; | 272 | force_reconnect (sh); |
375 | return NULL; | 273 | return NULL; |
376 | } | 274 | } |
377 | /* This check exploits the fact that first field of a session object | 275 | /* This check exploits the fact that first field of a session object |
@@ -381,9 +279,11 @@ find_session (struct GNUNET_ATS_SchedulingHandle *sh, | |||
381 | memcmp (peer, sh->session_array[session_id].session, | 279 | memcmp (peer, sh->session_array[session_id].session, |
382 | sizeof (struct GNUNET_PeerIdentity))) | 280 | sizeof (struct GNUNET_PeerIdentity))) |
383 | { | 281 | { |
384 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-scheduling-api", | 282 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
385 | "Session %p belongs to peer `%s'\n", | 283 | "ats-scheduling-api", |
386 | sh->session_array[session_id].session, GNUNET_i2s_full ((struct GNUNET_PeerIdentity *) &sh->session_array[session_id].peer)); | 284 | "Session %p belongs to peer `%s'\n", |
285 | sh->session_array[session_id].session, | ||
286 | GNUNET_i2s_full ((struct GNUNET_PeerIdentity *) &sh->session_array[session_id].peer)); | ||
387 | /* | 287 | /* |
388 | GNUNET_break (0); | 288 | GNUNET_break (0); |
389 | sh->reconnect = GNUNET_YES; | 289 | sh->reconnect = GNUNET_YES; |
@@ -536,18 +436,18 @@ release_session (struct GNUNET_ATS_SchedulingHandle *sh, | |||
536 | uint32_t session_id, | 436 | uint32_t session_id, |
537 | const struct GNUNET_PeerIdentity *peer) | 437 | const struct GNUNET_PeerIdentity *peer) |
538 | { | 438 | { |
539 | 439 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | |
540 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-scheduling-api", | 440 | "ats-scheduling-api", |
541 | "Release sessionID %u from peer %s in %p\n", | 441 | "Release sessionID %u from peer %s in %p\n", |
542 | (unsigned int) session_id, GNUNET_i2s (peer), sh); | 442 | (unsigned int) session_id, |
543 | 443 | GNUNET_i2s (peer), | |
444 | sh); | ||
544 | if (session_id >= sh->session_array_size) | 445 | if (session_id >= sh->session_array_size) |
545 | { | 446 | { |
546 | GNUNET_break (0); | 447 | GNUNET_break (0); |
547 | sh->reconnect = GNUNET_YES; | 448 | force_reconnect (sh); |
548 | return; | 449 | return; |
549 | } | 450 | } |
550 | |||
551 | /* this slot should have been removed from remove_session before */ | 451 | /* this slot should have been removed from remove_session before */ |
552 | GNUNET_assert (sh->session_array[session_id].session == NULL); | 452 | GNUNET_assert (sh->session_array[session_id].session == NULL); |
553 | 453 | ||
@@ -556,33 +456,48 @@ release_session (struct GNUNET_ATS_SchedulingHandle *sh, | |||
556 | sizeof (struct GNUNET_PeerIdentity))) | 456 | sizeof (struct GNUNET_PeerIdentity))) |
557 | { | 457 | { |
558 | GNUNET_break (0); | 458 | GNUNET_break (0); |
559 | sh->reconnect = GNUNET_YES; | 459 | force_reconnect (sh); |
560 | return; | 460 | return; |
561 | } | 461 | } |
562 | sh->session_array[session_id].slot_used = GNUNET_NO; | 462 | sh->session_array[session_id].slot_used = GNUNET_NO; |
563 | memset (&sh->session_array[session_id].peer, 0, | 463 | memset (&sh->session_array[session_id].peer, |
464 | 0, | ||
564 | sizeof (struct GNUNET_PeerIdentity)); | 465 | sizeof (struct GNUNET_PeerIdentity)); |
565 | } | 466 | } |
566 | 467 | ||
567 | 468 | ||
469 | /** | ||
470 | * Type of a function to call when we receive a session release | ||
471 | * message from the service. | ||
472 | * | ||
473 | * @param cls the `struct GNUNET_ATS_SchedulingHandle` | ||
474 | * @param msg message received, NULL on timeout or fatal error | ||
475 | */ | ||
568 | static void | 476 | static void |
569 | process_release_message (struct GNUNET_ATS_SchedulingHandle *sh, | 477 | process_ats_session_release_message (void *cls, |
570 | const struct SessionReleaseMessage *srm) | 478 | const struct GNUNET_MessageHeader *msg) |
571 | { | 479 | { |
572 | release_session (sh, ntohl (srm->session_id), &srm->peer); | 480 | struct GNUNET_ATS_SchedulingHandle *sh = cls; |
481 | const struct SessionReleaseMessage *srm; | ||
482 | |||
483 | srm = (const struct SessionReleaseMessage *) msg; | ||
484 | |||
485 | release_session (sh, | ||
486 | ntohl (srm->session_id), | ||
487 | &srm->peer); | ||
573 | } | 488 | } |
574 | 489 | ||
575 | 490 | ||
576 | /** | 491 | /** |
577 | * Type of a function to call when we receive a message | 492 | * Type of a function to call when we receive a address suggestion |
578 | * from the service. | 493 | * message from the service. |
579 | * | 494 | * |
580 | * @param cls the `struct GNUNET_ATS_SchedulingHandle` | 495 | * @param cls the `struct GNUNET_ATS_SchedulingHandle` |
581 | * @param msg message received, NULL on timeout or fatal error | 496 | * @param msg message received, NULL on timeout or fatal error |
582 | */ | 497 | */ |
583 | static void | 498 | static void |
584 | process_ats_message (void *cls, | 499 | process_ats_address_suggestion_message (void *cls, |
585 | const struct GNUNET_MessageHeader *msg) | 500 | const struct GNUNET_MessageHeader *msg) |
586 | { | 501 | { |
587 | struct GNUNET_ATS_SchedulingHandle *sh = cls; | 502 | struct GNUNET_ATS_SchedulingHandle *sh = cls; |
588 | const struct AddressSuggestionMessage *m; | 503 | const struct AddressSuggestionMessage *m; |
@@ -595,23 +510,7 @@ process_ats_message (void *cls, | |||
595 | struct GNUNET_HELLO_Address address; | 510 | struct GNUNET_HELLO_Address address; |
596 | struct Session *s; | 511 | struct Session *s; |
597 | 512 | ||
598 | if (NULL == msg) | 513 | if (ntohs (msg->size) <= sizeof (struct AddressSuggestionMessage)) |
599 | { | ||
600 | force_reconnect (sh); | ||
601 | return; | ||
602 | } | ||
603 | if ((ntohs (msg->type) == GNUNET_MESSAGE_TYPE_ATS_SESSION_RELEASE) && | ||
604 | (ntohs (msg->size) == sizeof (struct SessionReleaseMessage))) | ||
605 | { | ||
606 | process_release_message (sh, (const struct SessionReleaseMessage *) msg); | ||
607 | GNUNET_CLIENT_receive (sh->client, &process_ats_message, sh, | ||
608 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
609 | if (GNUNET_YES == sh->reconnect) | ||
610 | force_reconnect (sh); | ||
611 | return; | ||
612 | } | ||
613 | if ((ntohs (msg->type) != GNUNET_MESSAGE_TYPE_ATS_ADDRESS_SUGGESTION) || | ||
614 | (ntohs (msg->size) <= sizeof (struct AddressSuggestionMessage))) | ||
615 | { | 514 | { |
616 | GNUNET_break (0); | 515 | GNUNET_break (0); |
617 | force_reconnect (sh); | 516 | force_reconnect (sh); |
@@ -642,21 +541,17 @@ process_ats_message (void *cls, | |||
642 | else | 541 | else |
643 | { | 542 | { |
644 | s = find_session (sh, session_id, &m->peer); | 543 | s = find_session (sh, session_id, &m->peer); |
645 | if (s == NULL) | 544 | if (NULL == s) |
646 | { | 545 | { |
647 | 546 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | |
648 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-scheduling-api", | 547 | "ats-scheduling-api", |
649 | "ATS tries to use outdated session `%s'\n", | 548 | "ATS tries to use outdated session `%s'\n", |
650 | GNUNET_i2s (&m->peer)); | 549 | GNUNET_i2s (&m->peer)); |
651 | GNUNET_CLIENT_receive (sh->client, &process_ats_message, sh, | ||
652 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
653 | return; | 550 | return; |
654 | } | 551 | } |
655 | } | 552 | } |
656 | |||
657 | if (NULL == sh->suggest_cb) | 553 | if (NULL == sh->suggest_cb) |
658 | return; | 554 | return; |
659 | |||
660 | address.peer = m->peer; | 555 | address.peer = m->peer; |
661 | address.address = plugin_address; | 556 | address.address = plugin_address; |
662 | address.address_length = plugin_address_length; | 557 | address.address_length = plugin_address_length; |
@@ -667,23 +562,40 @@ process_ats_message (void *cls, | |||
667 | { | 562 | { |
668 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 563 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
669 | "ATS returned invalid address for peer `%s' transport `%s' address length %i, session_id %i\n", | 564 | "ATS returned invalid address for peer `%s' transport `%s' address length %i, session_id %i\n", |
670 | GNUNET_i2s (&address.peer), address.transport_name, | 565 | GNUNET_i2s (&address.peer), |
671 | plugin_address_length, session_id); | 566 | address.transport_name, |
567 | plugin_address_length, | ||
568 | session_id); | ||
672 | GNUNET_break_op (0); | 569 | GNUNET_break_op (0); |
673 | GNUNET_CLIENT_receive (sh->client, &process_ats_message, sh, | ||
674 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
675 | return; | 570 | return; |
676 | } | 571 | } |
677 | |||
678 | sh->suggest_cb (sh->suggest_cb_cls, | 572 | sh->suggest_cb (sh->suggest_cb_cls, |
679 | (const struct GNUNET_PeerIdentity *) &m->peer, | 573 | &m->peer, |
680 | &address, s, m->bandwidth_out, | 574 | &address, |
681 | m->bandwidth_in, atsi, ats_count); | 575 | s, |
576 | m->bandwidth_out, | ||
577 | m->bandwidth_in, | ||
578 | atsi, ats_count); | ||
579 | } | ||
682 | 580 | ||
683 | GNUNET_CLIENT_receive (sh->client, &process_ats_message, sh, | 581 | |
684 | GNUNET_TIME_UNIT_FOREVER_REL); | 582 | /** |
685 | if (GNUNET_YES == sh->reconnect) | 583 | * We encountered an error handling the MQ to the |
686 | force_reconnect (sh); | 584 | * ATS service. Reconnect. |
585 | * | ||
586 | * @param cls the `struct GNUNET_ATS_SchedulingHandle` | ||
587 | * @param error details about the error | ||
588 | */ | ||
589 | static void | ||
590 | error_handler (void *cls, | ||
591 | enum GNUNET_MQ_Error error) | ||
592 | { | ||
593 | struct GNUNET_ATS_SchedulingHandle *sh = cls; | ||
594 | |||
595 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
596 | "ATS connection died (code %d), reconnecting\n", | ||
597 | (int) error); | ||
598 | force_reconnect (sh); | ||
687 | } | 599 | } |
688 | 600 | ||
689 | 601 | ||
@@ -695,36 +607,39 @@ process_ats_message (void *cls, | |||
695 | static void | 607 | static void |
696 | reconnect (struct GNUNET_ATS_SchedulingHandle *sh) | 608 | reconnect (struct GNUNET_ATS_SchedulingHandle *sh) |
697 | { | 609 | { |
698 | struct PendingMessage *p; | 610 | static const struct GNUNET_MQ_MessageHandler handlers[] = |
611 | { { &process_ats_session_release_message, | ||
612 | GNUNET_MESSAGE_TYPE_ATS_SESSION_RELEASE, | ||
613 | sizeof (struct SessionReleaseMessage) }, | ||
614 | { &process_ats_address_suggestion_message, | ||
615 | GNUNET_MESSAGE_TYPE_ATS_ADDRESS_SUGGESTION, | ||
616 | 0 }, | ||
617 | { NULL, 0, 0 } }; | ||
618 | struct GNUNET_MQ_Envelope *ev; | ||
699 | struct ClientStartMessage *init; | 619 | struct ClientStartMessage *init; |
700 | 620 | ||
701 | GNUNET_assert (NULL == sh->client); | 621 | GNUNET_assert (NULL == sh->client); |
702 | sh->client = GNUNET_CLIENT_connect ("ats", sh->cfg); | 622 | sh->client = GNUNET_CLIENT_connect ("ats", sh->cfg); |
703 | GNUNET_assert (NULL != sh->client); | 623 | if (NULL == sh->client) |
704 | GNUNET_CLIENT_receive (sh->client, | ||
705 | &process_ats_message, sh, | ||
706 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
707 | if ( (NULL == (p = sh->pending_head)) || | ||
708 | (GNUNET_YES != p->is_init) ) | ||
709 | { | 624 | { |
710 | p = GNUNET_malloc (sizeof (struct PendingMessage) + | 625 | force_reconnect (sh); |
711 | sizeof (struct ClientStartMessage)); | 626 | return; |
712 | p->size = sizeof (struct ClientStartMessage); | ||
713 | p->is_init = GNUNET_YES; | ||
714 | init = (struct ClientStartMessage *) &p[1]; | ||
715 | init->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_START); | ||
716 | init->header.size = htons (sizeof (struct ClientStartMessage)); | ||
717 | init->start_flag = htonl (START_FLAG_SCHEDULING); | ||
718 | GNUNET_CONTAINER_DLL_insert (sh->pending_head, | ||
719 | sh->pending_tail, | ||
720 | p); | ||
721 | } | 627 | } |
722 | do_transmit (sh); | 628 | sh->mq = GNUNET_MQ_queue_for_connection_client (sh->client, |
629 | handlers, | ||
630 | &error_handler, | ||
631 | sh); | ||
632 | ev = GNUNET_MQ_msg (init, | ||
633 | GNUNET_MESSAGE_TYPE_ATS_START); | ||
634 | init->start_flag = htonl (START_FLAG_SCHEDULING); | ||
635 | GNUNET_MQ_send (sh->mq, ev); | ||
636 | // FIXME: iterate over addresses... | ||
637 | // FIXME: iterate over peermap for address suggestion requests! | ||
723 | } | 638 | } |
724 | 639 | ||
725 | 640 | ||
726 | /** | 641 | /** |
727 | * Delete the current network list. | 642 | * Delete all entries from the current network list. |
728 | * | 643 | * |
729 | * @param sh scheduling handle to clean up | 644 | * @param sh scheduling handle to clean up |
730 | */ | 645 | */ |
@@ -743,6 +658,20 @@ delete_networks (struct GNUNET_ATS_SchedulingHandle *sh) | |||
743 | } | 658 | } |
744 | 659 | ||
745 | 660 | ||
661 | /** | ||
662 | * Function invoked for each interface found. Adds the interface's | ||
663 | * network addresses to the respective DLL, so we can distinguish | ||
664 | * between LAN and WAN. | ||
665 | * | ||
666 | * @param cls closure | ||
667 | * @param name name of the interface (can be NULL for unknown) | ||
668 | * @param isDefault is this presumably the default interface | ||
669 | * @param addr address of this interface (can be NULL for unknown or unassigned) | ||
670 | * @param broadcast_addr the broadcast address (can be NULL for unknown or unassigned) | ||
671 | * @param netmask the network mask (can be NULL for unknown or unassigned) | ||
672 | * @param addrlen length of the address | ||
673 | * @return #GNUNET_OK to continue iteration | ||
674 | */ | ||
746 | static int | 675 | static int |
747 | interface_proc (void *cls, | 676 | interface_proc (void *cls, |
748 | const char *name, | 677 | const char *name, |
@@ -759,7 +688,7 @@ interface_proc (void *cls, | |||
759 | /* Skipping IPv4 loopback addresses since we have special check */ | 688 | /* Skipping IPv4 loopback addresses since we have special check */ |
760 | if (addr->sa_family == AF_INET) | 689 | if (addr->sa_family == AF_INET) |
761 | { | 690 | { |
762 | struct sockaddr_in * a4 = (struct sockaddr_in *) addr; | 691 | const struct sockaddr_in *a4 = (const struct sockaddr_in *) addr; |
763 | 692 | ||
764 | if ((a4->sin_addr.s_addr & htonl(0xff000000)) == htonl (0x7f000000)) | 693 | if ((a4->sin_addr.s_addr & htonl(0xff000000)) == htonl (0x7f000000)) |
765 | return GNUNET_OK; | 694 | return GNUNET_OK; |
@@ -767,19 +696,19 @@ interface_proc (void *cls, | |||
767 | /* Skipping IPv6 loopback addresses since we have special check */ | 696 | /* Skipping IPv6 loopback addresses since we have special check */ |
768 | if (addr->sa_family == AF_INET6) | 697 | if (addr->sa_family == AF_INET6) |
769 | { | 698 | { |
770 | struct sockaddr_in6 * a6 = (struct sockaddr_in6 *) addr; | 699 | const struct sockaddr_in6 *a6 = (const struct sockaddr_in6 *) addr; |
771 | if (IN6_IS_ADDR_LOOPBACK (&a6->sin6_addr)) | 700 | if (IN6_IS_ADDR_LOOPBACK (&a6->sin6_addr)) |
772 | return GNUNET_OK; | 701 | return GNUNET_OK; |
773 | } | 702 | } |
774 | 703 | ||
775 | if (addr->sa_family == AF_INET) | 704 | if (addr->sa_family == AF_INET) |
776 | { | 705 | { |
777 | struct sockaddr_in *addr4 = (struct sockaddr_in *) addr; | 706 | const struct sockaddr_in *addr4 = (const struct sockaddr_in *) addr; |
778 | struct sockaddr_in *netmask4 = (struct sockaddr_in *) netmask; | 707 | const struct sockaddr_in *netmask4 = (const struct sockaddr_in *) netmask; |
779 | struct sockaddr_in *tmp = NULL; | 708 | struct sockaddr_in *tmp; |
780 | struct sockaddr_in network4; | 709 | struct sockaddr_in network4; |
781 | 710 | ||
782 | net = GNUNET_malloc(sizeof (struct ATS_Network) + 2 * sizeof (struct sockaddr_in)); | 711 | net = GNUNET_malloc (sizeof (struct ATS_Network) + 2 * sizeof (struct sockaddr_in)); |
783 | tmp = (struct sockaddr_in *) &net[1]; | 712 | tmp = (struct sockaddr_in *) &net[1]; |
784 | net->network = (struct sockaddr *) &tmp[0]; | 713 | net->network = (struct sockaddr *) &tmp[0]; |
785 | net->netmask = (struct sockaddr *) &tmp[1]; | 714 | net->netmask = (struct sockaddr *) &tmp[1]; |
@@ -798,12 +727,12 @@ interface_proc (void *cls, | |||
798 | 727 | ||
799 | if (addr->sa_family == AF_INET6) | 728 | if (addr->sa_family == AF_INET6) |
800 | { | 729 | { |
801 | struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) addr; | 730 | const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *) addr; |
802 | struct sockaddr_in6 *netmask6 = (struct sockaddr_in6 *) netmask; | 731 | const struct sockaddr_in6 *netmask6 = (const struct sockaddr_in6 *) netmask; |
803 | struct sockaddr_in6 * tmp = NULL; | 732 | struct sockaddr_in6 * tmp; |
804 | struct sockaddr_in6 network6; | 733 | struct sockaddr_in6 network6; |
805 | 734 | ||
806 | net = GNUNET_malloc(sizeof (struct ATS_Network) + 2 * sizeof (struct sockaddr_in6)); | 735 | net = GNUNET_malloc (sizeof (struct ATS_Network) + 2 * sizeof (struct sockaddr_in6)); |
807 | tmp = (struct sockaddr_in6 *) &net[1]; | 736 | tmp = (struct sockaddr_in6 *) &net[1]; |
808 | net->network = (struct sockaddr *) &tmp[0]; | 737 | net->network = (struct sockaddr *) &tmp[0]; |
809 | net->netmask = (struct sockaddr *) &tmp[1]; | 738 | net->netmask = (struct sockaddr *) &tmp[1]; |
@@ -814,7 +743,7 @@ interface_proc (void *cls, | |||
814 | #if HAVE_SOCKADDR_IN_SIN_LEN | 743 | #if HAVE_SOCKADDR_IN_SIN_LEN |
815 | network6.sin6_len = sizeof (network6); | 744 | network6.sin6_len = sizeof (network6); |
816 | #endif | 745 | #endif |
817 | int c = 0; | 746 | unsigned int c = 0; |
818 | uint32_t *addr_elem = (uint32_t *) &addr6->sin6_addr; | 747 | uint32_t *addr_elem = (uint32_t *) &addr6->sin6_addr; |
819 | uint32_t *mask_elem = (uint32_t *) &netmask6->sin6_addr; | 748 | uint32_t *mask_elem = (uint32_t *) &netmask6->sin6_addr; |
820 | uint32_t *net_elem = (uint32_t *) &network6.sin6_addr; | 749 | uint32_t *net_elem = (uint32_t *) &network6.sin6_addr; |
@@ -824,19 +753,23 @@ interface_proc (void *cls, | |||
824 | memcpy (net->netmask, netmask6, sizeof (struct sockaddr_in6)); | 753 | memcpy (net->netmask, netmask6, sizeof (struct sockaddr_in6)); |
825 | memcpy (net->network, &network6, sizeof (struct sockaddr_in6)); | 754 | memcpy (net->network, &network6, sizeof (struct sockaddr_in6)); |
826 | } | 755 | } |
756 | if (NULL == net) | ||
757 | return GNUNET_OK; /* odd / unsupported address family */ | ||
827 | 758 | ||
828 | /* Store in list */ | 759 | /* Store in list */ |
829 | if (net != NULL) | ||
830 | { | ||
831 | #if VERBOSE_ATS | 760 | #if VERBOSE_ATS |
832 | char * netmask = GNUNET_strdup (GNUNET_a2s((struct sockaddr *) net->netmask, addrlen)); | 761 | char * netmask = GNUNET_strdup (GNUNET_a2s((struct sockaddr *) net->netmask, addrlen)); |
833 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding network `%s', netmask `%s'\n", | 762 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
834 | GNUNET_a2s((struct sockaddr *) net->network, addrlen), | 763 | "Adding network `%s', netmask `%s'\n", |
835 | netmask); | 764 | GNUNET_a2s ((struct sockaddr *) net->network, |
836 | GNUNET_free (netmask); | 765 | addrlen), |
837 | # endif | 766 | netmask); |
838 | GNUNET_CONTAINER_DLL_insert(sh->net_head, sh->net_tail, net); | 767 | GNUNET_free (netmask); |
839 | } | 768 | #endif |
769 | GNUNET_CONTAINER_DLL_insert (sh->net_head, | ||
770 | sh->net_tail, | ||
771 | net); | ||
772 | |||
840 | return GNUNET_OK; | 773 | return GNUNET_OK; |
841 | } | 774 | } |
842 | 775 | ||
@@ -857,7 +790,7 @@ get_addresses (void *cls, | |||
857 | delete_networks (sh); | 790 | delete_networks (sh); |
858 | GNUNET_OS_network_interfaces_list (&interface_proc, | 791 | GNUNET_OS_network_interfaces_list (&interface_proc, |
859 | sh); | 792 | sh); |
860 | sh->interface_task = GNUNET_SCHEDULER_add_delayed (INTERFACE_PROCESSING_INTERVALL, | 793 | sh->interface_task = GNUNET_SCHEDULER_add_delayed (INTERFACE_PROCESSING_INTERVAL, |
861 | &get_addresses, | 794 | &get_addresses, |
862 | sh); | 795 | sh); |
863 | } | 796 | } |
@@ -974,7 +907,7 @@ GNUNET_ATS_address_get_type (struct GNUNET_ATS_SchedulingHandle *sh, | |||
974 | } | 907 | } |
975 | 908 | ||
976 | /* Check local networks */ | 909 | /* Check local networks */ |
977 | while ((cur != NULL) && (type == GNUNET_ATS_NET_UNSPECIFIED)) | 910 | while ((NULL != cur) && (GNUNET_ATS_NET_UNSPECIFIED == type)) |
978 | { | 911 | { |
979 | if (addrlen != cur->length) | 912 | if (addrlen != cur->length) |
980 | { | 913 | { |
@@ -983,18 +916,18 @@ GNUNET_ATS_address_get_type (struct GNUNET_ATS_SchedulingHandle *sh, | |||
983 | } | 916 | } |
984 | if (addr->sa_family == AF_INET) | 917 | if (addr->sa_family == AF_INET) |
985 | { | 918 | { |
986 | struct sockaddr_in * a4 = (struct sockaddr_in *) addr; | 919 | const struct sockaddr_in *a4 = (const struct sockaddr_in *) addr; |
987 | struct sockaddr_in * net4 = (struct sockaddr_in *) cur->network; | 920 | const struct sockaddr_in *net4 = (const struct sockaddr_in *) cur->network; |
988 | struct sockaddr_in * mask4 = (struct sockaddr_in *) cur->netmask; | 921 | const struct sockaddr_in *mask4 = (const struct sockaddr_in *) cur->netmask; |
989 | 922 | ||
990 | if (((a4->sin_addr.s_addr & mask4->sin_addr.s_addr)) == net4->sin_addr.s_addr) | 923 | if (((a4->sin_addr.s_addr & mask4->sin_addr.s_addr)) == net4->sin_addr.s_addr) |
991 | type = GNUNET_ATS_NET_LAN; | 924 | type = GNUNET_ATS_NET_LAN; |
992 | } | 925 | } |
993 | if (addr->sa_family == AF_INET6) | 926 | if (addr->sa_family == AF_INET6) |
994 | { | 927 | { |
995 | struct sockaddr_in6 * a6 = (struct sockaddr_in6 *) addr; | 928 | const struct sockaddr_in6 *a6 = (const struct sockaddr_in6 *) addr; |
996 | struct sockaddr_in6 * net6 = (struct sockaddr_in6 *) cur->network; | 929 | const struct sockaddr_in6 *net6 = (const struct sockaddr_in6 *) cur->network; |
997 | struct sockaddr_in6 * mask6 = (struct sockaddr_in6 *) cur->netmask; | 930 | const struct sockaddr_in6 *mask6 = (const struct sockaddr_in6 *) cur->netmask; |
998 | 931 | ||
999 | int res = GNUNET_YES; | 932 | int res = GNUNET_YES; |
1000 | int c = 0; | 933 | int c = 0; |
@@ -1046,9 +979,11 @@ GNUNET_ATS_scheduling_init (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
1046 | GNUNET_array_grow (sh->session_array, | 979 | GNUNET_array_grow (sh->session_array, |
1047 | sh->session_array_size, | 980 | sh->session_array_size, |
1048 | 4); | 981 | 4); |
982 | sh->sug_requests = GNUNET_CONTAINER_multipeermap_create (32, | ||
983 | GNUNET_YES); | ||
1049 | GNUNET_OS_network_interfaces_list (&interface_proc, | 984 | GNUNET_OS_network_interfaces_list (&interface_proc, |
1050 | sh); | 985 | sh); |
1051 | sh->interface_task = GNUNET_SCHEDULER_add_delayed (INTERFACE_PROCESSING_INTERVALL, | 986 | sh->interface_task = GNUNET_SCHEDULER_add_delayed (INTERFACE_PROCESSING_INTERVAL, |
1052 | &get_addresses, | 987 | &get_addresses, |
1053 | sh); | 988 | sh); |
1054 | reconnect (sh); | 989 | reconnect (sh); |
@@ -1057,6 +992,28 @@ GNUNET_ATS_scheduling_init (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
1057 | 992 | ||
1058 | 993 | ||
1059 | /** | 994 | /** |
995 | * Function called to free all `struct GNUNET_ATS_SuggestHandles` | ||
996 | * in the map. | ||
997 | * | ||
998 | * @param cls NULL | ||
999 | * @param key the key | ||
1000 | * @param value the value to free | ||
1001 | * @return #GNUNET_OK (continue to iterate) | ||
1002 | */ | ||
1003 | static int | ||
1004 | free_sug_handle (void *cls, | ||
1005 | const struct GNUNET_PeerIdentity *key, | ||
1006 | void *value) | ||
1007 | { | ||
1008 | struct GNUNET_ATS_SuggestHandle *cur = value; | ||
1009 | |||
1010 | GNUNET_free (cur); | ||
1011 | return GNUNET_OK; | ||
1012 | } | ||
1013 | |||
1014 | |||
1015 | |||
1016 | /** | ||
1060 | * Client is done with ATS scheduling, release resources. | 1017 | * Client is done with ATS scheduling, release resources. |
1061 | * | 1018 | * |
1062 | * @param sh handle to release | 1019 | * @param sh handle to release |
@@ -1064,15 +1021,10 @@ GNUNET_ATS_scheduling_init (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
1064 | void | 1021 | void |
1065 | GNUNET_ATS_scheduling_done (struct GNUNET_ATS_SchedulingHandle *sh) | 1022 | GNUNET_ATS_scheduling_done (struct GNUNET_ATS_SchedulingHandle *sh) |
1066 | { | 1023 | { |
1067 | struct PendingMessage *p; | 1024 | if (NULL != sh->mq) |
1068 | struct GNUNET_ATS_SuggestHandle *cur; | ||
1069 | |||
1070 | while (NULL != (p = sh->pending_head)) | ||
1071 | { | 1025 | { |
1072 | GNUNET_CONTAINER_DLL_remove (sh->pending_head, | 1026 | GNUNET_MQ_destroy (sh->mq); |
1073 | sh->pending_tail, | 1027 | sh->mq = NULL; |
1074 | p); | ||
1075 | GNUNET_free (p); | ||
1076 | } | 1028 | } |
1077 | if (NULL != sh->client) | 1029 | if (NULL != sh->client) |
1078 | { | 1030 | { |
@@ -1084,19 +1036,16 @@ GNUNET_ATS_scheduling_done (struct GNUNET_ATS_SchedulingHandle *sh) | |||
1084 | GNUNET_SCHEDULER_cancel (sh->task); | 1036 | GNUNET_SCHEDULER_cancel (sh->task); |
1085 | sh->task = NULL; | 1037 | sh->task = NULL; |
1086 | } | 1038 | } |
1087 | while (NULL != (cur = sh->sug_head)) | 1039 | GNUNET_CONTAINER_multipeermap_iterate (sh->sug_requests, |
1088 | { | 1040 | &free_sug_handle, |
1089 | GNUNET_CONTAINER_DLL_remove (sh->sug_head, | 1041 | NULL); |
1090 | sh->sug_tail, | 1042 | GNUNET_CONTAINER_multipeermap_destroy (sh->sug_requests); |
1091 | cur); | ||
1092 | GNUNET_free (cur); | ||
1093 | } | ||
1094 | delete_networks (sh); | ||
1095 | if (NULL != sh->interface_task) | 1043 | if (NULL != sh->interface_task) |
1096 | { | 1044 | { |
1097 | GNUNET_SCHEDULER_cancel (sh->interface_task); | 1045 | GNUNET_SCHEDULER_cancel (sh->interface_task); |
1098 | sh->interface_task = NULL; | 1046 | sh->interface_task = NULL; |
1099 | } | 1047 | } |
1048 | delete_networks (sh); | ||
1100 | GNUNET_array_grow (sh->session_array, | 1049 | GNUNET_array_grow (sh->session_array, |
1101 | sh->session_array_size, | 1050 | sh->session_array_size, |
1102 | 0); | 1051 | 0); |
@@ -1115,22 +1064,13 @@ void | |||
1115 | GNUNET_ATS_reset_backoff (struct GNUNET_ATS_SchedulingHandle *sh, | 1064 | GNUNET_ATS_reset_backoff (struct GNUNET_ATS_SchedulingHandle *sh, |
1116 | const struct GNUNET_PeerIdentity *peer) | 1065 | const struct GNUNET_PeerIdentity *peer) |
1117 | { | 1066 | { |
1118 | struct PendingMessage *p; | 1067 | struct GNUNET_MQ_Envelope *ev; |
1119 | struct ResetBackoffMessage *m; | 1068 | struct ResetBackoffMessage *m; |
1120 | 1069 | ||
1121 | p = GNUNET_malloc (sizeof (struct PendingMessage) + | 1070 | ev = GNUNET_MQ_msg (m, GNUNET_MESSAGE_TYPE_ATS_RESET_BACKOFF); |
1122 | sizeof (struct ResetBackoffMessage)); | ||
1123 | p->size = sizeof (struct ResetBackoffMessage); | ||
1124 | p->is_init = GNUNET_NO; | ||
1125 | m = (struct ResetBackoffMessage *) &p[1]; | ||
1126 | m->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_RESET_BACKOFF); | ||
1127 | m->header.size = htons (sizeof (struct ResetBackoffMessage)); | ||
1128 | m->reserved = htonl (0); | 1071 | m->reserved = htonl (0); |
1129 | m->peer = *peer; | 1072 | m->peer = *peer; |
1130 | GNUNET_CONTAINER_DLL_insert_tail (sh->pending_head, | 1073 | GNUNET_MQ_send (sh->mq, ev); |
1131 | sh->pending_tail, | ||
1132 | p); | ||
1133 | do_transmit (sh); | ||
1134 | } | 1074 | } |
1135 | 1075 | ||
1136 | 1076 | ||
@@ -1148,29 +1088,23 @@ struct GNUNET_ATS_SuggestHandle * | |||
1148 | GNUNET_ATS_suggest_address (struct GNUNET_ATS_SchedulingHandle *sh, | 1088 | GNUNET_ATS_suggest_address (struct GNUNET_ATS_SchedulingHandle *sh, |
1149 | const struct GNUNET_PeerIdentity *peer) | 1089 | const struct GNUNET_PeerIdentity *peer) |
1150 | { | 1090 | { |
1151 | struct PendingMessage *p; | 1091 | struct GNUNET_MQ_Envelope *ev; |
1152 | struct RequestAddressMessage *m; | 1092 | struct RequestAddressMessage *m; |
1153 | struct GNUNET_ATS_SuggestHandle *s; | 1093 | struct GNUNET_ATS_SuggestHandle *s; |
1154 | 1094 | ||
1155 | // FIXME: ATS needs to remember this in case of | ||
1156 | // a disconnect! | ||
1157 | p = GNUNET_malloc (sizeof (struct PendingMessage) + | ||
1158 | sizeof (struct RequestAddressMessage)); | ||
1159 | p->size = sizeof (struct RequestAddressMessage); | ||
1160 | m = (struct RequestAddressMessage *) &p[1]; | ||
1161 | m->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_REQUEST_ADDRESS); | ||
1162 | m->header.size = htons (sizeof (struct RequestAddressMessage)); | ||
1163 | m->reserved = htonl (0); | ||
1164 | m->peer = *peer; | ||
1165 | GNUNET_CONTAINER_DLL_insert_tail (sh->pending_head, | ||
1166 | sh->pending_tail, | ||
1167 | p); | ||
1168 | do_transmit (sh); | ||
1169 | s = GNUNET_new (struct GNUNET_ATS_SuggestHandle); | 1095 | s = GNUNET_new (struct GNUNET_ATS_SuggestHandle); |
1170 | s->id = *peer; | 1096 | s->id = *peer; |
1171 | GNUNET_CONTAINER_DLL_insert_tail (sh->sug_head, | 1097 | GNUNET_break (GNUNET_OK == |
1172 | sh->sug_tail, | 1098 | GNUNET_CONTAINER_multipeermap_put (sh->sug_requests, |
1173 | s); | 1099 | &s->id, |
1100 | s, | ||
1101 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
1102 | if (NULL == sh->mq) | ||
1103 | return s; | ||
1104 | ev = GNUNET_MQ_msg (m, GNUNET_MESSAGE_TYPE_ATS_REQUEST_ADDRESS); | ||
1105 | m->reserved = htonl (0); | ||
1106 | m->peer = *peer; | ||
1107 | GNUNET_MQ_send (sh->mq, ev); | ||
1174 | return s; | 1108 | return s; |
1175 | } | 1109 | } |
1176 | 1110 | ||
@@ -1185,36 +1119,28 @@ void | |||
1185 | GNUNET_ATS_suggest_address_cancel (struct GNUNET_ATS_SchedulingHandle *sh, | 1119 | GNUNET_ATS_suggest_address_cancel (struct GNUNET_ATS_SchedulingHandle *sh, |
1186 | const struct GNUNET_PeerIdentity *peer) | 1120 | const struct GNUNET_PeerIdentity *peer) |
1187 | { | 1121 | { |
1188 | struct PendingMessage *p; | 1122 | struct GNUNET_MQ_Envelope *ev; |
1189 | struct RequestAddressMessage *m; | 1123 | struct RequestAddressMessage *m; |
1190 | struct GNUNET_ATS_SuggestHandle *s; | 1124 | struct GNUNET_ATS_SuggestHandle *s; |
1191 | 1125 | ||
1192 | for (s = sh->sug_head; NULL != s; s = s->next) | 1126 | s = GNUNET_CONTAINER_multipeermap_get (sh->sug_requests, |
1193 | if (0 == memcmp (peer, &s->id, sizeof (s->id))) | 1127 | peer); |
1194 | break; | ||
1195 | if (NULL == s) | 1128 | if (NULL == s) |
1196 | { | 1129 | { |
1197 | GNUNET_break (0); | 1130 | GNUNET_break (0); |
1198 | return; | 1131 | return; |
1199 | } | 1132 | } |
1200 | GNUNET_CONTAINER_DLL_remove (sh->sug_head, | 1133 | GNUNET_assert (GNUNET_OK == |
1201 | sh->sug_tail, | 1134 | GNUNET_CONTAINER_multipeermap_remove (sh->sug_requests, |
1202 | s); | 1135 | &s->id, |
1136 | s)); | ||
1203 | GNUNET_free (s); | 1137 | GNUNET_free (s); |
1204 | 1138 | if (NULL == sh->mq) | |
1205 | p = GNUNET_malloc (sizeof (struct PendingMessage) + | 1139 | return; |
1206 | sizeof (struct RequestAddressMessage)); | 1140 | ev = GNUNET_MQ_msg (m, GNUNET_MESSAGE_TYPE_ATS_REQUEST_ADDRESS_CANCEL); |
1207 | p->size = sizeof (struct RequestAddressMessage); | ||
1208 | p->is_init = GNUNET_NO; | ||
1209 | m = (struct RequestAddressMessage *) &p[1]; | ||
1210 | m->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_REQUEST_ADDRESS_CANCEL); | ||
1211 | m->header.size = htons (sizeof (struct RequestAddressMessage)); | ||
1212 | m->reserved = htonl (0); | 1141 | m->reserved = htonl (0); |
1213 | m->peer = *peer; | 1142 | m->peer = *peer; |
1214 | GNUNET_CONTAINER_DLL_insert_tail (sh->pending_head, | 1143 | GNUNET_MQ_send (sh->mq, ev); |
1215 | sh->pending_tail, | ||
1216 | p); | ||
1217 | do_transmit (sh); | ||
1218 | } | 1144 | } |
1219 | 1145 | ||
1220 | 1146 | ||
@@ -1242,8 +1168,9 @@ GNUNET_ATS_session_known (struct GNUNET_ATS_SchedulingHandle *sh, | |||
1242 | 1168 | ||
1243 | 1169 | ||
1244 | /** | 1170 | /** |
1245 | * We have a new address ATS should know. Addresses have to be added with this | 1171 | * We have a new address ATS should know. Addresses have to be added |
1246 | * function before they can be: updated, set in use and destroyed | 1172 | * with this function before they can be: updated, set in use and |
1173 | * destroyed. | ||
1247 | * | 1174 | * |
1248 | * @param sh handle | 1175 | * @param sh handle |
1249 | * @param address the address | 1176 | * @param address the address |
@@ -1259,8 +1186,7 @@ GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh, | |||
1259 | const struct GNUNET_ATS_Information *ats, | 1186 | const struct GNUNET_ATS_Information *ats, |
1260 | uint32_t ats_count) | 1187 | uint32_t ats_count) |
1261 | { | 1188 | { |
1262 | 1189 | struct GNUNET_MQ_Envelope *ev; | |
1263 | struct PendingMessage *p; | ||
1264 | struct AddressUpdateMessage *m; | 1190 | struct AddressUpdateMessage *m; |
1265 | struct GNUNET_ATS_Information *am; | 1191 | struct GNUNET_ATS_Information *am; |
1266 | char *pm; | 1192 | char *pm; |
@@ -1278,9 +1204,9 @@ GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh, | |||
1278 | ? 0 | 1204 | ? 0 |
1279 | : strlen (address->transport_name) + 1; | 1205 | : strlen (address->transport_name) + 1; |
1280 | 1206 | ||
1281 | msize = sizeof (struct AddressUpdateMessage) + address->address_length + | 1207 | msize = address->address_length + |
1282 | ats_count * sizeof (struct GNUNET_ATS_Information) + namelen; | 1208 | ats_count * sizeof (struct GNUNET_ATS_Information) + namelen; |
1283 | if ((msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || | 1209 | if ((msize + sizeof (struct AddressUpdateMessage) >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || |
1284 | (address->address_length >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || | 1210 | (address->address_length >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || |
1285 | (namelen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || | 1211 | (namelen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || |
1286 | (ats_count >= | 1212 | (ats_count >= |
@@ -1303,12 +1229,7 @@ GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh, | |||
1303 | GNUNET_break (NOT_FOUND != s); | 1229 | GNUNET_break (NOT_FOUND != s); |
1304 | } | 1230 | } |
1305 | 1231 | ||
1306 | p = GNUNET_malloc (sizeof (struct PendingMessage) + msize); | 1232 | ev = GNUNET_MQ_msg_extra (m, msize, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_ADD); |
1307 | p->size = msize; | ||
1308 | p->is_init = GNUNET_NO; | ||
1309 | m = (struct AddressUpdateMessage *) &p[1]; | ||
1310 | m->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_ADDRESS_ADD); | ||
1311 | m->header.size = htons (msize); | ||
1312 | m->ats_count = htonl (ats_count); | 1233 | m->ats_count = htonl (ats_count); |
1313 | m->peer = address->peer; | 1234 | m->peer = address->peer; |
1314 | m->address_length = htons (address->address_length); | 1235 | m->address_length = htons (address->address_length); |
@@ -1322,19 +1243,17 @@ GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh, | |||
1322 | address->transport_name, | 1243 | address->transport_name, |
1323 | session, | 1244 | session, |
1324 | s); | 1245 | s); |
1325 | |||
1326 | am = (struct GNUNET_ATS_Information *) &m[1]; | 1246 | am = (struct GNUNET_ATS_Information *) &m[1]; |
1327 | memcpy (am, ats, ats_count * sizeof (struct GNUNET_ATS_Information)); | 1247 | memcpy (am, |
1248 | ats, | ||
1249 | ats_count * sizeof (struct GNUNET_ATS_Information)); | ||
1328 | pm = (char *) &am[ats_count]; | 1250 | pm = (char *) &am[ats_count]; |
1329 | memcpy (pm, address->address, address->address_length); | 1251 | memcpy (pm, address->address, address->address_length); |
1330 | if (NULL != address->transport_name) | 1252 | if (NULL != address->transport_name) |
1331 | memcpy (&pm[address->address_length], | 1253 | memcpy (&pm[address->address_length], |
1332 | address->transport_name, | 1254 | address->transport_name, |
1333 | namelen); | 1255 | namelen); |
1334 | GNUNET_CONTAINER_DLL_insert_tail (sh->pending_head, | 1256 | GNUNET_MQ_send (sh->mq, ev); |
1335 | sh->pending_tail, | ||
1336 | p); | ||
1337 | do_transmit (sh); | ||
1338 | return GNUNET_OK; | 1257 | return GNUNET_OK; |
1339 | } | 1258 | } |
1340 | 1259 | ||
@@ -1362,7 +1281,7 @@ GNUNET_ATS_address_update (struct GNUNET_ATS_SchedulingHandle *sh, | |||
1362 | const struct GNUNET_ATS_Information *ats, | 1281 | const struct GNUNET_ATS_Information *ats, |
1363 | uint32_t ats_count) | 1282 | uint32_t ats_count) |
1364 | { | 1283 | { |
1365 | struct PendingMessage *p; | 1284 | struct GNUNET_MQ_Envelope *ev; |
1366 | struct AddressUpdateMessage *m; | 1285 | struct AddressUpdateMessage *m; |
1367 | struct GNUNET_ATS_Information *am; | 1286 | struct GNUNET_ATS_Information *am; |
1368 | char *pm; | 1287 | char *pm; |
@@ -1383,10 +1302,9 @@ GNUNET_ATS_address_update (struct GNUNET_ATS_SchedulingHandle *sh, | |||
1383 | 1302 | ||
1384 | namelen = (address->transport_name == | 1303 | namelen = (address->transport_name == |
1385 | NULL) ? 0 : strlen (address->transport_name) + 1; | 1304 | NULL) ? 0 : strlen (address->transport_name) + 1; |
1386 | msize = | 1305 | msize = address->address_length + |
1387 | sizeof (struct AddressUpdateMessage) + address->address_length + | ||
1388 | ats_count * sizeof (struct GNUNET_ATS_Information) + namelen; | 1306 | ats_count * sizeof (struct GNUNET_ATS_Information) + namelen; |
1389 | if ((msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || | 1307 | if ((msize + sizeof (struct AddressUpdateMessage) >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || |
1390 | (address->address_length >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || | 1308 | (address->address_length >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || |
1391 | (namelen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || | 1309 | (namelen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || |
1392 | (ats_count >= | 1310 | (ats_count >= |
@@ -1403,18 +1321,12 @@ GNUNET_ATS_address_update (struct GNUNET_ATS_SchedulingHandle *sh, | |||
1403 | return GNUNET_NO; | 1321 | return GNUNET_NO; |
1404 | } | 1322 | } |
1405 | 1323 | ||
1406 | p = GNUNET_malloc (sizeof (struct PendingMessage) + msize); | 1324 | ev = GNUNET_MQ_msg_extra (m, msize, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_UPDATE); |
1407 | p->size = msize; | ||
1408 | p->is_init = GNUNET_NO; | ||
1409 | m = (struct AddressUpdateMessage *) &p[1]; | ||
1410 | m->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_ADDRESS_UPDATE); | ||
1411 | m->header.size = htons (msize); | ||
1412 | m->ats_count = htonl (ats_count); | 1325 | m->ats_count = htonl (ats_count); |
1413 | m->peer = address->peer; | 1326 | m->peer = address->peer; |
1414 | m->address_length = htons (address->address_length); | 1327 | m->address_length = htons (address->address_length); |
1415 | m->address_local_info = htonl ((uint32_t) address->local_info); | 1328 | m->address_local_info = htonl ((uint32_t) address->local_info); |
1416 | m->plugin_name_length = htons (namelen); | 1329 | m->plugin_name_length = htons (namelen); |
1417 | |||
1418 | m->session_id = htonl (s); | 1330 | m->session_id = htonl (s); |
1419 | 1331 | ||
1420 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1332 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -1431,8 +1343,7 @@ GNUNET_ATS_address_update (struct GNUNET_ATS_SchedulingHandle *sh, | |||
1431 | pm = (char *) &am[ats_count]; | 1343 | pm = (char *) &am[ats_count]; |
1432 | memcpy (pm, address->address, address->address_length); | 1344 | memcpy (pm, address->address, address->address_length); |
1433 | memcpy (&pm[address->address_length], address->transport_name, namelen); | 1345 | memcpy (&pm[address->address_length], address->transport_name, namelen); |
1434 | GNUNET_CONTAINER_DLL_insert_tail (sh->pending_head, sh->pending_tail, p); | 1346 | GNUNET_MQ_send (sh->mq, ev); |
1435 | do_transmit (sh); | ||
1436 | return GNUNET_YES; | 1347 | return GNUNET_YES; |
1437 | } | 1348 | } |
1438 | 1349 | ||
@@ -1452,19 +1363,18 @@ GNUNET_ATS_address_in_use (struct GNUNET_ATS_SchedulingHandle *sh, | |||
1452 | struct Session *session, | 1363 | struct Session *session, |
1453 | int in_use) | 1364 | int in_use) |
1454 | { | 1365 | { |
1455 | struct PendingMessage *p; | 1366 | struct GNUNET_MQ_Envelope *ev; |
1456 | struct AddressUseMessage *m; | 1367 | struct AddressUseMessage *m; |
1457 | char *pm; | 1368 | char *pm; |
1458 | size_t namelen; | 1369 | size_t namelen; |
1459 | size_t msize; | 1370 | size_t msize; |
1460 | uint32_t s = 0; | 1371 | uint32_t s = 0; |
1461 | 1372 | ||
1462 | GNUNET_assert (NULL != address); | ||
1463 | namelen = | 1373 | namelen = |
1464 | (address->transport_name == | 1374 | (address->transport_name == |
1465 | NULL) ? 0 : strlen (address->transport_name) + 1; | 1375 | NULL) ? 0 : strlen (address->transport_name) + 1; |
1466 | msize = sizeof (struct AddressUseMessage) + address->address_length + namelen; | 1376 | msize = address->address_length + namelen; |
1467 | if ((msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || | 1377 | if ((msize + sizeof (struct AddressUseMessage) >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || |
1468 | (address->address_length >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || | 1378 | (address->address_length >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || |
1469 | (namelen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)) | 1379 | (namelen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)) |
1470 | { | 1380 | { |
@@ -1472,7 +1382,7 @@ GNUNET_ATS_address_in_use (struct GNUNET_ATS_SchedulingHandle *sh, | |||
1472 | return; | 1382 | return; |
1473 | } | 1383 | } |
1474 | 1384 | ||
1475 | if (session != NULL) | 1385 | if (NULL != session) |
1476 | { | 1386 | { |
1477 | s = find_session_id (sh, session, &address->peer); | 1387 | s = find_session_id (sh, session, &address->peer); |
1478 | if ((s == NOT_FOUND) && (GNUNET_NO == in_use)) | 1388 | if ((s == NOT_FOUND) && (GNUNET_NO == in_use)) |
@@ -1492,12 +1402,7 @@ GNUNET_ATS_address_in_use (struct GNUNET_ATS_SchedulingHandle *sh, | |||
1492 | } | 1402 | } |
1493 | } | 1403 | } |
1494 | 1404 | ||
1495 | p = GNUNET_malloc (sizeof (struct PendingMessage) + msize); | 1405 | ev = GNUNET_MQ_msg_extra (m, msize, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_IN_USE); |
1496 | p->size = msize; | ||
1497 | p->is_init = GNUNET_NO; | ||
1498 | m = (struct AddressUseMessage *) &p[1]; | ||
1499 | m->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_ADDRESS_IN_USE); | ||
1500 | m->header.size = htons (msize); | ||
1501 | m->peer = address->peer; | 1406 | m->peer = address->peer; |
1502 | m->in_use = htons (in_use); | 1407 | m->in_use = htons (in_use); |
1503 | m->address_length = htons (address->address_length); | 1408 | m->address_length = htons (address->address_length); |
@@ -1513,8 +1418,7 @@ GNUNET_ATS_address_in_use (struct GNUNET_ATS_SchedulingHandle *sh, | |||
1513 | pm = (char *) &m[1]; | 1418 | pm = (char *) &m[1]; |
1514 | memcpy (pm, address->address, address->address_length); | 1419 | memcpy (pm, address->address, address->address_length); |
1515 | memcpy (&pm[address->address_length], address->transport_name, namelen); | 1420 | memcpy (&pm[address->address_length], address->transport_name, namelen); |
1516 | GNUNET_CONTAINER_DLL_insert_tail (sh->pending_head, sh->pending_tail, p); | 1421 | GNUNET_MQ_send (sh->mq, ev); |
1517 | do_transmit (sh); | ||
1518 | } | 1422 | } |
1519 | 1423 | ||
1520 | 1424 | ||
@@ -1533,7 +1437,7 @@ GNUNET_ATS_address_destroyed (struct GNUNET_ATS_SchedulingHandle *sh, | |||
1533 | const struct GNUNET_HELLO_Address *address, | 1437 | const struct GNUNET_HELLO_Address *address, |
1534 | struct Session *session) | 1438 | struct Session *session) |
1535 | { | 1439 | { |
1536 | struct PendingMessage *p; | 1440 | struct GNUNET_MQ_Envelope *ev; |
1537 | struct AddressDestroyedMessage *m; | 1441 | struct AddressDestroyedMessage *m; |
1538 | char *pm; | 1442 | char *pm; |
1539 | size_t namelen; | 1443 | size_t namelen; |
@@ -1545,14 +1449,11 @@ GNUNET_ATS_address_destroyed (struct GNUNET_ATS_SchedulingHandle *sh, | |||
1545 | GNUNET_break (0); | 1449 | GNUNET_break (0); |
1546 | return; | 1450 | return; |
1547 | } | 1451 | } |
1548 | 1452 | GNUNET_assert (NULL != address->transport_name); | |
1549 | GNUNET_assert (address->transport_name != NULL); | ||
1550 | namelen = strlen (address->transport_name) + 1; | 1453 | namelen = strlen (address->transport_name) + 1; |
1551 | GNUNET_assert (namelen > 1); | 1454 | GNUNET_assert (namelen > 1); |
1552 | msize = | 1455 | msize = address->address_length + namelen; |
1553 | sizeof (struct AddressDestroyedMessage) + address->address_length + | 1456 | if ((msize + sizeof (struct AddressDestroyedMessage) >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || |
1554 | namelen; | ||
1555 | if ((msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || | ||
1556 | (address->address_length >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || | 1457 | (address->address_length >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || |
1557 | (namelen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)) | 1458 | (namelen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)) |
1558 | { | 1459 | { |
@@ -1570,13 +1471,7 @@ GNUNET_ATS_address_destroyed (struct GNUNET_ATS_SchedulingHandle *sh, | |||
1570 | return; | 1471 | return; |
1571 | } | 1472 | } |
1572 | 1473 | ||
1573 | p = GNUNET_malloc (sizeof (struct PendingMessage) + msize); | 1474 | ev = GNUNET_MQ_msg_extra (m, msize, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_DESTROYED); |
1574 | p->size = msize; | ||
1575 | p->is_init = GNUNET_NO; | ||
1576 | m = (struct AddressDestroyedMessage *) &p[1]; | ||
1577 | m->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_ADDRESS_DESTROYED); | ||
1578 | m->header.size = htons (msize); | ||
1579 | m->reserved = htonl (0); | ||
1580 | m->peer = address->peer; | 1475 | m->peer = address->peer; |
1581 | m->address_length = htons (address->address_length); | 1476 | m->address_length = htons (address->address_length); |
1582 | m->address_local_info = htonl ((uint32_t) address->local_info); | 1477 | m->address_local_info = htonl ((uint32_t) address->local_info); |
@@ -1590,8 +1485,7 @@ GNUNET_ATS_address_destroyed (struct GNUNET_ATS_SchedulingHandle *sh, | |||
1590 | pm = (char *) &m[1]; | 1485 | pm = (char *) &m[1]; |
1591 | memcpy (pm, address->address, address->address_length); | 1486 | memcpy (pm, address->address, address->address_length); |
1592 | memcpy (&pm[address->address_length], address->transport_name, namelen); | 1487 | memcpy (&pm[address->address_length], address->transport_name, namelen); |
1593 | GNUNET_CONTAINER_DLL_insert_tail (sh->pending_head, sh->pending_tail, p); | 1488 | GNUNET_MQ_send (sh->mq, ev); |
1594 | do_transmit (sh); | ||
1595 | remove_session (sh, s, &address->peer); | 1489 | remove_session (sh, s, &address->peer); |
1596 | } | 1490 | } |
1597 | 1491 | ||