aboutsummaryrefslogtreecommitdiff
path: root/src/ats
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-01-17 23:30:08 +0000
committerChristian Grothoff <christian@grothoff.org>2015-01-17 23:30:08 +0000
commit67733608f6251367c11277b2f2fe0ee9d8281ccc (patch)
tree42f49e5706ab36e49a25154948b6df303253ecf6 /src/ats
parentf2bbe49b6d6ae46b3981974333f9f60594c3e768 (diff)
downloadgnunet-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.c666
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 */
39struct 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 */
86struct ATS_Network 70struct 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 */
103struct GNUNET_ATS_SuggestHandle 102struct 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,
235static void 216static void
236force_reconnect (struct GNUNET_ATS_SchedulingHandle *sh) 217force_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 */
253static void
254do_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 */
264static void
265process_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 */
277static size_t
278transmit_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 */
318static void
319do_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 */
568static void 476static void
569process_release_message (struct GNUNET_ATS_SchedulingHandle *sh, 477process_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 */
583static void 498static void
584process_ats_message (void *cls, 499process_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 */
589static void
590error_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,
695static void 607static void
696reconnect (struct GNUNET_ATS_SchedulingHandle *sh) 608reconnect (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 */
746static int 675static int
747interface_proc (void *cls, 676interface_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 */
1003static int
1004free_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,
1064void 1021void
1065GNUNET_ATS_scheduling_done (struct GNUNET_ATS_SchedulingHandle *sh) 1022GNUNET_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
1115GNUNET_ATS_reset_backoff (struct GNUNET_ATS_SchedulingHandle *sh, 1064GNUNET_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 *
1148GNUNET_ATS_suggest_address (struct GNUNET_ATS_SchedulingHandle *sh, 1088GNUNET_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
1185GNUNET_ATS_suggest_address_cancel (struct GNUNET_ATS_SchedulingHandle *sh, 1119GNUNET_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