diff options
author | Christian Grothoff <christian@grothoff.org> | 2019-04-03 21:25:59 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2019-04-03 21:26:08 +0200 |
commit | 670ebb20b9570120df1021e467b575a212743125 (patch) | |
tree | e94b1e8e2bb52da66b426c861f34f8e950dcf8ed | |
parent | f13792325fc3f7e49ec2b0880eb4f1aa978e00d7 (diff) | |
download | gnunet-670ebb20b9570120df1021e467b575a212743125.tar.gz gnunet-670ebb20b9570120df1021e467b575a212743125.zip |
allow applications expressing connection preferences directly to TNG, collect HELLOs from PEERSTORE for expressed prefs
-rw-r--r-- | src/ats/gnunet-service-ats-new.c | 16 | ||||
-rw-r--r-- | src/include/gnunet_ats_application_service.h | 6 | ||||
-rw-r--r-- | src/include/gnunet_peerstore_service.h | 4 | ||||
-rw-r--r-- | src/include/gnunet_protocols.h | 12 | ||||
-rw-r--r-- | src/include/gnunet_transport_application_service.h | 100 | ||||
-rw-r--r-- | src/transport/Makefile.am | 10 | ||||
-rw-r--r-- | src/transport/gnunet-service-tng.c | 628 | ||||
-rw-r--r-- | src/transport/transport.h | 32 | ||||
-rw-r--r-- | src/transport/transport_api2_application.c | 366 |
9 files changed, 908 insertions, 266 deletions
diff --git a/src/ats/gnunet-service-ats-new.c b/src/ats/gnunet-service-ats-new.c index a1666d8d3..f2bc1de7f 100644 --- a/src/ats/gnunet-service-ats-new.c +++ b/src/ats/gnunet-service-ats-new.c | |||
@@ -304,7 +304,7 @@ prop_ntoh (const struct PropertiesNBO *properties, | |||
304 | */ | 304 | */ |
305 | static void | 305 | static void |
306 | handle_suggest (void *cls, | 306 | handle_suggest (void *cls, |
307 | const struct ExpressPreferenceMessage *msg) | 307 | const struct ExpressPreferenceMessage *msg) |
308 | { | 308 | { |
309 | struct Client *c = cls; | 309 | struct Client *c = cls; |
310 | struct ClientPreference *cp; | 310 | struct ClientPreference *cp; |
@@ -344,7 +344,7 @@ handle_suggest (void *cls, | |||
344 | */ | 344 | */ |
345 | static void | 345 | static void |
346 | handle_suggest_cancel (void *cls, | 346 | handle_suggest_cancel (void *cls, |
347 | const struct ExpressPreferenceMessage *msg) | 347 | const struct ExpressPreferenceMessage *msg) |
348 | { | 348 | { |
349 | struct Client *c = cls; | 349 | struct Client *c = cls; |
350 | struct ClientPreference *cp; | 350 | struct ClientPreference *cp; |
@@ -772,13 +772,13 @@ GNUNET_SERVICE_MAIN | |||
772 | &client_disconnect_cb, | 772 | &client_disconnect_cb, |
773 | NULL, | 773 | NULL, |
774 | GNUNET_MQ_hd_fixed_size (suggest, | 774 | GNUNET_MQ_hd_fixed_size (suggest, |
775 | GNUNET_MESSAGE_TYPE_ATS_SUGGEST, | 775 | GNUNET_MESSAGE_TYPE_ATS_SUGGEST, |
776 | struct ExpressPreferenceMessage, | 776 | struct ExpressPreferenceMessage, |
777 | NULL), | 777 | NULL), |
778 | GNUNET_MQ_hd_fixed_size (suggest_cancel, | 778 | GNUNET_MQ_hd_fixed_size (suggest_cancel, |
779 | GNUNET_MESSAGE_TYPE_ATS_SUGGEST_CANCEL, | 779 | GNUNET_MESSAGE_TYPE_ATS_SUGGEST_CANCEL, |
780 | struct ExpressPreferenceMessage, | 780 | struct ExpressPreferenceMessage, |
781 | NULL), | 781 | NULL), |
782 | GNUNET_MQ_hd_fixed_size (start, | 782 | GNUNET_MQ_hd_fixed_size (start, |
783 | GNUNET_MESSAGE_TYPE_ATS_START, | 783 | GNUNET_MESSAGE_TYPE_ATS_START, |
784 | struct GNUNET_MessageHeader, | 784 | struct GNUNET_MessageHeader, |
diff --git a/src/include/gnunet_ats_application_service.h b/src/include/gnunet_ats_application_service.h index e942ca4d8..fbc6f48ac 100644 --- a/src/include/gnunet_ats_application_service.h +++ b/src/include/gnunet_ats_application_service.h | |||
@@ -83,9 +83,9 @@ struct GNUNET_ATS_ApplicationSuggestHandle; | |||
83 | */ | 83 | */ |
84 | struct GNUNET_ATS_ApplicationSuggestHandle * | 84 | struct GNUNET_ATS_ApplicationSuggestHandle * |
85 | GNUNET_ATS_application_suggest (struct GNUNET_ATS_ApplicationHandle *ch, | 85 | GNUNET_ATS_application_suggest (struct GNUNET_ATS_ApplicationHandle *ch, |
86 | const struct GNUNET_PeerIdentity *peer, | 86 | const struct GNUNET_PeerIdentity *peer, |
87 | enum GNUNET_MQ_PreferenceKind pk, | 87 | enum GNUNET_MQ_PreferenceKind pk, |
88 | struct GNUNET_BANDWIDTH_Value32NBO bw); | 88 | struct GNUNET_BANDWIDTH_Value32NBO bw); |
89 | 89 | ||
90 | 90 | ||
91 | /** | 91 | /** |
diff --git a/src/include/gnunet_peerstore_service.h b/src/include/gnunet_peerstore_service.h index 55f371399..31567c004 100644 --- a/src/include/gnunet_peerstore_service.h +++ b/src/include/gnunet_peerstore_service.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet | 2 | This file is part of GNUnet |
3 | Copyright (C) | 3 | Copyright (C) GNUnet e.V. 2004--2019 |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 5 | GNUnet is free software: you can redistribute it and/or modify it |
6 | under the terms of the GNU Affero General Public License as published | 6 | under the terms of the GNU Affero General Public License as published |
@@ -11,7 +11,7 @@ | |||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Affero General Public License for more details. | 13 | Affero General Public License for more details. |
14 | 14 | ||
15 | You should have received a copy of the GNU Affero General Public License | 15 | You should have received a copy of the GNU Affero General Public License |
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | 17 | ||
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index 46620b829..7f1667d51 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h | |||
@@ -3177,6 +3177,18 @@ extern "C" | |||
3177 | */ | 3177 | */ |
3178 | #define GNUNET_MESSAGE_TYPE_TRANSPORT_COMMUNICATOR_FC_LIMITS 1276 | 3178 | #define GNUNET_MESSAGE_TYPE_TRANSPORT_COMMUNICATOR_FC_LIMITS 1276 |
3179 | 3179 | ||
3180 | /** | ||
3181 | * Type of the 'struct ExpressPreferenceMessage' send by clients to TRANSPORT | ||
3182 | * to establish bandwidth preference. | ||
3183 | */ | ||
3184 | #define GNUNET_MESSAGE_TYPE_TRANSPORT_SUGGEST 1300 | ||
3185 | |||
3186 | /** | ||
3187 | * Type of the 'struct ExpressPreferenceMessage' send by clients to TRANSPORT | ||
3188 | * to abandon bandwidth preference. | ||
3189 | */ | ||
3190 | #define GNUNET_MESSAGE_TYPE_TRANSPORT_SUGGEST_CANCEL 1301 | ||
3191 | |||
3180 | 3192 | ||
3181 | /* ************** NEW (NG) ATS Messages ************* */ | 3193 | /* ************** NEW (NG) ATS Messages ************* */ |
3182 | 3194 | ||
diff --git a/src/include/gnunet_transport_application_service.h b/src/include/gnunet_transport_application_service.h new file mode 100644 index 000000000..31097b88e --- /dev/null +++ b/src/include/gnunet_transport_application_service.h | |||
@@ -0,0 +1,100 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2010-2015, 2018, 2019 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | /** | ||
21 | * @file | ||
22 | * Bandwidth allocation API for applications to interact with | ||
23 | * | ||
24 | * @author Christian Grothoff | ||
25 | * @author Matthias Wachs | ||
26 | * | ||
27 | * @defgroup TRANSPORT service | ||
28 | * Bandwidth allocation | ||
29 | * | ||
30 | * @{ | ||
31 | */ | ||
32 | #ifndef GNUNET_TRANSPORT_APPLICATION_SERVICE_H | ||
33 | #define GNUNET_TRANSPORT_APPLICATION_SERVICE_H | ||
34 | |||
35 | #include "gnunet_constants.h" | ||
36 | #include "gnunet_util_lib.h" | ||
37 | |||
38 | /** | ||
39 | * Handle to the TRANSPORT subsystem for making suggestions about | ||
40 | * connections the peer would like to have. | ||
41 | */ | ||
42 | struct GNUNET_TRANSPORT_ApplicationHandle; | ||
43 | |||
44 | |||
45 | /** | ||
46 | * Initialize the TRANSPORT application client handle. | ||
47 | * | ||
48 | * @param cfg configuration to use | ||
49 | * @return ats application handle, NULL on error | ||
50 | */ | ||
51 | struct GNUNET_TRANSPORT_ApplicationHandle * | ||
52 | GNUNET_TRANSPORT_application_init (const struct GNUNET_CONFIGURATION_Handle *cfg); | ||
53 | |||
54 | |||
55 | /** | ||
56 | * Shutdown TRANSPORT application client. | ||
57 | * | ||
58 | * @param ch handle to destroy | ||
59 | */ | ||
60 | void | ||
61 | GNUNET_TRANSPORT_application_done (struct GNUNET_TRANSPORT_ApplicationHandle *ch); | ||
62 | |||
63 | |||
64 | /** | ||
65 | * Handle for suggestion requests. | ||
66 | */ | ||
67 | struct GNUNET_TRANSPORT_ApplicationSuggestHandle; | ||
68 | |||
69 | |||
70 | /** | ||
71 | * An application would like to communicate with a peer. TRANSPORT should | ||
72 | * allocate bandwith using a suitable address for requiremetns @a pk | ||
73 | * to transport. | ||
74 | * | ||
75 | * @param ch handle | ||
76 | * @param peer identity of the peer we need an address for | ||
77 | * @param pk what kind of application will the application require (can be | ||
78 | * #GNUNET_MQ_PREFERENCE_NONE, we will still try to connect) | ||
79 | * @param bw desired bandwith, can be zero (we will still try to connect) | ||
80 | * @return suggestion handle, NULL if request is already pending | ||
81 | */ | ||
82 | struct GNUNET_TRANSPORT_ApplicationSuggestHandle * | ||
83 | GNUNET_TRANSPORT_application_suggest (struct GNUNET_TRANSPORT_ApplicationHandle *ch, | ||
84 | const struct GNUNET_PeerIdentity *peer, | ||
85 | enum GNUNET_MQ_PreferenceKind pk, | ||
86 | struct GNUNET_BANDWIDTH_Value32NBO bw); | ||
87 | |||
88 | |||
89 | /** | ||
90 | * We no longer care about communicating with a peer. | ||
91 | * | ||
92 | * @param sh handle | ||
93 | */ | ||
94 | void | ||
95 | GNUNET_TRANSPORT_application_suggest_cancel (struct GNUNET_TRANSPORT_ApplicationSuggestHandle *sh); | ||
96 | |||
97 | /** @} */ /* end of group */ | ||
98 | |||
99 | #endif | ||
100 | /* end of file gnunet_ats_application_service.h */ | ||
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am index cd31f7cd7..2865460fd 100644 --- a/src/transport/Makefile.am +++ b/src/transport/Makefile.am | |||
@@ -155,6 +155,7 @@ endif | |||
155 | lib_LTLIBRARIES = \ | 155 | lib_LTLIBRARIES = \ |
156 | libgnunettransport.la \ | 156 | libgnunettransport.la \ |
157 | libgnunettransportaddress.la \ | 157 | libgnunettransportaddress.la \ |
158 | libgnunettransportapplication.la \ | ||
158 | libgnunettransportcore.la \ | 159 | libgnunettransportcore.la \ |
159 | libgnunettransportcommunicator.la \ | 160 | libgnunettransportcommunicator.la \ |
160 | libgnunettransportmonitor.la \ | 161 | libgnunettransportmonitor.la \ |
@@ -196,6 +197,14 @@ libgnunettransport_la_LDFLAGS = \ | |||
196 | $(GN_LIB_LDFLAGS) $(WINFLAGS) \ | 197 | $(GN_LIB_LDFLAGS) $(WINFLAGS) \ |
197 | -version-info 4:0:2 | 198 | -version-info 4:0:2 |
198 | 199 | ||
200 | libgnunettransportapplication_la_SOURCES = \ | ||
201 | transport_api2_application.c | ||
202 | libgnunettransportapplication_la_LIBADD = \ | ||
203 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
204 | $(LTLIBINTL) | ||
205 | libgnunettransportapplication_la_LDFLAGS = \ | ||
206 | $(GN_LIB_LDFLAGS) $(WINFLAGS) \ | ||
207 | -version-info 0:0:0 | ||
199 | 208 | ||
200 | 209 | ||
201 | libgnunettransportaddress_la_SOURCES = \ | 210 | libgnunettransportaddress_la_SOURCES = \ |
@@ -360,7 +369,6 @@ gnunet_service_transport_CFLAGS = \ | |||
360 | gnunet_service_tng_SOURCES = \ | 369 | gnunet_service_tng_SOURCES = \ |
361 | gnunet-service-tng.c | 370 | gnunet-service-tng.c |
362 | gnunet_service_tng_LDADD = \ | 371 | gnunet_service_tng_LDADD = \ |
363 | $(top_builddir)/src/ats/libgnunetatstransport.la \ | ||
364 | $(top_builddir)/src/peerstore/libgnunetpeerstore.la \ | 372 | $(top_builddir)/src/peerstore/libgnunetpeerstore.la \ |
365 | $(top_builddir)/src/hello/libgnunethello.la \ | 373 | $(top_builddir)/src/hello/libgnunethello.la \ |
366 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | 374 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ |
diff --git a/src/transport/gnunet-service-tng.c b/src/transport/gnunet-service-tng.c index b64bfb182..6494a5dfd 100644 --- a/src/transport/gnunet-service-tng.c +++ b/src/transport/gnunet-service-tng.c | |||
@@ -41,7 +41,7 @@ | |||
41 | * #3 transport should use validation to also establish | 41 | * #3 transport should use validation to also establish |
42 | * effective flow control (for uni-directional transports!) | 42 | * effective flow control (for uni-directional transports!) |
43 | * #4 UDP broadcasting logic must be extended to use the new API | 43 | * #4 UDP broadcasting logic must be extended to use the new API |
44 | * #5 only validated addresses go to ATS for scheduling; that | 44 | * #5 only validated addresses are selected for scheduling; that |
45 | * also ensures we know the RTT | 45 | * also ensures we know the RTT |
46 | * #6 to ensure flow control and RTT are OK, we always do the | 46 | * #6 to ensure flow control and RTT are OK, we always do the |
47 | * 'validation', even if address comes from PEERSTORE | 47 | * 'validation', even if address comes from PEERSTORE |
@@ -59,10 +59,7 @@ | |||
59 | * - | 59 | * - |
60 | * | 60 | * |
61 | * Easy: | 61 | * Easy: |
62 | * - use ATS bandwidth allocation callback and schedule transmissions! | 62 | * - figure out how to call XXX_suggestion_cb! |
63 | * | ||
64 | * Plan: | ||
65 | * - inform ATS about RTT, goodput/loss, overheads, etc. (GNUNET_ATS_session_update()) | ||
66 | * | 63 | * |
67 | * Later: | 64 | * Later: |
68 | * - change transport-core API to provide proper flow control in both | 65 | * - change transport-core API to provide proper flow control in both |
@@ -98,8 +95,6 @@ | |||
98 | * "latest timestamps seen" data | 95 | * "latest timestamps seen" data |
99 | * - if transport implements DV, we likely need a 3rd peermap | 96 | * - if transport implements DV, we likely need a 3rd peermap |
100 | * in addition to ephemerals and (direct) neighbours | 97 | * in addition to ephemerals and (direct) neighbours |
101 | * => in this data structure, we should track ATS metrics (distance, RTT, etc.) | ||
102 | * as well as latest timestamps seen, goodput, fragments for transmission, etc. | ||
103 | * ==> check if stuff needs to be moved out of "Neighbour" | 98 | * ==> check if stuff needs to be moved out of "Neighbour" |
104 | * - transport should encapsualte core-level messages and do its | 99 | * - transport should encapsualte core-level messages and do its |
105 | * own ACKing for RTT/goodput/loss measurements _and_ fragment | 100 | * own ACKing for RTT/goodput/loss measurements _and_ fragment |
@@ -111,7 +106,6 @@ | |||
111 | #include "gnunet_transport_monitor_service.h" | 106 | #include "gnunet_transport_monitor_service.h" |
112 | #include "gnunet_peerstore_service.h" | 107 | #include "gnunet_peerstore_service.h" |
113 | #include "gnunet_hello_lib.h" | 108 | #include "gnunet_hello_lib.h" |
114 | #include "gnunet_ats_transport_service.h" | ||
115 | #include "gnunet_signatures.h" | 109 | #include "gnunet_signatures.h" |
116 | #include "transport.h" | 110 | #include "transport.h" |
117 | 111 | ||
@@ -148,18 +142,11 @@ | |||
148 | #define COMMUNICATOR_TOTAL_QUEUE_LIMIT 512 | 142 | #define COMMUNICATOR_TOTAL_QUEUE_LIMIT 512 |
149 | 143 | ||
150 | /** | 144 | /** |
151 | * How many messages can we have pending for a given session (queue to | 145 | * How many messages can we have pending for a given queue (queue to |
152 | * a particular peer via a communicator) process before we start to | 146 | * a particular peer via a communicator) process before we start to |
153 | * throttle that queue? | 147 | * throttle that queue? |
154 | * | ||
155 | * Used if ATS assigns more bandwidth to a particular transmission | ||
156 | * method than that transmission method can right now handle. (Yes, | ||
157 | * ATS should eventually notice utilization below allocation and | ||
158 | * adjust, but we don't want to queue up tons of messages in the | ||
159 | * meantime). Must be significantly below | ||
160 | * #COMMUNICATOR_TOTAL_QUEUE_LIMIT. | ||
161 | */ | 148 | */ |
162 | #define SESSION_QUEUE_LIMIT 32 | 149 | #define QUEUE_LENGTH_LIMIT 32 |
163 | 150 | ||
164 | 151 | ||
165 | GNUNET_NETWORK_STRUCT_BEGIN | 152 | GNUNET_NETWORK_STRUCT_BEGIN |
@@ -547,7 +534,6 @@ struct TransportDVBox | |||
547 | GNUNET_NETWORK_STRUCT_END | 534 | GNUNET_NETWORK_STRUCT_END |
548 | 535 | ||
549 | 536 | ||
550 | |||
551 | /** | 537 | /** |
552 | * What type of client is the `struct TransportClient` about? | 538 | * What type of client is the `struct TransportClient` about? |
553 | */ | 539 | */ |
@@ -571,7 +557,12 @@ enum ClientType | |||
571 | /** | 557 | /** |
572 | * It is a communicator, use for communication. | 558 | * It is a communicator, use for communication. |
573 | */ | 559 | */ |
574 | CT_COMMUNICATOR = 3 | 560 | CT_COMMUNICATOR = 3, |
561 | |||
562 | /** | ||
563 | * "Application" telling us where to connect (i.e. TOPOLOGY, DHT or CADET). | ||
564 | */ | ||
565 | CT_APPLICATION = 4 | ||
575 | }; | 566 | }; |
576 | 567 | ||
577 | 568 | ||
@@ -725,11 +716,18 @@ struct DistanceVector | |||
725 | 716 | ||
726 | 717 | ||
727 | /** | 718 | /** |
719 | * A queue is a message queue provided by a communicator | ||
720 | * via which we can reach a particular neighbour. | ||
721 | */ | ||
722 | struct Queue; | ||
723 | |||
724 | |||
725 | /** | ||
728 | * Entry identifying transmission in one of our `struct | 726 | * Entry identifying transmission in one of our `struct |
729 | * GNUNET_ATS_Sessions` which still awaits an ACK. This is used to | 727 | * Queue` which still awaits an ACK. This is used to |
730 | * ensure we do not overwhelm a communicator and limit the number of | 728 | * ensure we do not overwhelm a communicator and limit the number of |
731 | * messages outstanding per communicator (say in case communicator is | 729 | * messages outstanding per communicator (say in case communicator is |
732 | * CPU bound) and per queue (in case ATS bandwidth allocation exceeds | 730 | * CPU bound) and per queue (in case bandwidth allocation exceeds |
733 | * what the communicator can actually provide towards a particular | 731 | * what the communicator can actually provide towards a particular |
734 | * peer/target). | 732 | * peer/target). |
735 | */ | 733 | */ |
@@ -747,9 +745,9 @@ struct QueueEntry | |||
747 | struct QueueEntry *prev; | 745 | struct QueueEntry *prev; |
748 | 746 | ||
749 | /** | 747 | /** |
750 | * ATS session this entry is queued with. | 748 | * Queue this entry is queued with. |
751 | */ | 749 | */ |
752 | struct GNUNET_ATS_Session *session; | 750 | struct Queue *queue; |
753 | 751 | ||
754 | /** | 752 | /** |
755 | * Message ID used for this message with the queue used for transmission. | 753 | * Message ID used for this message with the queue used for transmission. |
@@ -759,30 +757,30 @@ struct QueueEntry | |||
759 | 757 | ||
760 | 758 | ||
761 | /** | 759 | /** |
762 | * An ATS session is a message queue provided by a communicator | 760 | * A queue is a message queue provided by a communicator |
763 | * via which we can reach a particular neighbour. | 761 | * via which we can reach a particular neighbour. |
764 | */ | 762 | */ |
765 | struct GNUNET_ATS_Session | 763 | struct Queue |
766 | { | 764 | { |
767 | /** | 765 | /** |
768 | * Kept in a MDLL. | 766 | * Kept in a MDLL. |
769 | */ | 767 | */ |
770 | struct GNUNET_ATS_Session *next_neighbour; | 768 | struct Queue *next_neighbour; |
771 | 769 | ||
772 | /** | 770 | /** |
773 | * Kept in a MDLL. | 771 | * Kept in a MDLL. |
774 | */ | 772 | */ |
775 | struct GNUNET_ATS_Session *prev_neighbour; | 773 | struct Queue *prev_neighbour; |
776 | 774 | ||
777 | /** | 775 | /** |
778 | * Kept in a MDLL. | 776 | * Kept in a MDLL. |
779 | */ | 777 | */ |
780 | struct GNUNET_ATS_Session *prev_client; | 778 | struct Queue *prev_client; |
781 | 779 | ||
782 | /** | 780 | /** |
783 | * Kept in a MDLL. | 781 | * Kept in a MDLL. |
784 | */ | 782 | */ |
785 | struct GNUNET_ATS_Session *next_client; | 783 | struct Queue *next_client; |
786 | 784 | ||
787 | /** | 785 | /** |
788 | * Head of DLL of unacked transmission requests. | 786 | * Head of DLL of unacked transmission requests. |
@@ -795,33 +793,28 @@ struct GNUNET_ATS_Session | |||
795 | struct QueueEntry *queue_tail; | 793 | struct QueueEntry *queue_tail; |
796 | 794 | ||
797 | /** | 795 | /** |
798 | * Which neighbour is this ATS session for? | 796 | * Which neighbour is this queue for? |
799 | */ | 797 | */ |
800 | struct Neighbour *neighbour; | 798 | struct Neighbour *neighbour; |
801 | 799 | ||
802 | /** | 800 | /** |
803 | * Which communicator offers this ATS session? | 801 | * Which communicator offers this queue? |
804 | */ | 802 | */ |
805 | struct TransportClient *tc; | 803 | struct TransportClient *tc; |
806 | 804 | ||
807 | /** | 805 | /** |
808 | * Address served by the ATS session. | 806 | * Address served by the queue. |
809 | */ | 807 | */ |
810 | const char *address; | 808 | const char *address; |
811 | 809 | ||
812 | /** | 810 | /** |
813 | * Handle by which we inform ATS about this queue. | ||
814 | */ | ||
815 | struct GNUNET_ATS_SessionRecord *sr; | ||
816 | |||
817 | /** | ||
818 | * Task scheduled for the time when this queue can (likely) transmit the | 811 | * Task scheduled for the time when this queue can (likely) transmit the |
819 | * next message. Still needs to check with the @e tracker_out to be sure. | 812 | * next message. Still needs to check with the @e tracker_out to be sure. |
820 | */ | 813 | */ |
821 | struct GNUNET_SCHEDULER_Task *transmit_task; | 814 | struct GNUNET_SCHEDULER_Task *transmit_task; |
822 | 815 | ||
823 | /** | 816 | /** |
824 | * Our current RTT estimate for this ATS session. | 817 | * Our current RTT estimate for this queue. |
825 | */ | 818 | */ |
826 | struct GNUNET_TIME_Relative rtt; | 819 | struct GNUNET_TIME_Relative rtt; |
827 | 820 | ||
@@ -831,17 +824,17 @@ struct GNUNET_ATS_Session | |||
831 | uint64_t mid_gen; | 824 | uint64_t mid_gen; |
832 | 825 | ||
833 | /** | 826 | /** |
834 | * Unique identifier of this ATS session with the communicator. | 827 | * Unique identifier of this queue with the communicator. |
835 | */ | 828 | */ |
836 | uint32_t qid; | 829 | uint32_t qid; |
837 | 830 | ||
838 | /** | 831 | /** |
839 | * Maximum transmission unit supported by this ATS session. | 832 | * Maximum transmission unit supported by this queue. |
840 | */ | 833 | */ |
841 | uint32_t mtu; | 834 | uint32_t mtu; |
842 | 835 | ||
843 | /** | 836 | /** |
844 | * Distance to the target of this ATS session. | 837 | * Distance to the target of this queue. |
845 | */ | 838 | */ |
846 | uint32_t distance; | 839 | uint32_t distance; |
847 | 840 | ||
@@ -861,22 +854,22 @@ struct GNUNET_ATS_Session | |||
861 | unsigned int queue_length; | 854 | unsigned int queue_length; |
862 | 855 | ||
863 | /** | 856 | /** |
864 | * Network type offered by this ATS session. | 857 | * Network type offered by this queue. |
865 | */ | 858 | */ |
866 | enum GNUNET_NetworkType nt; | 859 | enum GNUNET_NetworkType nt; |
867 | 860 | ||
868 | /** | 861 | /** |
869 | * Connection status for this ATS session. | 862 | * Connection status for this queue. |
870 | */ | 863 | */ |
871 | enum GNUNET_TRANSPORT_ConnectionStatus cs; | 864 | enum GNUNET_TRANSPORT_ConnectionStatus cs; |
872 | 865 | ||
873 | /** | 866 | /** |
874 | * How much outbound bandwidth do we have available for this session? | 867 | * How much outbound bandwidth do we have available for this queue? |
875 | */ | 868 | */ |
876 | struct GNUNET_BANDWIDTH_Tracker tracker_out; | 869 | struct GNUNET_BANDWIDTH_Tracker tracker_out; |
877 | 870 | ||
878 | /** | 871 | /** |
879 | * How much inbound bandwidth do we have available for this session? | 872 | * How much inbound bandwidth do we have available for this queue? |
880 | */ | 873 | */ |
881 | struct GNUNET_BANDWIDTH_Tracker tracker_in; | 874 | struct GNUNET_BANDWIDTH_Tracker tracker_in; |
882 | }; | 875 | }; |
@@ -1025,14 +1018,14 @@ struct Neighbour | |||
1025 | struct DistanceVectorHop *dv_tail; | 1018 | struct DistanceVectorHop *dv_tail; |
1026 | 1019 | ||
1027 | /** | 1020 | /** |
1028 | * Head of DLL of ATS sessions to this peer. | 1021 | * Head of DLL of queues to this peer. |
1029 | */ | 1022 | */ |
1030 | struct GNUNET_ATS_Session *session_head; | 1023 | struct Queue *queue_head; |
1031 | 1024 | ||
1032 | /** | 1025 | /** |
1033 | * Tail of DLL of ATS sessions to this peer. | 1026 | * Tail of DLL of queues to this peer. |
1034 | */ | 1027 | */ |
1035 | struct GNUNET_ATS_Session *session_tail; | 1028 | struct Queue *queue_tail; |
1036 | 1029 | ||
1037 | /** | 1030 | /** |
1038 | * Task run to cleanup pending messages that have exceeded their timeout. | 1031 | * Task run to cleanup pending messages that have exceeded their timeout. |
@@ -1040,13 +1033,12 @@ struct Neighbour | |||
1040 | struct GNUNET_SCHEDULER_Task *timeout_task; | 1033 | struct GNUNET_SCHEDULER_Task *timeout_task; |
1041 | 1034 | ||
1042 | /** | 1035 | /** |
1043 | * Quota at which CORE is allowed to transmit to this peer | 1036 | * Quota at which CORE is allowed to transmit to this peer. |
1044 | * according to ATS. | ||
1045 | * | 1037 | * |
1046 | * FIXME: not yet used, tricky to get right given multiple queues! | 1038 | * FIXME: not yet used, tricky to get right given multiple queues! |
1047 | * (=> Idea: let ATS set a quota per queue and we add them up here?) | 1039 | * (=> Idea: measure???) |
1048 | * FIXME: how do we set this value initially when we tell CORE? | 1040 | * FIXME: how do we set this value initially when we tell CORE? |
1049 | * Options: start at a minimum value or at literally zero (before ATS?) | 1041 | * Options: start at a minimum value or at literally zero? |
1050 | * (=> Current thought: clean would be zero!) | 1042 | * (=> Current thought: clean would be zero!) |
1051 | */ | 1043 | */ |
1052 | struct GNUNET_BANDWIDTH_Value32NBO quota_out; | 1044 | struct GNUNET_BANDWIDTH_Value32NBO quota_out; |
@@ -1060,6 +1052,40 @@ struct Neighbour | |||
1060 | 1052 | ||
1061 | 1053 | ||
1062 | /** | 1054 | /** |
1055 | * A peer that an application (client) would like us to talk to directly. | ||
1056 | */ | ||
1057 | struct PeerRequest | ||
1058 | { | ||
1059 | |||
1060 | /** | ||
1061 | * Which peer is this about? | ||
1062 | */ | ||
1063 | struct GNUNET_PeerIdentity pid; | ||
1064 | |||
1065 | /** | ||
1066 | * Client responsible for the request. | ||
1067 | */ | ||
1068 | struct TransportClient *tc; | ||
1069 | |||
1070 | /** | ||
1071 | * Handle for watching the peerstore for HELLOs for this peer. | ||
1072 | */ | ||
1073 | struct GNUNET_PEERSTORE_WatchContext *wc; | ||
1074 | |||
1075 | /** | ||
1076 | * What kind of performance preference does this @e tc have? | ||
1077 | */ | ||
1078 | enum GNUNET_MQ_PreferenceKind pk; | ||
1079 | |||
1080 | /** | ||
1081 | * How much bandwidth would this @e tc like to see? | ||
1082 | */ | ||
1083 | struct GNUNET_BANDWIDTH_Value32NBO bw; | ||
1084 | |||
1085 | }; | ||
1086 | |||
1087 | |||
1088 | /** | ||
1063 | * Types of different pending messages. | 1089 | * Types of different pending messages. |
1064 | */ | 1090 | */ |
1065 | enum PendingMessageType | 1091 | enum PendingMessageType |
@@ -1362,12 +1388,12 @@ struct TransportClient | |||
1362 | /** | 1388 | /** |
1363 | * Head of DLL of queues offered by this communicator. | 1389 | * Head of DLL of queues offered by this communicator. |
1364 | */ | 1390 | */ |
1365 | struct GNUNET_ATS_Session *session_head; | 1391 | struct Queue *queue_head; |
1366 | 1392 | ||
1367 | /** | 1393 | /** |
1368 | * Tail of DLL of queues offered by this communicator. | 1394 | * Tail of DLL of queues offered by this communicator. |
1369 | */ | 1395 | */ |
1370 | struct GNUNET_ATS_Session *session_tail; | 1396 | struct Queue *queue_tail; |
1371 | 1397 | ||
1372 | /** | 1398 | /** |
1373 | * Head of list of the addresses of this peer offered by this communicator. | 1399 | * Head of list of the addresses of this peer offered by this communicator. |
@@ -1393,6 +1419,19 @@ struct TransportClient | |||
1393 | 1419 | ||
1394 | } communicator; | 1420 | } communicator; |
1395 | 1421 | ||
1422 | /** | ||
1423 | * Information for @e type #CT_APPLICATION | ||
1424 | */ | ||
1425 | struct { | ||
1426 | |||
1427 | /** | ||
1428 | * Map of requests for peers the given client application would like to | ||
1429 | * see connections for. Maps from PIDs to `struct PeerRequest`. | ||
1430 | */ | ||
1431 | struct GNUNET_CONTAINER_MultiPeerMap *requests; | ||
1432 | |||
1433 | } application; | ||
1434 | |||
1396 | } details; | 1435 | } details; |
1397 | 1436 | ||
1398 | }; | 1437 | }; |
@@ -1465,11 +1504,6 @@ static struct GNUNET_CONTAINER_MultiPeerMap *ephemeral_map; | |||
1465 | */ | 1504 | */ |
1466 | static struct GNUNET_SCHEDULER_Task *ephemeral_task; | 1505 | static struct GNUNET_SCHEDULER_Task *ephemeral_task; |
1467 | 1506 | ||
1468 | /** | ||
1469 | * Our connection to ATS for allocation and bootstrapping. | ||
1470 | */ | ||
1471 | static struct GNUNET_ATS_TransportHandle *ats; | ||
1472 | |||
1473 | 1507 | ||
1474 | /** | 1508 | /** |
1475 | * Free cached ephemeral key. | 1509 | * Free cached ephemeral key. |
@@ -1781,7 +1815,7 @@ free_neighbour (struct Neighbour *neighbour) | |||
1781 | { | 1815 | { |
1782 | struct DistanceVectorHop *dvh; | 1816 | struct DistanceVectorHop *dvh; |
1783 | 1817 | ||
1784 | GNUNET_assert (NULL == neighbour->session_head); | 1818 | GNUNET_assert (NULL == neighbour->queue_head); |
1785 | GNUNET_assert (GNUNET_YES == | 1819 | GNUNET_assert (GNUNET_YES == |
1786 | GNUNET_CONTAINER_multipeermap_remove (neighbours, | 1820 | GNUNET_CONTAINER_multipeermap_remove (neighbours, |
1787 | &neighbour->pid, | 1821 | &neighbour->pid, |
@@ -1886,7 +1920,7 @@ cores_send_disconnect_info (const struct GNUNET_PeerIdentity *pid) | |||
1886 | * communicator for transmission (updating the tracker, and re-scheduling | 1920 | * communicator for transmission (updating the tracker, and re-scheduling |
1887 | * itself if applicable). | 1921 | * itself if applicable). |
1888 | * | 1922 | * |
1889 | * @param cls the `struct GNUNET_ATS_Session` to process transmissions for | 1923 | * @param cls the `struct Queue` to process transmissions for |
1890 | */ | 1924 | */ |
1891 | static void | 1925 | static void |
1892 | transmit_on_queue (void *cls); | 1926 | transmit_on_queue (void *cls); |
@@ -1902,7 +1936,7 @@ transmit_on_queue (void *cls); | |||
1902 | * @param queue the queue to do scheduling for | 1936 | * @param queue the queue to do scheduling for |
1903 | */ | 1937 | */ |
1904 | static void | 1938 | static void |
1905 | schedule_transmit_on_queue (struct GNUNET_ATS_Session *queue) | 1939 | schedule_transmit_on_queue (struct Queue *queue) |
1906 | { | 1940 | { |
1907 | struct Neighbour *n = queue->neighbour; | 1941 | struct Neighbour *n = queue->neighbour; |
1908 | struct PendingMessage *pm = n->pending_msg_head; | 1942 | struct PendingMessage *pm = n->pending_msg_head; |
@@ -1919,10 +1953,10 @@ schedule_transmit_on_queue (struct GNUNET_ATS_Session *queue) | |||
1919 | GNUNET_NO); | 1953 | GNUNET_NO); |
1920 | return; | 1954 | return; |
1921 | } | 1955 | } |
1922 | if (queue->queue_length >= SESSION_QUEUE_LIMIT) | 1956 | if (queue->queue_length >= QUEUE_LENGTH_LIMIT) |
1923 | { | 1957 | { |
1924 | GNUNET_STATISTICS_update (GST_stats, | 1958 | GNUNET_STATISTICS_update (GST_stats, |
1925 | "# Transmission throttled due to session queue limit", | 1959 | "# Transmission throttled due to queue queue limit", |
1926 | 1, | 1960 | 1, |
1927 | GNUNET_NO); | 1961 | GNUNET_NO); |
1928 | return; | 1962 | return; |
@@ -1958,15 +1992,15 @@ schedule_transmit_on_queue (struct GNUNET_ATS_Session *queue) | |||
1958 | 1992 | ||
1959 | 1993 | ||
1960 | /** | 1994 | /** |
1961 | * Free @a session. | 1995 | * Free @a queue. |
1962 | * | 1996 | * |
1963 | * @param session the session to free | 1997 | * @param queue the queue to free |
1964 | */ | 1998 | */ |
1965 | static void | 1999 | static void |
1966 | free_session (struct GNUNET_ATS_Session *session) | 2000 | free_queue (struct Queue *queue) |
1967 | { | 2001 | { |
1968 | struct Neighbour *neighbour = session->neighbour; | 2002 | struct Neighbour *neighbour = queue->neighbour; |
1969 | struct TransportClient *tc = session->tc; | 2003 | struct TransportClient *tc = queue->tc; |
1970 | struct MonitorEvent me = { | 2004 | struct MonitorEvent me = { |
1971 | .cs = GNUNET_TRANSPORT_CS_DOWN, | 2005 | .cs = GNUNET_TRANSPORT_CS_DOWN, |
1972 | .rtt = GNUNET_TIME_UNIT_FOREVER_REL | 2006 | .rtt = GNUNET_TIME_UNIT_FOREVER_REL |
@@ -1974,30 +2008,30 @@ free_session (struct GNUNET_ATS_Session *session) | |||
1974 | struct QueueEntry *qe; | 2008 | struct QueueEntry *qe; |
1975 | int maxxed; | 2009 | int maxxed; |
1976 | 2010 | ||
1977 | if (NULL != session->transmit_task) | 2011 | if (NULL != queue->transmit_task) |
1978 | { | 2012 | { |
1979 | GNUNET_SCHEDULER_cancel (session->transmit_task); | 2013 | GNUNET_SCHEDULER_cancel (queue->transmit_task); |
1980 | session->transmit_task = NULL; | 2014 | queue->transmit_task = NULL; |
1981 | } | 2015 | } |
1982 | GNUNET_CONTAINER_MDLL_remove (neighbour, | 2016 | GNUNET_CONTAINER_MDLL_remove (neighbour, |
1983 | neighbour->session_head, | 2017 | neighbour->queue_head, |
1984 | neighbour->session_tail, | 2018 | neighbour->queue_tail, |
1985 | session); | 2019 | queue); |
1986 | GNUNET_CONTAINER_MDLL_remove (client, | 2020 | GNUNET_CONTAINER_MDLL_remove (client, |
1987 | tc->details.communicator.session_head, | 2021 | tc->details.communicator.queue_head, |
1988 | tc->details.communicator.session_tail, | 2022 | tc->details.communicator.queue_tail, |
1989 | session); | 2023 | queue); |
1990 | maxxed = (COMMUNICATOR_TOTAL_QUEUE_LIMIT >= tc->details.communicator.total_queue_length); | 2024 | maxxed = (COMMUNICATOR_TOTAL_QUEUE_LIMIT >= tc->details.communicator.total_queue_length); |
1991 | while (NULL != (qe = session->queue_head)) | 2025 | while (NULL != (qe = queue->queue_head)) |
1992 | { | 2026 | { |
1993 | GNUNET_CONTAINER_DLL_remove (session->queue_head, | 2027 | GNUNET_CONTAINER_DLL_remove (queue->queue_head, |
1994 | session->queue_tail, | 2028 | queue->queue_tail, |
1995 | qe); | 2029 | qe); |
1996 | session->queue_length--; | 2030 | queue->queue_length--; |
1997 | tc->details.communicator.total_queue_length--; | 2031 | tc->details.communicator.total_queue_length--; |
1998 | GNUNET_free (qe); | 2032 | GNUNET_free (qe); |
1999 | } | 2033 | } |
2000 | GNUNET_assert (0 == session->queue_length); | 2034 | GNUNET_assert (0 == queue->queue_length); |
2001 | if ( (maxxed) && | 2035 | if ( (maxxed) && |
2002 | (COMMUNICATOR_TOTAL_QUEUE_LIMIT < tc->details.communicator.total_queue_length) ) | 2036 | (COMMUNICATOR_TOTAL_QUEUE_LIMIT < tc->details.communicator.total_queue_length) ) |
2003 | { | 2037 | { |
@@ -2006,20 +2040,19 @@ free_session (struct GNUNET_ATS_Session *session) | |||
2006 | "# Transmission throttled due to communicator queue limit", | 2040 | "# Transmission throttled due to communicator queue limit", |
2007 | -1, | 2041 | -1, |
2008 | GNUNET_NO); | 2042 | GNUNET_NO); |
2009 | for (struct GNUNET_ATS_Session *s = tc->details.communicator.session_head; | 2043 | for (struct Queue *s = tc->details.communicator.queue_head; |
2010 | NULL != s; | 2044 | NULL != s; |
2011 | s = s->next_client) | 2045 | s = s->next_client) |
2012 | schedule_transmit_on_queue (s); | 2046 | schedule_transmit_on_queue (s); |
2013 | } | 2047 | } |
2014 | notify_monitors (&neighbour->pid, | 2048 | notify_monitors (&neighbour->pid, |
2015 | session->address, | 2049 | queue->address, |
2016 | session->nt, | 2050 | queue->nt, |
2017 | &me); | 2051 | &me); |
2018 | GNUNET_ATS_session_del (session->sr); | 2052 | GNUNET_BANDWIDTH_tracker_notification_stop (&queue->tracker_in); |
2019 | GNUNET_BANDWIDTH_tracker_notification_stop (&session->tracker_in); | 2053 | GNUNET_BANDWIDTH_tracker_notification_stop (&queue->tracker_out); |
2020 | GNUNET_BANDWIDTH_tracker_notification_stop (&session->tracker_out); | 2054 | GNUNET_free (queue); |
2021 | GNUNET_free (session); | 2055 | if (NULL == neighbour->queue_head) |
2022 | if (NULL == neighbour->session_head) | ||
2023 | { | 2056 | { |
2024 | cores_send_disconnect_info (&neighbour->pid); | 2057 | cores_send_disconnect_info (&neighbour->pid); |
2025 | free_neighbour (neighbour); | 2058 | free_neighbour (neighbour); |
@@ -2055,6 +2088,33 @@ free_address_list_entry (struct AddressListEntry *ale) | |||
2055 | 2088 | ||
2056 | 2089 | ||
2057 | /** | 2090 | /** |
2091 | * Stop the peer request in @a value. | ||
2092 | * | ||
2093 | * @param cls a `struct TransportClient` that no longer makes the request | ||
2094 | * @param pid the peer's identity | ||
2095 | * @param value a `struct PeerRequest` | ||
2096 | * @return #GNUNET_YES (always) | ||
2097 | */ | ||
2098 | static int | ||
2099 | stop_peer_request (void *cls, | ||
2100 | const struct GNUNET_PeerIdentity *pid, | ||
2101 | void *value) | ||
2102 | { | ||
2103 | struct TransportClient *tc = cls; | ||
2104 | struct PeerRequest *pr = value; | ||
2105 | |||
2106 | GNUNET_PEERSTORE_watch_cancel (pr->wc); | ||
2107 | GNUNET_assert (GNUNET_YES == | ||
2108 | GNUNET_CONTAINER_multipeermap_remove (tc->details.application.requests, | ||
2109 | pid, | ||
2110 | pr)); | ||
2111 | GNUNET_free (pr); | ||
2112 | |||
2113 | return GNUNET_OK; | ||
2114 | } | ||
2115 | |||
2116 | |||
2117 | /** | ||
2058 | * Called whenever a client is disconnected. Frees our | 2118 | * Called whenever a client is disconnected. Frees our |
2059 | * resources associated with that client. | 2119 | * resources associated with that client. |
2060 | * | 2120 | * |
@@ -2097,16 +2157,22 @@ client_disconnect_cb (void *cls, | |||
2097 | break; | 2157 | break; |
2098 | case CT_COMMUNICATOR: | 2158 | case CT_COMMUNICATOR: |
2099 | { | 2159 | { |
2100 | struct GNUNET_ATS_Session *q; | 2160 | struct Queue *q; |
2101 | struct AddressListEntry *ale; | 2161 | struct AddressListEntry *ale; |
2102 | 2162 | ||
2103 | while (NULL != (q = tc->details.communicator.session_head)) | 2163 | while (NULL != (q = tc->details.communicator.queue_head)) |
2104 | free_session (q); | 2164 | free_queue (q); |
2105 | while (NULL != (ale = tc->details.communicator.addr_head)) | 2165 | while (NULL != (ale = tc->details.communicator.addr_head)) |
2106 | free_address_list_entry (ale); | 2166 | free_address_list_entry (ale); |
2107 | GNUNET_free (tc->details.communicator.address_prefix); | 2167 | GNUNET_free (tc->details.communicator.address_prefix); |
2108 | } | 2168 | } |
2109 | break; | 2169 | break; |
2170 | case CT_APPLICATION: | ||
2171 | GNUNET_CONTAINER_multipeermap_iterate (tc->details.application.requests, | ||
2172 | &stop_peer_request, | ||
2173 | tc); | ||
2174 | GNUNET_CONTAINER_multipeermap_destroy (tc->details.application.requests); | ||
2175 | break; | ||
2110 | } | 2176 | } |
2111 | GNUNET_free (tc); | 2177 | GNUNET_free (tc); |
2112 | } | 2178 | } |
@@ -2419,7 +2485,7 @@ handle_client_send (void *cls, | |||
2419 | } | 2485 | } |
2420 | if (! was_empty) | 2486 | if (! was_empty) |
2421 | return; /* all queues must already be busy */ | 2487 | return; /* all queues must already be busy */ |
2422 | for (struct GNUNET_ATS_Session *queue = target->session_head; | 2488 | for (struct Queue *queue = target->queue_head; |
2423 | NULL != queue; | 2489 | NULL != queue; |
2424 | queue = queue->next_neighbour) | 2490 | queue = queue->next_neighbour) |
2425 | { | 2491 | { |
@@ -2491,7 +2557,7 @@ handle_communicator_available (void *cls, | |||
2491 | */ | 2557 | */ |
2492 | static int | 2558 | static int |
2493 | check_communicator_backchannel (void *cls, | 2559 | check_communicator_backchannel (void *cls, |
2494 | const struct GNUNET_TRANSPORT_CommunicatorBackchannel *cb) | 2560 | const struct GNUNET_TRANSPORT_CommunicatorBackchannel *cb) |
2495 | { | 2561 | { |
2496 | const struct GNUNET_MessageHeader *inbox; | 2562 | const struct GNUNET_MessageHeader *inbox; |
2497 | const char *is; | 2563 | const char *is; |
@@ -2565,10 +2631,10 @@ expire_ephemerals (void *cls) | |||
2565 | */ | 2631 | */ |
2566 | static void | 2632 | static void |
2567 | lookup_ephemeral (const struct GNUNET_PeerIdentity *pid, | 2633 | lookup_ephemeral (const struct GNUNET_PeerIdentity *pid, |
2568 | struct GNUNET_CRYPTO_EcdhePrivateKey *private_key, | 2634 | struct GNUNET_CRYPTO_EcdhePrivateKey *private_key, |
2569 | struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral_key, | 2635 | struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral_key, |
2570 | struct GNUNET_CRYPTO_EddsaSignature *ephemeral_sender_sig, | 2636 | struct GNUNET_CRYPTO_EddsaSignature *ephemeral_sender_sig, |
2571 | struct GNUNET_TIME_Absolute *ephemeral_validity) | 2637 | struct GNUNET_TIME_Absolute *ephemeral_validity) |
2572 | { | 2638 | { |
2573 | struct EphemeralCacheEntry *ece; | 2639 | struct EphemeralCacheEntry *ece; |
2574 | struct EphemeralConfirmation ec; | 2640 | struct EphemeralConfirmation ec; |
@@ -2643,7 +2709,7 @@ route_message (const struct GNUNET_PeerIdentity *target, | |||
2643 | */ | 2709 | */ |
2644 | static void | 2710 | static void |
2645 | handle_communicator_backchannel (void *cls, | 2711 | handle_communicator_backchannel (void *cls, |
2646 | const struct GNUNET_TRANSPORT_CommunicatorBackchannel *cb) | 2712 | const struct GNUNET_TRANSPORT_CommunicatorBackchannel *cb) |
2647 | { | 2713 | { |
2648 | struct TransportClient *tc = cls; | 2714 | struct TransportClient *tc = cls; |
2649 | struct GNUNET_CRYPTO_EcdhePrivateKey private_key; | 2715 | struct GNUNET_CRYPTO_EcdhePrivateKey private_key; |
@@ -2729,7 +2795,7 @@ store_pi (void *cls); | |||
2729 | */ | 2795 | */ |
2730 | static void | 2796 | static void |
2731 | peerstore_store_cb (void *cls, | 2797 | peerstore_store_cb (void *cls, |
2732 | int success) | 2798 | int success) |
2733 | { | 2799 | { |
2734 | struct AddressListEntry *ale = cls; | 2800 | struct AddressListEntry *ale = cls; |
2735 | 2801 | ||
@@ -3178,7 +3244,7 @@ handle_fragment_box (void *cls, | |||
3178 | if (65 == rc->num_acks) /* FIXME: maybe use smaller threshold? This is very aggressive. */ | 3244 | if (65 == rc->num_acks) /* FIXME: maybe use smaller threshold? This is very aggressive. */ |
3179 | ack_now = GNUNET_YES; /* maximum acks received */ | 3245 | ack_now = GNUNET_YES; /* maximum acks received */ |
3180 | // FIXME: possibly also ACK based on RTT (but for that we'd need to | 3246 | // FIXME: possibly also ACK based on RTT (but for that we'd need to |
3181 | // determine the session used for the ACK first!) | 3247 | // determine the queue used for the ACK first!) |
3182 | 3248 | ||
3183 | /* is reassembly complete? */ | 3249 | /* is reassembly complete? */ |
3184 | if (0 != rc->msg_missing) | 3250 | if (0 != rc->msg_missing) |
@@ -3289,7 +3355,7 @@ handle_reliability_box (void *cls, | |||
3289 | */ | 3355 | */ |
3290 | static void | 3356 | static void |
3291 | handle_reliability_ack (void *cls, | 3357 | handle_reliability_ack (void *cls, |
3292 | const struct TransportReliabilityAckMessage *ra) | 3358 | const struct TransportReliabilityAckMessage *ra) |
3293 | { | 3359 | { |
3294 | struct CommunicatorMessageContext *cmc = cls; | 3360 | struct CommunicatorMessageContext *cmc = cls; |
3295 | 3361 | ||
@@ -3308,7 +3374,7 @@ handle_reliability_ack (void *cls, | |||
3308 | */ | 3374 | */ |
3309 | static int | 3375 | static int |
3310 | check_backchannel_encapsulation (void *cls, | 3376 | check_backchannel_encapsulation (void *cls, |
3311 | const struct TransportBackchannelEncapsulationMessage *be) | 3377 | const struct TransportBackchannelEncapsulationMessage *be) |
3312 | { | 3378 | { |
3313 | uint16_t size = ntohs (be->header.size); | 3379 | uint16_t size = ntohs (be->header.size); |
3314 | 3380 | ||
@@ -3329,7 +3395,7 @@ check_backchannel_encapsulation (void *cls, | |||
3329 | */ | 3395 | */ |
3330 | static void | 3396 | static void |
3331 | handle_backchannel_encapsulation (void *cls, | 3397 | handle_backchannel_encapsulation (void *cls, |
3332 | const struct TransportBackchannelEncapsulationMessage *be) | 3398 | const struct TransportBackchannelEncapsulationMessage *be) |
3333 | { | 3399 | { |
3334 | struct CommunicatorMessageContext *cmc = cls; | 3400 | struct CommunicatorMessageContext *cmc = cls; |
3335 | 3401 | ||
@@ -3361,7 +3427,7 @@ handle_backchannel_encapsulation (void *cls, | |||
3361 | */ | 3427 | */ |
3362 | static int | 3428 | static int |
3363 | check_dv_learn (void *cls, | 3429 | check_dv_learn (void *cls, |
3364 | const struct TransportDVLearn *dvl) | 3430 | const struct TransportDVLearn *dvl) |
3365 | { | 3431 | { |
3366 | uint16_t size = ntohs (dvl->header.size); | 3432 | uint16_t size = ntohs (dvl->header.size); |
3367 | uint16_t num_hops = ntohs (dvl->num_hops); | 3433 | uint16_t num_hops = ntohs (dvl->num_hops); |
@@ -3375,15 +3441,15 @@ check_dv_learn (void *cls, | |||
3375 | for (unsigned int i=0;i<num_hops;i++) | 3441 | for (unsigned int i=0;i<num_hops;i++) |
3376 | { | 3442 | { |
3377 | if (0 == memcmp (&dvl->initiator, | 3443 | if (0 == memcmp (&dvl->initiator, |
3378 | &hops[i], | 3444 | &hops[i], |
3379 | sizeof (struct GNUNET_PeerIdentity))) | 3445 | sizeof (struct GNUNET_PeerIdentity))) |
3380 | { | 3446 | { |
3381 | GNUNET_break_op (0); | 3447 | GNUNET_break_op (0); |
3382 | return GNUNET_SYSERR; | 3448 | return GNUNET_SYSERR; |
3383 | } | 3449 | } |
3384 | if (0 == memcmp (&GST_my_identity, | 3450 | if (0 == memcmp (&GST_my_identity, |
3385 | &hops[i], | 3451 | &hops[i], |
3386 | sizeof (struct GNUNET_PeerIdentity))) | 3452 | sizeof (struct GNUNET_PeerIdentity))) |
3387 | { | 3453 | { |
3388 | GNUNET_break_op (0); | 3454 | GNUNET_break_op (0); |
3389 | return GNUNET_SYSERR; | 3455 | return GNUNET_SYSERR; |
@@ -3401,7 +3467,7 @@ check_dv_learn (void *cls, | |||
3401 | */ | 3467 | */ |
3402 | static void | 3468 | static void |
3403 | handle_dv_learn (void *cls, | 3469 | handle_dv_learn (void *cls, |
3404 | const struct TransportDVLearn *dvl) | 3470 | const struct TransportDVLearn *dvl) |
3405 | { | 3471 | { |
3406 | struct CommunicatorMessageContext *cmc = cls; | 3472 | struct CommunicatorMessageContext *cmc = cls; |
3407 | 3473 | ||
@@ -3420,7 +3486,7 @@ handle_dv_learn (void *cls, | |||
3420 | */ | 3486 | */ |
3421 | static int | 3487 | static int |
3422 | check_dv_box (void *cls, | 3488 | check_dv_box (void *cls, |
3423 | const struct TransportDVBox *dvb) | 3489 | const struct TransportDVBox *dvb) |
3424 | { | 3490 | { |
3425 | uint16_t size = ntohs (dvb->header.size); | 3491 | uint16_t size = ntohs (dvb->header.size); |
3426 | uint16_t num_hops = ntohs (dvb->num_hops); | 3492 | uint16_t num_hops = ntohs (dvb->num_hops); |
@@ -3614,12 +3680,12 @@ check_add_queue_message (void *cls, | |||
3614 | * Bandwidth tracker informs us that the delay until we should receive | 3680 | * Bandwidth tracker informs us that the delay until we should receive |
3615 | * more has changed. | 3681 | * more has changed. |
3616 | * | 3682 | * |
3617 | * @param cls a `struct GNUNET_ATS_Session` for which the delay changed | 3683 | * @param cls a `struct Queue` for which the delay changed |
3618 | */ | 3684 | */ |
3619 | static void | 3685 | static void |
3620 | tracker_update_in_cb (void *cls) | 3686 | tracker_update_in_cb (void *cls) |
3621 | { | 3687 | { |
3622 | struct GNUNET_ATS_Session *queue = cls; | 3688 | struct Queue *queue = cls; |
3623 | struct GNUNET_TIME_Relative in_delay; | 3689 | struct GNUNET_TIME_Relative in_delay; |
3624 | unsigned int rsize; | 3690 | unsigned int rsize; |
3625 | 3691 | ||
@@ -3816,12 +3882,12 @@ reliability_box_message (struct PendingMessage *pm) | |||
3816 | * communicator for transmission (updating the tracker, and re-scheduling | 3882 | * communicator for transmission (updating the tracker, and re-scheduling |
3817 | * itself if applicable). | 3883 | * itself if applicable). |
3818 | * | 3884 | * |
3819 | * @param cls the `struct GNUNET_ATS_Session` to process transmissions for | 3885 | * @param cls the `struct Queue` to process transmissions for |
3820 | */ | 3886 | */ |
3821 | static void | 3887 | static void |
3822 | transmit_on_queue (void *cls) | 3888 | transmit_on_queue (void *cls) |
3823 | { | 3889 | { |
3824 | struct GNUNET_ATS_Session *queue = cls; | 3890 | struct Queue *queue = cls; |
3825 | struct Neighbour *n = queue->neighbour; | 3891 | struct Neighbour *n = queue->neighbour; |
3826 | struct QueueEntry *qe; | 3892 | struct QueueEntry *qe; |
3827 | struct PendingMessage *pm; | 3893 | struct PendingMessage *pm; |
@@ -3871,7 +3937,7 @@ transmit_on_queue (void *cls) | |||
3871 | /* Pass 's' for transission to the communicator */ | 3937 | /* Pass 's' for transission to the communicator */ |
3872 | qe = GNUNET_new (struct QueueEntry); | 3938 | qe = GNUNET_new (struct QueueEntry); |
3873 | qe->mid = queue->mid_gen++; | 3939 | qe->mid = queue->mid_gen++; |
3874 | qe->session = queue; | 3940 | qe->queue = queue; |
3875 | // qe->pm = s; // FIXME: not so easy, reference management on 'free(s)'! | 3941 | // qe->pm = s; // FIXME: not so easy, reference management on 'free(s)'! |
3876 | GNUNET_CONTAINER_DLL_insert (queue->queue_head, | 3942 | GNUNET_CONTAINER_DLL_insert (queue->queue_head, |
3877 | queue->queue_tail, | 3943 | queue->queue_tail, |
@@ -4007,12 +4073,12 @@ transmit_on_queue (void *cls) | |||
4007 | * Bandwidth tracker informs us that the delay until we | 4073 | * Bandwidth tracker informs us that the delay until we |
4008 | * can transmit again changed. | 4074 | * can transmit again changed. |
4009 | * | 4075 | * |
4010 | * @param cls a `struct GNUNET_ATS_Session` for which the delay changed | 4076 | * @param cls a `struct Queue` for which the delay changed |
4011 | */ | 4077 | */ |
4012 | static void | 4078 | static void |
4013 | tracker_update_out_cb (void *cls) | 4079 | tracker_update_out_cb (void *cls) |
4014 | { | 4080 | { |
4015 | struct GNUNET_ATS_Session *queue = cls; | 4081 | struct Queue *queue = cls; |
4016 | struct Neighbour *n = queue->neighbour; | 4082 | struct Neighbour *n = queue->neighbour; |
4017 | 4083 | ||
4018 | if (NULL == n->pending_msg_head) | 4084 | if (NULL == n->pending_msg_head) |
@@ -4032,7 +4098,7 @@ tracker_update_out_cb (void *cls) | |||
4032 | * Bandwidth tracker informs us that excessive outbound bandwidth was | 4098 | * Bandwidth tracker informs us that excessive outbound bandwidth was |
4033 | * allocated which is not being used. | 4099 | * allocated which is not being used. |
4034 | * | 4100 | * |
4035 | * @param cls a `struct GNUNET_ATS_Session` for which the excess was noted | 4101 | * @param cls a `struct Queue` for which the excess was noted |
4036 | */ | 4102 | */ |
4037 | static void | 4103 | static void |
4038 | tracker_excess_out_cb (void *cls) | 4104 | tracker_excess_out_cb (void *cls) |
@@ -4041,7 +4107,7 @@ tracker_excess_out_cb (void *cls) | |||
4041 | this is done internally within transport_api2_core already, | 4107 | this is done internally within transport_api2_core already, |
4042 | but we probably want to change the logic and trigger it | 4108 | but we probably want to change the logic and trigger it |
4043 | from here via a message instead! */ | 4109 | from here via a message instead! */ |
4044 | /* TODO: maybe inform ATS at this point? */ | 4110 | /* TODO: maybe inform someone at this point? */ |
4045 | GNUNET_STATISTICS_update (GST_stats, | 4111 | GNUNET_STATISTICS_update (GST_stats, |
4046 | "# Excess outbound bandwidth reported", | 4112 | "# Excess outbound bandwidth reported", |
4047 | 1, | 4113 | 1, |
@@ -4054,12 +4120,12 @@ tracker_excess_out_cb (void *cls) | |||
4054 | * Bandwidth tracker informs us that excessive inbound bandwidth was allocated | 4120 | * Bandwidth tracker informs us that excessive inbound bandwidth was allocated |
4055 | * which is not being used. | 4121 | * which is not being used. |
4056 | * | 4122 | * |
4057 | * @param cls a `struct GNUNET_ATS_Session` for which the excess was noted | 4123 | * @param cls a `struct Queue` for which the excess was noted |
4058 | */ | 4124 | */ |
4059 | static void | 4125 | static void |
4060 | tracker_excess_in_cb (void *cls) | 4126 | tracker_excess_in_cb (void *cls) |
4061 | { | 4127 | { |
4062 | /* TODO: maybe inform ATS at this point? */ | 4128 | /* TODO: maybe inform somone at this point? */ |
4063 | GNUNET_STATISTICS_update (GST_stats, | 4129 | GNUNET_STATISTICS_update (GST_stats, |
4064 | "# Excess inbound bandwidth reported", | 4130 | "# Excess inbound bandwidth reported", |
4065 | 1, | 4131 | 1, |
@@ -4078,7 +4144,7 @@ handle_add_queue_message (void *cls, | |||
4078 | const struct GNUNET_TRANSPORT_AddQueueMessage *aqm) | 4144 | const struct GNUNET_TRANSPORT_AddQueueMessage *aqm) |
4079 | { | 4145 | { |
4080 | struct TransportClient *tc = cls; | 4146 | struct TransportClient *tc = cls; |
4081 | struct GNUNET_ATS_Session *queue; | 4147 | struct Queue *queue; |
4082 | struct Neighbour *neighbour; | 4148 | struct Neighbour *neighbour; |
4083 | const char *addr; | 4149 | const char *addr; |
4084 | uint16_t addr_len; | 4150 | uint16_t addr_len; |
@@ -4108,7 +4174,7 @@ handle_add_queue_message (void *cls, | |||
4108 | addr_len = ntohs (aqm->header.size) - sizeof (*aqm); | 4174 | addr_len = ntohs (aqm->header.size) - sizeof (*aqm); |
4109 | addr = (const char *) &aqm[1]; | 4175 | addr = (const char *) &aqm[1]; |
4110 | 4176 | ||
4111 | queue = GNUNET_malloc (sizeof (struct GNUNET_ATS_Session) + addr_len); | 4177 | queue = GNUNET_malloc (sizeof (struct Queue) + addr_len); |
4112 | queue->tc = tc; | 4178 | queue->tc = tc; |
4113 | queue->address = (const char *) &queue[1]; | 4179 | queue->address = (const char *) &queue[1]; |
4114 | queue->rtt = GNUNET_TIME_UNIT_FOREVER_REL; | 4180 | queue->rtt = GNUNET_TIME_UNIT_FOREVER_REL; |
@@ -4134,38 +4200,6 @@ handle_add_queue_message (void *cls, | |||
4134 | memcpy (&queue[1], | 4200 | memcpy (&queue[1], |
4135 | addr, | 4201 | addr, |
4136 | addr_len); | 4202 | addr_len); |
4137 | /* notify ATS about new queue */ | ||
4138 | { | ||
4139 | struct GNUNET_ATS_Properties prop = { | ||
4140 | .delay = GNUNET_TIME_UNIT_FOREVER_REL, | ||
4141 | .mtu = queue->mtu, | ||
4142 | .nt = queue->nt, | ||
4143 | .cc = tc->details.communicator.cc | ||
4144 | }; | ||
4145 | |||
4146 | queue->sr = GNUNET_ATS_session_add (ats, | ||
4147 | &neighbour->pid, | ||
4148 | queue->address, | ||
4149 | queue, | ||
4150 | &prop); | ||
4151 | if (NULL == queue->sr) | ||
4152 | { | ||
4153 | /* This can only happen if the 'address' was way too long for ATS | ||
4154 | (approaching 64k in strlen()!). In this case, the communicator | ||
4155 | must be buggy and we drop it. */ | ||
4156 | GNUNET_break (0); | ||
4157 | GNUNET_BANDWIDTH_tracker_notification_stop (&queue->tracker_in); | ||
4158 | GNUNET_BANDWIDTH_tracker_notification_stop (&queue->tracker_out); | ||
4159 | GNUNET_free (queue); | ||
4160 | if (NULL == neighbour->session_head) | ||
4161 | { | ||
4162 | cores_send_disconnect_info (&neighbour->pid); | ||
4163 | free_neighbour (neighbour); | ||
4164 | } | ||
4165 | GNUNET_SERVICE_client_drop (tc->client); | ||
4166 | return; | ||
4167 | } | ||
4168 | } | ||
4169 | /* notify monitors about new queue */ | 4203 | /* notify monitors about new queue */ |
4170 | { | 4204 | { |
4171 | struct MonitorEvent me = { | 4205 | struct MonitorEvent me = { |
@@ -4179,12 +4213,12 @@ handle_add_queue_message (void *cls, | |||
4179 | &me); | 4213 | &me); |
4180 | } | 4214 | } |
4181 | GNUNET_CONTAINER_MDLL_insert (neighbour, | 4215 | GNUNET_CONTAINER_MDLL_insert (neighbour, |
4182 | neighbour->session_head, | 4216 | neighbour->queue_head, |
4183 | neighbour->session_tail, | 4217 | neighbour->queue_tail, |
4184 | queue); | 4218 | queue); |
4185 | GNUNET_CONTAINER_MDLL_insert (client, | 4219 | GNUNET_CONTAINER_MDLL_insert (client, |
4186 | tc->details.communicator.session_head, | 4220 | tc->details.communicator.queue_head, |
4187 | tc->details.communicator.session_tail, | 4221 | tc->details.communicator.queue_tail, |
4188 | queue); | 4222 | queue); |
4189 | GNUNET_SERVICE_client_continue (tc->client); | 4223 | GNUNET_SERVICE_client_continue (tc->client); |
4190 | } | 4224 | } |
@@ -4208,18 +4242,18 @@ handle_del_queue_message (void *cls, | |||
4208 | GNUNET_SERVICE_client_drop (tc->client); | 4242 | GNUNET_SERVICE_client_drop (tc->client); |
4209 | return; | 4243 | return; |
4210 | } | 4244 | } |
4211 | for (struct GNUNET_ATS_Session *session = tc->details.communicator.session_head; | 4245 | for (struct Queue *queue = tc->details.communicator.queue_head; |
4212 | NULL != session; | 4246 | NULL != queue; |
4213 | session = session->next_client) | 4247 | queue = queue->next_client) |
4214 | { | 4248 | { |
4215 | struct Neighbour *neighbour = session->neighbour; | 4249 | struct Neighbour *neighbour = queue->neighbour; |
4216 | 4250 | ||
4217 | if ( (dqm->qid != session->qid) || | 4251 | if ( (dqm->qid != queue->qid) || |
4218 | (0 != memcmp (&dqm->receiver, | 4252 | (0 != memcmp (&dqm->receiver, |
4219 | &neighbour->pid, | 4253 | &neighbour->pid, |
4220 | sizeof (struct GNUNET_PeerIdentity))) ) | 4254 | sizeof (struct GNUNET_PeerIdentity))) ) |
4221 | continue; | 4255 | continue; |
4222 | free_session (session); | 4256 | free_queue (queue); |
4223 | GNUNET_SERVICE_client_continue (tc->client); | 4257 | GNUNET_SERVICE_client_continue (tc->client); |
4224 | return; | 4258 | return; |
4225 | } | 4259 | } |
@@ -4239,7 +4273,7 @@ handle_send_message_ack (void *cls, | |||
4239 | const struct GNUNET_TRANSPORT_SendMessageToAck *sma) | 4273 | const struct GNUNET_TRANSPORT_SendMessageToAck *sma) |
4240 | { | 4274 | { |
4241 | struct TransportClient *tc = cls; | 4275 | struct TransportClient *tc = cls; |
4242 | struct QueueEntry *queue; | 4276 | struct QueueEntry *qe; |
4243 | 4277 | ||
4244 | if (CT_COMMUNICATOR != tc->type) | 4278 | if (CT_COMMUNICATOR != tc->type) |
4245 | { | 4279 | { |
@@ -4249,37 +4283,37 @@ handle_send_message_ack (void *cls, | |||
4249 | } | 4283 | } |
4250 | 4284 | ||
4251 | /* find our queue entry matching the ACK */ | 4285 | /* find our queue entry matching the ACK */ |
4252 | queue = NULL; | 4286 | qe = NULL; |
4253 | for (struct GNUNET_ATS_Session *session = tc->details.communicator.session_head; | 4287 | for (struct Queue *queue = tc->details.communicator.queue_head; |
4254 | NULL != session; | 4288 | NULL != queue; |
4255 | session = session->next_client) | 4289 | queue = queue->next_client) |
4256 | { | 4290 | { |
4257 | if (0 != memcmp (&session->neighbour->pid, | 4291 | if (0 != memcmp (&queue->neighbour->pid, |
4258 | &sma->receiver, | 4292 | &sma->receiver, |
4259 | sizeof (struct GNUNET_PeerIdentity))) | 4293 | sizeof (struct GNUNET_PeerIdentity))) |
4260 | continue; | 4294 | continue; |
4261 | for (struct QueueEntry *qe = session->queue_head; | 4295 | for (struct QueueEntry *qep = queue->queue_head; |
4262 | NULL != qe; | 4296 | NULL != qep; |
4263 | qe = qe->next) | 4297 | qep = qep->next) |
4264 | { | 4298 | { |
4265 | if (qe->mid != sma->mid) | 4299 | if (qep->mid != sma->mid) |
4266 | continue; | 4300 | continue; |
4267 | queue = qe; | 4301 | qe = qep; |
4268 | break; | 4302 | break; |
4269 | } | 4303 | } |
4270 | break; | 4304 | break; |
4271 | } | 4305 | } |
4272 | if (NULL == queue) | 4306 | if (NULL == qe) |
4273 | { | 4307 | { |
4274 | /* this should never happen */ | 4308 | /* this should never happen */ |
4275 | GNUNET_break (0); | 4309 | GNUNET_break (0); |
4276 | GNUNET_SERVICE_client_drop (tc->client); | 4310 | GNUNET_SERVICE_client_drop (tc->client); |
4277 | return; | 4311 | return; |
4278 | } | 4312 | } |
4279 | GNUNET_CONTAINER_DLL_remove (queue->session->queue_head, | 4313 | GNUNET_CONTAINER_DLL_remove (qe->queue->queue_head, |
4280 | queue->session->queue_tail, | 4314 | qe->queue->queue_tail, |
4281 | queue); | 4315 | qe); |
4282 | queue->session->queue_length--; | 4316 | qe->queue->queue_length--; |
4283 | tc->details.communicator.total_queue_length--; | 4317 | tc->details.communicator.total_queue_length--; |
4284 | GNUNET_SERVICE_client_continue (tc->client); | 4318 | GNUNET_SERVICE_client_continue (tc->client); |
4285 | 4319 | ||
@@ -4291,19 +4325,19 @@ handle_send_message_ack (void *cls, | |||
4291 | "# Transmission throttled due to communicator queue limit", | 4325 | "# Transmission throttled due to communicator queue limit", |
4292 | -1, | 4326 | -1, |
4293 | GNUNET_NO); | 4327 | GNUNET_NO); |
4294 | for (struct GNUNET_ATS_Session *session = tc->details.communicator.session_head; | 4328 | for (struct Queue *queue = tc->details.communicator.queue_head; |
4295 | NULL != session; | 4329 | NULL != queue; |
4296 | session = session->next_client) | 4330 | queue = queue->next_client) |
4297 | schedule_transmit_on_queue (session); | 4331 | schedule_transmit_on_queue (queue); |
4298 | } | 4332 | } |
4299 | else if (SESSION_QUEUE_LIMIT - 1 == queue->session->queue_length) | 4333 | else if (QUEUE_LENGTH_LIMIT - 1 == qe->queue->queue_length) |
4300 | { | 4334 | { |
4301 | /* queue dropped below threshold; only resume this one queue */ | 4335 | /* queue dropped below threshold; only resume this one queue */ |
4302 | GNUNET_STATISTICS_update (GST_stats, | 4336 | GNUNET_STATISTICS_update (GST_stats, |
4303 | "# Transmission throttled due to session queue limit", | 4337 | "# Transmission throttled due to queue queue limit", |
4304 | -1, | 4338 | -1, |
4305 | GNUNET_NO); | 4339 | GNUNET_NO); |
4306 | schedule_transmit_on_queue (queue->session); | 4340 | schedule_transmit_on_queue (qe->queue); |
4307 | } | 4341 | } |
4308 | 4342 | ||
4309 | /* TODO: we also should react on the status! */ | 4343 | /* TODO: we also should react on the status! */ |
@@ -4311,7 +4345,7 @@ handle_send_message_ack (void *cls, | |||
4311 | // FIXME: react to communicator status about transmission request. We got: | 4345 | // FIXME: react to communicator status about transmission request. We got: |
4312 | sma->status; // OK success, SYSERR failure | 4346 | sma->status; // OK success, SYSERR failure |
4313 | 4347 | ||
4314 | GNUNET_free (queue); | 4348 | GNUNET_free (qe); |
4315 | } | 4349 | } |
4316 | 4350 | ||
4317 | 4351 | ||
@@ -4333,7 +4367,7 @@ notify_client_queues (void *cls, | |||
4333 | struct Neighbour *neighbour = value; | 4367 | struct Neighbour *neighbour = value; |
4334 | 4368 | ||
4335 | GNUNET_assert (CT_MONITOR == tc->type); | 4369 | GNUNET_assert (CT_MONITOR == tc->type); |
4336 | for (struct GNUNET_ATS_Session *q = neighbour->session_head; | 4370 | for (struct Queue *q = neighbour->queue_head; |
4337 | NULL != q; | 4371 | NULL != q; |
4338 | q = q->next_neighbour) | 4372 | q = q->next_neighbour) |
4339 | { | 4373 | { |
@@ -4384,31 +4418,6 @@ handle_monitor_start (void *cls, | |||
4384 | 4418 | ||
4385 | 4419 | ||
4386 | /** | 4420 | /** |
4387 | * Signature of a function called by ATS with the current bandwidth | ||
4388 | * allocation to be used as determined by ATS. | ||
4389 | * | ||
4390 | * @param cls closure, NULL | ||
4391 | * @param session session this is about | ||
4392 | * @param bandwidth_out assigned outbound bandwidth for the connection, | ||
4393 | * 0 to signal disconnect | ||
4394 | * @param bandwidth_in assigned inbound bandwidth for the connection, | ||
4395 | * 0 to signal disconnect | ||
4396 | */ | ||
4397 | static void | ||
4398 | ats_allocation_cb (void *cls, | ||
4399 | struct GNUNET_ATS_Session *session, | ||
4400 | struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, | ||
4401 | struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in) | ||
4402 | { | ||
4403 | (void) cls; | ||
4404 | GNUNET_BANDWIDTH_tracker_update_quota (&session->tracker_out, | ||
4405 | bandwidth_out); | ||
4406 | GNUNET_BANDWIDTH_tracker_update_quota (&session->tracker_in, | ||
4407 | bandwidth_in); | ||
4408 | } | ||
4409 | |||
4410 | |||
4411 | /** | ||
4412 | * Find transport client providing communication service | 4421 | * Find transport client providing communication service |
4413 | * for the protocol @a prefix. | 4422 | * for the protocol @a prefix. |
4414 | * | 4423 | * |
@@ -4429,24 +4438,22 @@ lookup_communicator (const char *prefix) | |||
4429 | return tc; | 4438 | return tc; |
4430 | } | 4439 | } |
4431 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 4440 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
4432 | "ATS suggested use of communicator for `%s', but we do not have such a communicator!\n", | 4441 | "Somone suggested use of communicator for `%s', but we do not have such a communicator!\n", |
4433 | prefix); | 4442 | prefix); |
4434 | return NULL; | 4443 | return NULL; |
4435 | } | 4444 | } |
4436 | 4445 | ||
4437 | 4446 | ||
4438 | /** | 4447 | /** |
4439 | * Signature of a function called by ATS suggesting transport to | 4448 | * Signature of a function called with a communicator @a address of a peer |
4440 | * try connecting with a particular address. | 4449 | * @a pid that an application wants us to connect to. |
4441 | * | 4450 | * |
4442 | * @param cls closure, NULL | ||
4443 | * @param pid target peer | 4451 | * @param pid target peer |
4444 | * @param address the address to try | 4452 | * @param address the address to try |
4445 | */ | 4453 | */ |
4446 | static void | 4454 | static void |
4447 | ats_suggestion_cb (void *cls, | 4455 | suggest_to_connect (const struct GNUNET_PeerIdentity *pid, |
4448 | const struct GNUNET_PeerIdentity *pid, | 4456 | const char *address) |
4449 | const char *address) | ||
4450 | { | 4457 | { |
4451 | static uint32_t idgen; | 4458 | static uint32_t idgen; |
4452 | struct TransportClient *tc; | 4459 | struct TransportClient *tc; |
@@ -4455,18 +4462,17 @@ ats_suggestion_cb (void *cls, | |||
4455 | struct GNUNET_MQ_Envelope *env; | 4462 | struct GNUNET_MQ_Envelope *env; |
4456 | size_t alen; | 4463 | size_t alen; |
4457 | 4464 | ||
4458 | (void) cls; | ||
4459 | prefix = GNUNET_HELLO_address_to_prefix (address); | 4465 | prefix = GNUNET_HELLO_address_to_prefix (address); |
4460 | if (NULL == prefix) | 4466 | if (NULL == prefix) |
4461 | { | 4467 | { |
4462 | GNUNET_break (0); /* ATS gave invalid address!? */ | 4468 | GNUNET_break (0); /* We got an invalid address!? */ |
4463 | return; | 4469 | return; |
4464 | } | 4470 | } |
4465 | tc = lookup_communicator (prefix); | 4471 | tc = lookup_communicator (prefix); |
4466 | if (NULL == tc) | 4472 | if (NULL == tc) |
4467 | { | 4473 | { |
4468 | GNUNET_STATISTICS_update (GST_stats, | 4474 | GNUNET_STATISTICS_update (GST_stats, |
4469 | "# ATS suggestions ignored due to missing communicator", | 4475 | "# Suggestions ignored due to missing communicator", |
4470 | 1, | 4476 | 1, |
4471 | GNUNET_NO); | 4477 | GNUNET_NO); |
4472 | return; | 4478 | return; |
@@ -4511,7 +4517,7 @@ handle_queue_create_ok (void *cls, | |||
4511 | return; | 4517 | return; |
4512 | } | 4518 | } |
4513 | GNUNET_STATISTICS_update (GST_stats, | 4519 | GNUNET_STATISTICS_update (GST_stats, |
4514 | "# ATS suggestions succeeded at communicator", | 4520 | "# Suggestions succeeded at communicator", |
4515 | 1, | 4521 | 1, |
4516 | GNUNET_NO); | 4522 | GNUNET_NO); |
4517 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 4523 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -4531,7 +4537,7 @@ handle_queue_create_ok (void *cls, | |||
4531 | */ | 4537 | */ |
4532 | static void | 4538 | static void |
4533 | handle_queue_create_fail (void *cls, | 4539 | handle_queue_create_fail (void *cls, |
4534 | const struct GNUNET_TRANSPORT_CreateQueueResponse *cqr) | 4540 | const struct GNUNET_TRANSPORT_CreateQueueResponse *cqr) |
4535 | { | 4541 | { |
4536 | struct TransportClient *tc = cls; | 4542 | struct TransportClient *tc = cls; |
4537 | 4543 | ||
@@ -4545,7 +4551,7 @@ handle_queue_create_fail (void *cls, | |||
4545 | "Request #%u for communicator to create queue failed\n", | 4551 | "Request #%u for communicator to create queue failed\n", |
4546 | (unsigned int) ntohs (cqr->request_id)); | 4552 | (unsigned int) ntohs (cqr->request_id)); |
4547 | GNUNET_STATISTICS_update (GST_stats, | 4553 | GNUNET_STATISTICS_update (GST_stats, |
4548 | "# ATS suggestions failed in queue creation at communicator", | 4554 | "# Suggestions failed in queue creation at communicator", |
4549 | 1, | 4555 | 1, |
4550 | GNUNET_NO); | 4556 | GNUNET_NO); |
4551 | GNUNET_SERVICE_client_continue (tc->client); | 4557 | GNUNET_SERVICE_client_continue (tc->client); |
@@ -4553,6 +4559,131 @@ handle_queue_create_fail (void *cls, | |||
4553 | 4559 | ||
4554 | 4560 | ||
4555 | /** | 4561 | /** |
4562 | * Function called by PEERSTORE for each matching record. | ||
4563 | * | ||
4564 | * @param cls closure | ||
4565 | * @param record peerstore record information | ||
4566 | * @param emsg error message, or NULL if no errors | ||
4567 | */ | ||
4568 | static void | ||
4569 | handle_hello (void *cls, | ||
4570 | const struct GNUNET_PEERSTORE_Record *record, | ||
4571 | const char *emsg) | ||
4572 | { | ||
4573 | struct PeerRequest *pr = cls; | ||
4574 | const char *val; | ||
4575 | |||
4576 | if (NULL != emsg) | ||
4577 | { | ||
4578 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
4579 | "Got failure from PEERSTORE: %s\n", | ||
4580 | emsg); | ||
4581 | return; | ||
4582 | } | ||
4583 | val = record->value; | ||
4584 | if ( (0 == record->value_size) || | ||
4585 | ('\0' != val[record->value_size - 1]) ) | ||
4586 | { | ||
4587 | GNUNET_break (0); | ||
4588 | return; | ||
4589 | } | ||
4590 | suggest_to_connect (&pr->pid, | ||
4591 | (const char *) record->value); | ||
4592 | } | ||
4593 | |||
4594 | |||
4595 | /** | ||
4596 | * We have received a `struct ExpressPreferenceMessage` from an application client. | ||
4597 | * | ||
4598 | * @param cls handle to the client | ||
4599 | * @param msg the start message | ||
4600 | */ | ||
4601 | static void | ||
4602 | handle_suggest (void *cls, | ||
4603 | const struct ExpressPreferenceMessage *msg) | ||
4604 | { | ||
4605 | struct TransportClient *tc = cls; | ||
4606 | struct PeerRequest *pr; | ||
4607 | |||
4608 | if (CT_NONE == tc->type) | ||
4609 | { | ||
4610 | tc->type = CT_APPLICATION; | ||
4611 | tc->details.application.requests | ||
4612 | = GNUNET_CONTAINER_multipeermap_create (16, | ||
4613 | GNUNET_YES); | ||
4614 | } | ||
4615 | if (CT_APPLICATION != tc->type) | ||
4616 | { | ||
4617 | GNUNET_break (0); | ||
4618 | GNUNET_SERVICE_client_drop (tc->client); | ||
4619 | return; | ||
4620 | } | ||
4621 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
4622 | "Client suggested we talk to %s with preference %d at rate %u\n", | ||
4623 | GNUNET_i2s (&msg->peer), | ||
4624 | (int) ntohl (msg->pk), | ||
4625 | (int) ntohl (msg->bw.value__)); | ||
4626 | pr = GNUNET_new (struct PeerRequest); | ||
4627 | pr->tc = tc; | ||
4628 | pr->pid = msg->peer; | ||
4629 | pr->bw = msg->bw; | ||
4630 | pr->pk = (enum GNUNET_MQ_PreferenceKind) ntohl (msg->pk); | ||
4631 | if (GNUNET_YES != | ||
4632 | GNUNET_CONTAINER_multipeermap_put (tc->details.application.requests, | ||
4633 | &pr->pid, | ||
4634 | pr, | ||
4635 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) | ||
4636 | { | ||
4637 | GNUNET_break (0); | ||
4638 | GNUNET_free (pr); | ||
4639 | GNUNET_SERVICE_client_drop (tc->client); | ||
4640 | return; | ||
4641 | } | ||
4642 | pr->wc = GNUNET_PEERSTORE_watch (peerstore, | ||
4643 | "transport", | ||
4644 | &pr->pid, | ||
4645 | "hello", | ||
4646 | &handle_hello, | ||
4647 | pr); | ||
4648 | GNUNET_SERVICE_client_continue (tc->client); | ||
4649 | } | ||
4650 | |||
4651 | |||
4652 | /** | ||
4653 | * We have received a `struct ExpressPreferenceMessage` from an application client. | ||
4654 | * | ||
4655 | * @param cls handle to the client | ||
4656 | * @param msg the start message | ||
4657 | */ | ||
4658 | static void | ||
4659 | handle_suggest_cancel (void *cls, | ||
4660 | const struct ExpressPreferenceMessage *msg) | ||
4661 | { | ||
4662 | struct TransportClient *tc = cls; | ||
4663 | struct PeerRequest *pr; | ||
4664 | |||
4665 | if (CT_APPLICATION != tc->type) | ||
4666 | { | ||
4667 | GNUNET_break (0); | ||
4668 | GNUNET_SERVICE_client_drop (tc->client); | ||
4669 | return; | ||
4670 | } | ||
4671 | pr = GNUNET_CONTAINER_multipeermap_get (tc->details.application.requests, | ||
4672 | &msg->peer); | ||
4673 | if (NULL == pr) | ||
4674 | { | ||
4675 | GNUNET_break (0); | ||
4676 | GNUNET_SERVICE_client_drop (tc->client); | ||
4677 | return; | ||
4678 | } | ||
4679 | (void) stop_peer_request (tc, | ||
4680 | &pr->pid, | ||
4681 | pr); | ||
4682 | GNUNET_SERVICE_client_continue (tc->client); | ||
4683 | } | ||
4684 | |||
4685 | |||
4686 | /** | ||
4556 | * Check #GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_CONSIDER_VERIFY | 4687 | * Check #GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_CONSIDER_VERIFY |
4557 | * messages. We do nothing here, real verification is done later. | 4688 | * messages. We do nothing here, real verification is done later. |
4558 | * | 4689 | * |
@@ -4692,13 +4823,8 @@ do_shutdown (void *cls) | |||
4692 | ephemeral_task = NULL; | 4823 | ephemeral_task = NULL; |
4693 | } | 4824 | } |
4694 | GNUNET_CONTAINER_multipeermap_iterate (neighbours, | 4825 | GNUNET_CONTAINER_multipeermap_iterate (neighbours, |
4695 | &free_neighbour_cb, | 4826 | &free_neighbour_cb, |
4696 | NULL); | 4827 | NULL); |
4697 | if (NULL != ats) | ||
4698 | { | ||
4699 | GNUNET_ATS_transport_done (ats); | ||
4700 | ats = NULL; | ||
4701 | } | ||
4702 | if (NULL != peerstore) | 4828 | if (NULL != peerstore) |
4703 | { | 4829 | { |
4704 | GNUNET_PEERSTORE_disconnect (peerstore, | 4830 | GNUNET_PEERSTORE_disconnect (peerstore, |
@@ -4779,17 +4905,6 @@ run (void *cls, | |||
4779 | GNUNET_SCHEDULER_shutdown (); | 4905 | GNUNET_SCHEDULER_shutdown (); |
4780 | return; | 4906 | return; |
4781 | } | 4907 | } |
4782 | ats = GNUNET_ATS_transport_init (GST_cfg, | ||
4783 | &ats_allocation_cb, | ||
4784 | NULL, | ||
4785 | &ats_suggestion_cb, | ||
4786 | NULL); | ||
4787 | if (NULL == ats) | ||
4788 | { | ||
4789 | GNUNET_break (0); | ||
4790 | GNUNET_SCHEDULER_shutdown (); | ||
4791 | return; | ||
4792 | } | ||
4793 | } | 4908 | } |
4794 | 4909 | ||
4795 | 4910 | ||
@@ -4803,6 +4918,15 @@ GNUNET_SERVICE_MAIN | |||
4803 | &client_connect_cb, | 4918 | &client_connect_cb, |
4804 | &client_disconnect_cb, | 4919 | &client_disconnect_cb, |
4805 | NULL, | 4920 | NULL, |
4921 | /* communication with applications */ | ||
4922 | GNUNET_MQ_hd_fixed_size (suggest, | ||
4923 | GNUNET_MESSAGE_TYPE_TRANSPORT_SUGGEST, | ||
4924 | struct ExpressPreferenceMessage, | ||
4925 | NULL), | ||
4926 | GNUNET_MQ_hd_fixed_size (suggest_cancel, | ||
4927 | GNUNET_MESSAGE_TYPE_TRANSPORT_SUGGEST_CANCEL, | ||
4928 | struct ExpressPreferenceMessage, | ||
4929 | NULL), | ||
4806 | /* communication with core */ | 4930 | /* communication with core */ |
4807 | GNUNET_MQ_hd_fixed_size (client_start, | 4931 | GNUNET_MQ_hd_fixed_size (client_start, |
4808 | GNUNET_MESSAGE_TYPE_TRANSPORT_START, | 4932 | GNUNET_MESSAGE_TYPE_TRANSPORT_START, |
diff --git a/src/transport/transport.h b/src/transport/transport.h index c0e02c3d9..b231ea8ae 100644 --- a/src/transport/transport.h +++ b/src/transport/transport.h | |||
@@ -1107,6 +1107,38 @@ struct GNUNET_TRANSPORT_AddressToVerify | |||
1107 | }; | 1107 | }; |
1108 | 1108 | ||
1109 | 1109 | ||
1110 | /** | ||
1111 | * Application client to TRANSPORT service: we would like to have | ||
1112 | * address suggestions for this peer. | ||
1113 | */ | ||
1114 | struct ExpressPreferenceMessage | ||
1115 | { | ||
1116 | /** | ||
1117 | * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_SUGGEST or | ||
1118 | * #GNUNET_MESSAGE_TYPE_TRANSPORT_SUGGEST_CANCEL to stop | ||
1119 | * suggestions. | ||
1120 | */ | ||
1121 | struct GNUNET_MessageHeader header; | ||
1122 | |||
1123 | /** | ||
1124 | * What type of performance preference does the client have? | ||
1125 | * A `enum GNUNET_MQ_PreferenceKind` in NBO. | ||
1126 | */ | ||
1127 | uint32_t pk GNUNET_PACKED; | ||
1128 | |||
1129 | /** | ||
1130 | * Peer to get address suggestions for. | ||
1131 | */ | ||
1132 | struct GNUNET_PeerIdentity peer; | ||
1133 | |||
1134 | /** | ||
1135 | * How much bandwidth in bytes/second does the application expect? | ||
1136 | */ | ||
1137 | struct GNUNET_BANDWIDTH_Value32NBO bw; | ||
1138 | |||
1139 | }; | ||
1140 | |||
1141 | |||
1110 | #endif | 1142 | #endif |
1111 | 1143 | ||
1112 | GNUNET_NETWORK_STRUCT_END | 1144 | GNUNET_NETWORK_STRUCT_END |
diff --git a/src/transport/transport_api2_application.c b/src/transport/transport_api2_application.c new file mode 100644 index 000000000..325438e11 --- /dev/null +++ b/src/transport/transport_api2_application.c | |||
@@ -0,0 +1,366 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2010--2019 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | /** | ||
21 | * @file transport/transport_api2_application.c | ||
22 | * @brief enable clients to ask TRANSPORT about establishing connections to peers | ||
23 | * @author Christian Grothoff | ||
24 | * @author Matthias Wachs | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_transport_application_service.h" | ||
28 | #include "gnunet_transport_core_service.h" | ||
29 | #include "transport.h" | ||
30 | |||
31 | |||
32 | #define LOG(kind,...) GNUNET_log_from(kind, "transport-application-api", __VA_ARGS__) | ||
33 | |||
34 | |||
35 | /** | ||
36 | * Handle for TRANSPORT address suggestion requests. | ||
37 | */ | ||
38 | struct GNUNET_TRANSPORT_ApplicationSuggestHandle | ||
39 | { | ||
40 | /** | ||
41 | * ID of the peer for which address suggestion was requested. | ||
42 | */ | ||
43 | struct GNUNET_PeerIdentity id; | ||
44 | |||
45 | /** | ||
46 | * Connecitivity handle this suggestion handle belongs to. | ||
47 | */ | ||
48 | struct GNUNET_TRANSPORT_ApplicationHandle *ch; | ||
49 | |||
50 | /** | ||
51 | * What preference is being expressed? | ||
52 | */ | ||
53 | enum GNUNET_MQ_PreferenceKind pk; | ||
54 | |||
55 | /** | ||
56 | * How much bandwidth does the client expect? | ||
57 | */ | ||
58 | struct GNUNET_BANDWIDTH_Value32NBO bw; | ||
59 | }; | ||
60 | |||
61 | |||
62 | /** | ||
63 | * Handle to the TRANSPORT subsystem for application management. | ||
64 | */ | ||
65 | struct GNUNET_TRANSPORT_ApplicationHandle | ||
66 | { | ||
67 | |||
68 | /** | ||
69 | * Our configuration. | ||
70 | */ | ||
71 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
72 | |||
73 | /** | ||
74 | * Map with the identities of all the peers for which we would | ||
75 | * like to have address suggestions. The key is the PID, the | ||
76 | * value is currently the `struct GNUNET_TRANSPORT_ApplicationSuggestHandle` | ||
77 | */ | ||
78 | struct GNUNET_CONTAINER_MultiPeerMap *sug_requests; | ||
79 | |||
80 | /** | ||
81 | * Message queue for sending requests to the TRANSPORT service. | ||
82 | */ | ||
83 | struct GNUNET_MQ_Handle *mq; | ||
84 | |||
85 | /** | ||
86 | * Task to trigger reconnect. | ||
87 | */ | ||
88 | struct GNUNET_SCHEDULER_Task *task; | ||
89 | |||
90 | /** | ||
91 | * Reconnect backoff delay. | ||
92 | */ | ||
93 | struct GNUNET_TIME_Relative backoff; | ||
94 | }; | ||
95 | |||
96 | |||
97 | /** | ||
98 | * Re-establish the connection to the TRANSPORT service. | ||
99 | * | ||
100 | * @param ch handle to use to re-connect. | ||
101 | */ | ||
102 | static void | ||
103 | reconnect (struct GNUNET_TRANSPORT_ApplicationHandle *ch); | ||
104 | |||
105 | |||
106 | /** | ||
107 | * Re-establish the connection to the TRANSPORT service. | ||
108 | * | ||
109 | * @param cls handle to use to re-connect. | ||
110 | */ | ||
111 | static void | ||
112 | reconnect_task (void *cls) | ||
113 | { | ||
114 | struct GNUNET_TRANSPORT_ApplicationHandle *ch = cls; | ||
115 | |||
116 | ch->task = NULL; | ||
117 | reconnect (ch); | ||
118 | } | ||
119 | |||
120 | |||
121 | /** | ||
122 | * Disconnect from TRANSPORT and then reconnect. | ||
123 | * | ||
124 | * @param ch our handle | ||
125 | */ | ||
126 | static void | ||
127 | force_reconnect (struct GNUNET_TRANSPORT_ApplicationHandle *ch) | ||
128 | { | ||
129 | if (NULL != ch->mq) | ||
130 | { | ||
131 | GNUNET_MQ_destroy (ch->mq); | ||
132 | ch->mq = NULL; | ||
133 | } | ||
134 | ch->backoff = GNUNET_TIME_STD_BACKOFF (ch->backoff); | ||
135 | ch->task = GNUNET_SCHEDULER_add_delayed (ch->backoff, | ||
136 | &reconnect_task, | ||
137 | ch); | ||
138 | } | ||
139 | |||
140 | |||
141 | /** | ||
142 | * We encountered an error handling the MQ to the | ||
143 | * TRANSPORT service. Reconnect. | ||
144 | * | ||
145 | * @param cls the `struct GNUNET_TRANSPORT_ApplicationHandle` | ||
146 | * @param error details about the error | ||
147 | */ | ||
148 | static void | ||
149 | error_handler (void *cls, | ||
150 | enum GNUNET_MQ_Error error) | ||
151 | { | ||
152 | struct GNUNET_TRANSPORT_ApplicationHandle *ch = cls; | ||
153 | |||
154 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
155 | "TRANSPORT connection died (code %d), reconnecting\n", | ||
156 | (int) error); | ||
157 | force_reconnect (ch); | ||
158 | } | ||
159 | |||
160 | |||
161 | /** | ||
162 | * Transmit request for an address suggestion. | ||
163 | * | ||
164 | * @param cls the `struct GNUNET_TRANSPORT_ApplicationHandle` | ||
165 | * @param peer peer to ask for an address suggestion for | ||
166 | * @param value the `struct GNUNET_TRANSPORT_SuggestHandle` | ||
167 | * @return #GNUNET_OK (continue to iterate), #GNUNET_SYSERR on | ||
168 | * failure (message queue no longer exists) | ||
169 | */ | ||
170 | static int | ||
171 | transmit_suggestion (void *cls, | ||
172 | const struct GNUNET_PeerIdentity *peer, | ||
173 | void *value) | ||
174 | { | ||
175 | struct GNUNET_TRANSPORT_ApplicationHandle *ch = cls; | ||
176 | struct GNUNET_TRANSPORT_ApplicationSuggestHandle *sh = value; | ||
177 | struct GNUNET_MQ_Envelope *ev; | ||
178 | struct ExpressPreferenceMessage *m; | ||
179 | |||
180 | if (NULL == ch->mq) | ||
181 | return GNUNET_SYSERR; | ||
182 | ev = GNUNET_MQ_msg (m, | ||
183 | GNUNET_MESSAGE_TYPE_TRANSPORT_SUGGEST); | ||
184 | m->pk = htonl ((uint32_t) sh->pk); | ||
185 | m->bw = sh->bw; | ||
186 | m->peer = *peer; | ||
187 | GNUNET_MQ_send (ch->mq, ev); | ||
188 | return GNUNET_OK; | ||
189 | } | ||
190 | |||
191 | |||
192 | /** | ||
193 | * Re-establish the connection to the TRANSPORT service. | ||
194 | * | ||
195 | * @param ch handle to use to re-connect. | ||
196 | */ | ||
197 | static void | ||
198 | reconnect (struct GNUNET_TRANSPORT_ApplicationHandle *ch) | ||
199 | { | ||
200 | static const struct GNUNET_MQ_MessageHandler handlers[] = { | ||
201 | { NULL, 0, 0 } | ||
202 | }; | ||
203 | |||
204 | GNUNET_assert (NULL == ch->mq); | ||
205 | ch->mq = GNUNET_CLIENT_connect (ch->cfg, | ||
206 | "transport", | ||
207 | handlers, | ||
208 | &error_handler, | ||
209 | ch); | ||
210 | if (NULL == ch->mq) | ||
211 | { | ||
212 | force_reconnect (ch); | ||
213 | return; | ||
214 | } | ||
215 | GNUNET_CONTAINER_multipeermap_iterate (ch->sug_requests, | ||
216 | &transmit_suggestion, | ||
217 | ch); | ||
218 | } | ||
219 | |||
220 | |||
221 | /** | ||
222 | * Initialize the TRANSPORT application suggestion client handle. | ||
223 | * | ||
224 | * @param cfg configuration to use | ||
225 | * @return transport application handle, NULL on error | ||
226 | */ | ||
227 | struct GNUNET_TRANSPORT_ApplicationHandle * | ||
228 | GNUNET_TRANSPORT_application_init (const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
229 | { | ||
230 | struct GNUNET_TRANSPORT_ApplicationHandle *ch; | ||
231 | |||
232 | ch = GNUNET_new (struct GNUNET_TRANSPORT_ApplicationHandle); | ||
233 | ch->cfg = cfg; | ||
234 | ch->sug_requests = GNUNET_CONTAINER_multipeermap_create (32, | ||
235 | GNUNET_YES); | ||
236 | reconnect (ch); | ||
237 | return ch; | ||
238 | } | ||
239 | |||
240 | |||
241 | /** | ||
242 | * Function called to free all `struct GNUNET_TRANSPORT_ApplicationSuggestHandle`s | ||
243 | * in the map. | ||
244 | * | ||
245 | * @param cls NULL | ||
246 | * @param key the key | ||
247 | * @param value the value to free | ||
248 | * @return #GNUNET_OK (continue to iterate) | ||
249 | */ | ||
250 | static int | ||
251 | free_sug_handle (void *cls, | ||
252 | const struct GNUNET_PeerIdentity *key, | ||
253 | void *value) | ||
254 | { | ||
255 | struct GNUNET_TRANSPORT_ApplicationSuggestHandle *cur = value; | ||
256 | |||
257 | GNUNET_free (cur); | ||
258 | return GNUNET_OK; | ||
259 | } | ||
260 | |||
261 | |||
262 | /** | ||
263 | * Client is done with TRANSPORT application management, release resources. | ||
264 | * | ||
265 | * @param ch handle to release | ||
266 | */ | ||
267 | void | ||
268 | GNUNET_TRANSPORT_application_done (struct GNUNET_TRANSPORT_ApplicationHandle *ch) | ||
269 | { | ||
270 | if (NULL != ch->mq) | ||
271 | { | ||
272 | GNUNET_MQ_destroy (ch->mq); | ||
273 | ch->mq = NULL; | ||
274 | } | ||
275 | if (NULL != ch->task) | ||
276 | { | ||
277 | GNUNET_SCHEDULER_cancel (ch->task); | ||
278 | ch->task = NULL; | ||
279 | } | ||
280 | GNUNET_CONTAINER_multipeermap_iterate (ch->sug_requests, | ||
281 | &free_sug_handle, | ||
282 | NULL); | ||
283 | GNUNET_CONTAINER_multipeermap_destroy (ch->sug_requests); | ||
284 | GNUNET_free (ch); | ||
285 | } | ||
286 | |||
287 | |||
288 | /** | ||
289 | * We would like to receive address suggestions for a peer. TRANSPORT will | ||
290 | * respond with a call to the continuation immediately containing an address or | ||
291 | * no address if none is available. TRANSPORT can suggest more addresses until we call | ||
292 | * #GNUNET_TRANSPORT_application_suggest_cancel(). | ||
293 | * | ||
294 | * @param ch handle | ||
295 | * @param peer identity of the peer we need an address for | ||
296 | * @param pk what kind of application will the application require (can be | ||
297 | * #GNUNET_MQ_PREFERENCE_NONE, we will still try to connect) | ||
298 | * @param bw desired bandwith, can be zero (we will still try to connect) | ||
299 | * @return suggest handle, NULL if a request is already pending | ||
300 | */ | ||
301 | struct GNUNET_TRANSPORT_ApplicationSuggestHandle * | ||
302 | GNUNET_TRANSPORT_application_suggest (struct GNUNET_TRANSPORT_ApplicationHandle *ch, | ||
303 | const struct GNUNET_PeerIdentity *peer, | ||
304 | enum GNUNET_MQ_PreferenceKind pk, | ||
305 | struct GNUNET_BANDWIDTH_Value32NBO bw) | ||
306 | { | ||
307 | struct GNUNET_TRANSPORT_ApplicationSuggestHandle *s; | ||
308 | |||
309 | s = GNUNET_new (struct GNUNET_TRANSPORT_ApplicationSuggestHandle); | ||
310 | s->ch = ch; | ||
311 | s->id = *peer; | ||
312 | s->pk = pk; | ||
313 | s->bw = bw; | ||
314 | (void) GNUNET_CONTAINER_multipeermap_put (ch->sug_requests, | ||
315 | &s->id, | ||
316 | s, | ||
317 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | ||
318 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
319 | "Requesting TRANSPORT to suggest address for `%s'\n", | ||
320 | GNUNET_i2s (peer)); | ||
321 | if (NULL == ch->mq) | ||
322 | return s; | ||
323 | GNUNET_assert (GNUNET_OK == | ||
324 | transmit_suggestion (ch, | ||
325 | &s->id, | ||
326 | s)); | ||
327 | return s; | ||
328 | } | ||
329 | |||
330 | |||
331 | /** | ||
332 | * We no longer care about being connected to a peer. | ||
333 | * | ||
334 | * @param sh handle to stop | ||
335 | */ | ||
336 | void | ||
337 | GNUNET_TRANSPORT_application_suggest_cancel (struct GNUNET_TRANSPORT_ApplicationSuggestHandle *sh) | ||
338 | { | ||
339 | struct GNUNET_TRANSPORT_ApplicationHandle *ch = sh->ch; | ||
340 | struct GNUNET_MQ_Envelope *ev; | ||
341 | struct ExpressPreferenceMessage *m; | ||
342 | |||
343 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
344 | "Telling TRANSPORT we no longer care for an address for `%s'\n", | ||
345 | GNUNET_i2s (&sh->id)); | ||
346 | GNUNET_assert (GNUNET_OK == | ||
347 | GNUNET_CONTAINER_multipeermap_remove (ch->sug_requests, | ||
348 | &sh->id, | ||
349 | sh)); | ||
350 | if (NULL == ch->mq) | ||
351 | { | ||
352 | GNUNET_free (sh); | ||
353 | return; | ||
354 | } | ||
355 | ev = GNUNET_MQ_msg (m, | ||
356 | GNUNET_MESSAGE_TYPE_TRANSPORT_SUGGEST_CANCEL); | ||
357 | m->pk = htonl ((uint32_t) sh->pk); | ||
358 | m->bw = sh->bw; | ||
359 | m->peer = sh->id; | ||
360 | GNUNET_MQ_send (ch->mq, | ||
361 | ev); | ||
362 | GNUNET_free (sh); | ||
363 | } | ||
364 | |||
365 | |||
366 | /* end of transport_api2_application.c */ | ||