diff options
author | Christian Grothoff <christian@grothoff.org> | 2018-12-16 17:13:42 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2018-12-16 17:13:42 +0100 |
commit | d37218d0b13292b78fcfc08d2903d6e415da0236 (patch) | |
tree | f9f354e6859b9868859cf421acbf747d8351ee7b /src/transport/gnunet-service-tng.c | |
parent | 18784b77764c56842ae59428f3ebea95c157ffab (diff) | |
download | gnunet-d37218d0b13292b78fcfc08d2903d6e415da0236.tar.gz gnunet-d37218d0b13292b78fcfc08d2903d6e415da0236.zip |
more work on tng
Diffstat (limited to 'src/transport/gnunet-service-tng.c')
-rw-r--r-- | src/transport/gnunet-service-tng.c | 512 |
1 files changed, 453 insertions, 59 deletions
diff --git a/src/transport/gnunet-service-tng.c b/src/transport/gnunet-service-tng.c index 3630e6af0..85ac3da83 100644 --- a/src/transport/gnunet-service-tng.c +++ b/src/transport/gnunet-service-tng.c | |||
@@ -16,32 +16,70 @@ | |||
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 | */ |
18 | /** | 18 | /** |
19 | * @file transport/gnunet-service-transport.c | 19 | * @file transport/gnunet-service-tng.c |
20 | * @brief main for gnunet-service-transport | 20 | * @brief main for gnunet-service-tng |
21 | * @author Christian Grothoff | 21 | * @author Christian Grothoff |
22 | * | 22 | * |
23 | * TODO: | 23 | * TODO: |
24 | * - design ATS-NG API | ||
25 | * - figure out how to transmit (selective) ACKs in case of uni-directional | 24 | * - figure out how to transmit (selective) ACKs in case of uni-directional |
26 | * communicators (with/without core? DV-only?) When do we use ACKs? | 25 | * communicators (with/without core? DV-only?) When do we use ACKs? |
27 | * How/where do we distinguish between TCP/HTTP and unreliable communicators? | 26 | * => communicators use selective ACKs for flow control |
28 | * => Should communicator provide reliable/unreliable ("flags") information? | 27 | * => transport uses message-level ACKs for RTT, fragment confirmation |
28 | * => integrate DV into transport, use neither core nor communicators | ||
29 | * but rather give communicators transport-encapsulated messages | ||
30 | * (which could be core-data, background-channel traffic, or | ||
31 | * transport-to-transport traffic) | ||
32 | * | ||
33 | * Implement: | ||
29 | * - manage fragmentation/defragmentation, retransmission, track RTT, loss, etc. | 34 | * - manage fragmentation/defragmentation, retransmission, track RTT, loss, etc. |
35 | * | ||
36 | * Easy: | ||
37 | * - use ATS bandwidth allocation callback and schedule transmissions! | ||
38 | * | ||
39 | * Plan: | ||
30 | * - inform ATS about RTT, goodput/loss, overheads, etc. | 40 | * - inform ATS about RTT, goodput/loss, overheads, etc. |
31 | * - ask ATS about bandwidth allocation! | 41 | * |
42 | * Later: | ||
32 | * - change transport-core API to provide proper flow control in both | 43 | * - change transport-core API to provide proper flow control in both |
33 | * directions, allow multiple messages per peer simultaneously (tag | 44 | * directions, allow multiple messages per peer simultaneously (tag |
34 | * confirmations with unique message ID), and replace quota-out with | 45 | * confirmations with unique message ID), and replace quota-out with |
35 | * proper flow control; | 46 | * proper flow control; |
47 | * | ||
48 | * Design realizations / discussion: | ||
49 | * - communicators do flow control by calling MQ "notify sent" | ||
50 | * when 'ready'. They determine flow implicitly (i.e. TCP blocking) | ||
51 | * or explicitly via background channel FC ACKs. As long as the | ||
52 | * channel is not full, they may 'notify sent' even if the other | ||
53 | * peer has not yet confirmed receipt. The other peer confirming | ||
54 | * is _only_ for FC, not for more reliable transmission; reliable | ||
55 | * transmission (i.e. of fragments) is left to _transport_. | ||
56 | * - ACKs sent back in uni-directional communicators are done via | ||
57 | * the background channel API; here transport _may_ initially | ||
58 | * broadcast (with bounded # hops) if no path is known; | ||
59 | * - transport should _integrate_ DV-routing and build a view of | ||
60 | * the network; then background channel traffic can be | ||
61 | * routed via DV as well as explicit "DV" traffic. | ||
62 | * - background channel is also used for ACKs and NAT traversal support | ||
63 | * - transport service is responsible for AEAD'ing the background | ||
64 | * channel, timestamps and monotonic time are used against replay | ||
65 | * of old messages -> peerstore needs to be supplied with | ||
66 | * "latest timestamps seen" data | ||
67 | * - if transport implements DV, we likely need a 3rd peermap | ||
68 | * in addition to ephemerals and (direct) neighbours | ||
69 | * => in this data structure, we should track ATS metrics (distance, RTT, etc.) | ||
70 | * as well as latest timestamps seen, goodput, fragments for transmission, etc. | ||
71 | * ==> check if stuff needs to be moved out of "Neighbour" | ||
72 | * - transport should encapsualte core-level messages and do its | ||
73 | * own ACKing for RTT/goodput/loss measurements _and_ fragment | ||
74 | * for retransmission | ||
36 | */ | 75 | */ |
37 | #include "platform.h" | 76 | #include "platform.h" |
38 | #include "gnunet_util_lib.h" | 77 | #include "gnunet_util_lib.h" |
39 | #include "gnunet_statistics_service.h" | 78 | #include "gnunet_statistics_service.h" |
40 | #include "gnunet_transport_service.h" | ||
41 | #include "gnunet_transport_monitor_service.h" | 79 | #include "gnunet_transport_monitor_service.h" |
42 | #include "gnunet_peerstore_service.h" | 80 | #include "gnunet_peerstore_service.h" |
43 | #include "gnunet_ats_service.h" | 81 | #include "gnunet_hello_lib.h" |
44 | #include "gnunet-service-transport.h" | 82 | #include "gnunet_ats_transport_service.h" |
45 | #include "transport.h" | 83 | #include "transport.h" |
46 | 84 | ||
47 | 85 | ||
@@ -60,6 +98,122 @@ | |||
60 | #define MAX_PENDING (128 * 1024) | 98 | #define MAX_PENDING (128 * 1024) |
61 | 99 | ||
62 | 100 | ||
101 | GNUNET_NETWORK_STRUCT_BEGIN | ||
102 | |||
103 | /** | ||
104 | * Outer layer of an encapsulated backchannel message. | ||
105 | */ | ||
106 | struct TransportBackchannelEncapsulationMessage | ||
107 | { | ||
108 | /** | ||
109 | * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_BACKCHANNEL_ENCAPSULATION. | ||
110 | */ | ||
111 | struct GNUNET_MessageHeader header; | ||
112 | |||
113 | /** | ||
114 | * Distance the backchannel message has traveled, to be updated at | ||
115 | * each hop. Used to bound the number of hops in case a backchannel | ||
116 | * message is broadcast and thus travels without routing | ||
117 | * information (during initial backchannel discovery). | ||
118 | */ | ||
119 | uint32_t distance; | ||
120 | |||
121 | /** | ||
122 | * Target's peer identity (as backchannels may be transmitted | ||
123 | * indirectly, or even be broadcast). | ||
124 | */ | ||
125 | struct GNUNET_PeerIdentity target; | ||
126 | |||
127 | /** | ||
128 | * Ephemeral key setup by the sender for @e target, used | ||
129 | * to encrypt the payload. | ||
130 | */ | ||
131 | struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key; | ||
132 | |||
133 | /** | ||
134 | * HMAC over the ciphertext of the encrypted, variable-size | ||
135 | * body that follows. Verified via DH of @e target and | ||
136 | * @e ephemeral_key | ||
137 | */ | ||
138 | struct GNUNET_HashCode hmac; | ||
139 | |||
140 | /* Followed by encrypted, variable-size payload */ | ||
141 | }; | ||
142 | |||
143 | |||
144 | /** | ||
145 | * Message by which a peer confirms that it is using an | ||
146 | * ephemeral key. | ||
147 | */ | ||
148 | struct EphemeralConfirmation | ||
149 | { | ||
150 | |||
151 | /** | ||
152 | * Purpose is #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_EPHEMERAL | ||
153 | */ | ||
154 | struct GNUNET_CRYPTO_EccSignaturePurpose purpose; | ||
155 | |||
156 | /** | ||
157 | * How long is this signature over the ephemeral key | ||
158 | * valid? | ||
159 | */ | ||
160 | struct GNUNET_TIME_AbsoluteNBO ephemeral_validity; | ||
161 | |||
162 | /** | ||
163 | * Ephemeral key setup by the sender for @e target, used | ||
164 | * to encrypt the payload. | ||
165 | */ | ||
166 | struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key; | ||
167 | |||
168 | }; | ||
169 | |||
170 | /** | ||
171 | * Plaintext of the variable-size payload that is encrypted | ||
172 | * within a `struct TransportBackchannelEncapsulationMessage` | ||
173 | */ | ||
174 | struct TransportBackchannelRequestPayload | ||
175 | { | ||
176 | |||
177 | /** | ||
178 | * Sender's peer identity. | ||
179 | */ | ||
180 | struct GNUNET_PeerIdentity sender; | ||
181 | |||
182 | /** | ||
183 | * Signature of the sender over an | ||
184 | * #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_EPHEMERAL. | ||
185 | */ | ||
186 | struct GNUNET_CRYPTO_EddsaSignature sender_sig; | ||
187 | |||
188 | /** | ||
189 | * How long is this signature over the ephemeral key | ||
190 | * valid? | ||
191 | */ | ||
192 | struct GNUNET_TIME_AbsoluteNBO ephemeral_validity; | ||
193 | |||
194 | /** | ||
195 | * Current monotonic time of the sending transport service. Used to | ||
196 | * detect replayed messages. Note that the receiver should remember | ||
197 | * a list of the recently seen timestamps and only reject messages | ||
198 | * if the timestamp is in the list, or the list is "full" and the | ||
199 | * timestamp is smaller than the lowest in the list. This list of | ||
200 | * timestamps per peer should be persisted to guard against replays | ||
201 | * after restarts. | ||
202 | */ | ||
203 | struct GNUNET_TIME_AbsoluteNBO monotonic_time; | ||
204 | |||
205 | /* Followed by a `struct GNUNET_MessageHeader` with a message | ||
206 | for a communicator */ | ||
207 | |||
208 | /* Followed by a 0-termianted string specifying the name of | ||
209 | the communicator which is to receive the message */ | ||
210 | |||
211 | }; | ||
212 | |||
213 | GNUNET_NETWORK_STRUCT_END | ||
214 | |||
215 | |||
216 | |||
63 | /** | 217 | /** |
64 | * What type of client is the `struct TransportClient` about? | 218 | * What type of client is the `struct TransportClient` about? |
65 | */ | 219 | */ |
@@ -88,6 +242,42 @@ enum ClientType | |||
88 | 242 | ||
89 | 243 | ||
90 | /** | 244 | /** |
245 | * Entry in our cache of ephemeral keys we currently use. | ||
246 | */ | ||
247 | struct EphemeralCacheEntry | ||
248 | { | ||
249 | |||
250 | /** | ||
251 | * Target's peer identity (we don't re-use ephemerals | ||
252 | * to limit linkability of messages). | ||
253 | */ | ||
254 | struct GNUNET_PeerIdentity target; | ||
255 | |||
256 | /** | ||
257 | * Signature affirming @e ephemeral_key of type | ||
258 | * #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_EPHEMERAL | ||
259 | */ | ||
260 | struct GNUNET_CRYPTO_EddsaSignature sender_sig; | ||
261 | |||
262 | /** | ||
263 | * How long is @e sender_sig valid | ||
264 | */ | ||
265 | struct GNUNET_TIME_Absolute ephemeral_validity; | ||
266 | |||
267 | /** | ||
268 | * Our ephemeral key. | ||
269 | */ | ||
270 | struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key; | ||
271 | |||
272 | /** | ||
273 | * Node in the ephemeral cache for this entry. | ||
274 | * Used for expiration. | ||
275 | */ | ||
276 | struct GNUNET_CONTAINER_HeapNode *hn; | ||
277 | }; | ||
278 | |||
279 | |||
280 | /** | ||
91 | * Client connected to the transport service. | 281 | * Client connected to the transport service. |
92 | */ | 282 | */ |
93 | struct TransportClient; | 283 | struct TransportClient; |
@@ -100,72 +290,73 @@ struct Neighbour; | |||
100 | 290 | ||
101 | 291 | ||
102 | /** | 292 | /** |
103 | * List of available queues for a particular neighbour. | 293 | * An ATS session is a message queue provided by a communicator |
294 | * via which we can reach a particular neighbour. | ||
104 | */ | 295 | */ |
105 | struct Queue | 296 | struct GNUNET_ATS_Session |
106 | { | 297 | { |
107 | /** | 298 | /** |
108 | * Kept in a MDLL. | 299 | * Kept in a MDLL. |
109 | */ | 300 | */ |
110 | struct Queue *next_neighbour; | 301 | struct GNUNET_ATS_Session *next_neighbour; |
111 | 302 | ||
112 | /** | 303 | /** |
113 | * Kept in a MDLL. | 304 | * Kept in a MDLL. |
114 | */ | 305 | */ |
115 | struct Queue *prev_neighbour; | 306 | struct GNUNET_ATS_Session *prev_neighbour; |
116 | 307 | ||
117 | /** | 308 | /** |
118 | * Kept in a MDLL. | 309 | * Kept in a MDLL. |
119 | */ | 310 | */ |
120 | struct Queue *prev_client; | 311 | struct GNUNET_ATS_Session *prev_client; |
121 | 312 | ||
122 | /** | 313 | /** |
123 | * Kept in a MDLL. | 314 | * Kept in a MDLL. |
124 | */ | 315 | */ |
125 | struct Queue *next_client; | 316 | struct GNUNET_ATS_Session *next_client; |
126 | 317 | ||
127 | /** | 318 | /** |
128 | * Which neighbour is this queue for? | 319 | * Which neighbour is this ATS session for? |
129 | */ | 320 | */ |
130 | struct Neighbour *neighbour; | 321 | struct Neighbour *neighbour; |
131 | 322 | ||
132 | /** | 323 | /** |
133 | * Which communicator offers this queue? | 324 | * Which communicator offers this ATS session? |
134 | */ | 325 | */ |
135 | struct TransportClient *tc; | 326 | struct TransportClient *tc; |
136 | 327 | ||
137 | /** | 328 | /** |
138 | * Address served by the queue. | 329 | * Address served by the ATS session. |
139 | */ | 330 | */ |
140 | const char *address; | 331 | const char *address; |
141 | 332 | ||
142 | /** | 333 | /** |
143 | * Our current RTT estimate for this queue. | 334 | * Our current RTT estimate for this ATS session. |
144 | */ | 335 | */ |
145 | struct GNUNET_TIME_Relative rtt; | 336 | struct GNUNET_TIME_Relative rtt; |
146 | 337 | ||
147 | /** | 338 | /** |
148 | * Unique identifier of this queue with the communicator. | 339 | * Unique identifier of this ATS session with the communicator. |
149 | */ | 340 | */ |
150 | uint32_t qid; | 341 | uint32_t qid; |
151 | 342 | ||
152 | /** | 343 | /** |
153 | * Maximum transmission unit supported by this queue. | 344 | * Maximum transmission unit supported by this ATS session. |
154 | */ | 345 | */ |
155 | uint32_t mtu; | 346 | uint32_t mtu; |
156 | 347 | ||
157 | /** | 348 | /** |
158 | * Distance to the target of this queue. | 349 | * Distance to the target of this ATS session. |
159 | */ | 350 | */ |
160 | uint32_t distance; | 351 | uint32_t distance; |
161 | 352 | ||
162 | /** | 353 | /** |
163 | * Network type offered by this queue. | 354 | * Network type offered by this ATS session. |
164 | */ | 355 | */ |
165 | enum GNUNET_NetworkType nt; | 356 | enum GNUNET_NetworkType nt; |
166 | 357 | ||
167 | /** | 358 | /** |
168 | * Connection status for this queue. | 359 | * Connection status for this ATS session. |
169 | */ | 360 | */ |
170 | enum GNUNET_TRANSPORT_ConnectionStatus cs; | 361 | enum GNUNET_TRANSPORT_ConnectionStatus cs; |
171 | 362 | ||
@@ -179,7 +370,15 @@ struct Queue | |||
179 | */ | 370 | */ |
180 | uint32_t num_bytes_pending; | 371 | uint32_t num_bytes_pending; |
181 | 372 | ||
182 | // FIXME: add ATS-specific fields here! | 373 | /** |
374 | * How much outbound bandwidth do we have available for this session? | ||
375 | */ | ||
376 | struct GNUNET_BANDWIDTH_Tracker tracker_out; | ||
377 | |||
378 | /** | ||
379 | * How much inbound bandwidth do we have available for this session? | ||
380 | */ | ||
381 | struct GNUNET_BANDWIDTH_Tracker tracker_in; | ||
183 | }; | 382 | }; |
184 | 383 | ||
185 | 384 | ||
@@ -205,14 +404,14 @@ struct Neighbour | |||
205 | struct PendingMessage *pending_msg_tail; | 404 | struct PendingMessage *pending_msg_tail; |
206 | 405 | ||
207 | /** | 406 | /** |
208 | * Head of DLL of queues to this peer. | 407 | * Head of DLL of ATS sessions to this peer. |
209 | */ | 408 | */ |
210 | struct Queue *queue_head; | 409 | struct GNUNET_ATS_Session *session_head; |
211 | 410 | ||
212 | /** | 411 | /** |
213 | * Tail of DLL of queues to this peer. | 412 | * Tail of DLL of ATS sessions to this peer. |
214 | */ | 413 | */ |
215 | struct Queue *queue_tail; | 414 | struct GNUNET_ATS_Session *session_tail; |
216 | 415 | ||
217 | /** | 416 | /** |
218 | * Quota at which CORE is allowed to transmit to this peer | 417 | * Quota at which CORE is allowed to transmit to this peer |
@@ -411,12 +610,12 @@ struct TransportClient | |||
411 | /** | 610 | /** |
412 | * Head of DLL of queues offered by this communicator. | 611 | * Head of DLL of queues offered by this communicator. |
413 | */ | 612 | */ |
414 | struct Queue *queue_head; | 613 | struct GNUNET_ATS_Session *session_head; |
415 | 614 | ||
416 | /** | 615 | /** |
417 | * Tail of DLL of queues offered by this communicator. | 616 | * Tail of DLL of queues offered by this communicator. |
418 | */ | 617 | */ |
419 | struct Queue *queue_tail; | 618 | struct GNUNET_ATS_Session *session_tail; |
420 | 619 | ||
421 | /** | 620 | /** |
422 | * Head of list of the addresses of this peer offered by this communicator. | 621 | * Head of list of the addresses of this peer offered by this communicator. |
@@ -453,22 +652,22 @@ static struct TransportClient *clients_tail; | |||
453 | /** | 652 | /** |
454 | * Statistics handle. | 653 | * Statistics handle. |
455 | */ | 654 | */ |
456 | struct GNUNET_STATISTICS_Handle *GST_stats; | 655 | static struct GNUNET_STATISTICS_Handle *GST_stats; |
457 | 656 | ||
458 | /** | 657 | /** |
459 | * Configuration handle. | 658 | * Configuration handle. |
460 | */ | 659 | */ |
461 | const struct GNUNET_CONFIGURATION_Handle *GST_cfg; | 660 | static const struct GNUNET_CONFIGURATION_Handle *GST_cfg; |
462 | 661 | ||
463 | /** | 662 | /** |
464 | * Our public key. | 663 | * Our public key. |
465 | */ | 664 | */ |
466 | struct GNUNET_PeerIdentity GST_my_identity; | 665 | static struct GNUNET_PeerIdentity GST_my_identity; |
467 | 666 | ||
468 | /** | 667 | /** |
469 | * Our private key. | 668 | * Our private key. |
470 | */ | 669 | */ |
471 | struct GNUNET_CRYPTO_EddsaPrivateKey *GST_my_private_key; | 670 | static struct GNUNET_CRYPTO_EddsaPrivateKey *GST_my_private_key; |
472 | 671 | ||
473 | /** | 672 | /** |
474 | * Map from PIDs to `struct Neighbour` entries. A peer is | 673 | * Map from PIDs to `struct Neighbour` entries. A peer is |
@@ -481,6 +680,42 @@ static struct GNUNET_CONTAINER_MultiPeerMap *neighbours; | |||
481 | */ | 680 | */ |
482 | static struct GNUNET_PEERSTORE_Handle *peerstore; | 681 | static struct GNUNET_PEERSTORE_Handle *peerstore; |
483 | 682 | ||
683 | /** | ||
684 | * Heap sorting `struct EphemeralCacheEntry` by their | ||
685 | * key/signature validity. | ||
686 | */ | ||
687 | static struct GNUNET_CONTAINER_Heap *ephemeral_heap; | ||
688 | |||
689 | /** | ||
690 | * Hash map for looking up `struct EphemeralCacheEntry`s | ||
691 | * by peer identity. (We may have ephemerals in our | ||
692 | * cache for which we do not have a neighbour entry, | ||
693 | * and similar many neighbours may not need ephemerals, | ||
694 | * so we use a second map.) | ||
695 | */ | ||
696 | static struct GNUNET_CONTAINER_MultiPeerMap *ephemeral_map; | ||
697 | |||
698 | /** | ||
699 | * Our connection to ATS for allocation and bootstrapping. | ||
700 | */ | ||
701 | static struct GNUNET_ATS_TransportHandle *ats; | ||
702 | |||
703 | |||
704 | /** | ||
705 | * Free cached ephemeral key. | ||
706 | * | ||
707 | * @param ece cached signature to free | ||
708 | */ | ||
709 | static void | ||
710 | free_ephemeral (struct EphemeralCacheEntry *ece) | ||
711 | { | ||
712 | GNUNET_CONTAINER_multipeermap_remove (ephemeral_map, | ||
713 | &ece->target, | ||
714 | ece); | ||
715 | GNUNET_CONTAINER_heap_remove_node (ece->hn); | ||
716 | GNUNET_free (ece); | ||
717 | } | ||
718 | |||
484 | 719 | ||
485 | /** | 720 | /** |
486 | * Lookup neighbour record for peer @a pid. | 721 | * Lookup neighbour record for peer @a pid. |
@@ -654,7 +889,7 @@ client_connect_cb (void *cls, | |||
654 | static void | 889 | static void |
655 | free_neighbour (struct Neighbour *neighbour) | 890 | free_neighbour (struct Neighbour *neighbour) |
656 | { | 891 | { |
657 | GNUNET_assert (NULL == neighbour->queue_head); | 892 | GNUNET_assert (NULL == neighbour->session_head); |
658 | GNUNET_assert (GNUNET_YES == | 893 | GNUNET_assert (GNUNET_YES == |
659 | GNUNET_CONTAINER_multipeermap_remove (neighbours, | 894 | GNUNET_CONTAINER_multipeermap_remove (neighbours, |
660 | &neighbour->pid, | 895 | &neighbour->pid, |
@@ -743,7 +978,7 @@ cores_send_disconnect_info (const struct GNUNET_PeerIdentity *pid) | |||
743 | * @param queue the queue to free | 978 | * @param queue the queue to free |
744 | */ | 979 | */ |
745 | static void | 980 | static void |
746 | free_queue (struct Queue *queue) | 981 | free_queue (struct GNUNET_ATS_Session *queue) |
747 | { | 982 | { |
748 | struct Neighbour *neighbour = queue->neighbour; | 983 | struct Neighbour *neighbour = queue->neighbour; |
749 | struct TransportClient *tc = queue->tc; | 984 | struct TransportClient *tc = queue->tc; |
@@ -753,20 +988,22 @@ free_queue (struct Queue *queue) | |||
753 | }; | 988 | }; |
754 | 989 | ||
755 | GNUNET_CONTAINER_MDLL_remove (neighbour, | 990 | GNUNET_CONTAINER_MDLL_remove (neighbour, |
756 | neighbour->queue_head, | 991 | neighbour->session_head, |
757 | neighbour->queue_tail, | 992 | neighbour->session_tail, |
758 | queue); | 993 | queue); |
759 | GNUNET_CONTAINER_MDLL_remove (client, | 994 | GNUNET_CONTAINER_MDLL_remove (client, |
760 | tc->details.communicator.queue_head, | 995 | tc->details.communicator.session_head, |
761 | tc->details.communicator.queue_tail, | 996 | tc->details.communicator.session_tail, |
762 | queue); | 997 | queue); |
763 | 998 | ||
764 | notify_monitors (&neighbour->pid, | 999 | notify_monitors (&neighbour->pid, |
765 | queue->address, | 1000 | queue->address, |
766 | queue->nt, | 1001 | queue->nt, |
767 | &me); | 1002 | &me); |
1003 | GNUNET_BANDWIDTH_tracker_notification_stop (&queue->tracker_in); | ||
1004 | GNUNET_BANDWIDTH_tracker_notification_stop (&queue->tracker_out); | ||
768 | GNUNET_free (queue); | 1005 | GNUNET_free (queue); |
769 | if (NULL == neighbour->queue_head) | 1006 | if (NULL == neighbour->session_head) |
770 | { | 1007 | { |
771 | cores_send_disconnect_info (&neighbour->pid); | 1008 | cores_send_disconnect_info (&neighbour->pid); |
772 | free_neighbour (neighbour); | 1009 | free_neighbour (neighbour); |
@@ -844,10 +1081,10 @@ client_disconnect_cb (void *cls, | |||
844 | break; | 1081 | break; |
845 | case CT_COMMUNICATOR: | 1082 | case CT_COMMUNICATOR: |
846 | { | 1083 | { |
847 | struct Queue *q; | 1084 | struct GNUNET_ATS_Session *q; |
848 | struct AddressListEntry *ale; | 1085 | struct AddressListEntry *ale; |
849 | 1086 | ||
850 | while (NULL != (q = tc->details.communicator.queue_head)) | 1087 | while (NULL != (q = tc->details.communicator.session_head)) |
851 | free_queue (q); | 1088 | free_queue (q); |
852 | while (NULL != (ale = tc->details.communicator.addr_head)) | 1089 | while (NULL != (ale = tc->details.communicator.addr_head)) |
853 | free_address_list_entry (ale); | 1090 | free_address_list_entry (ale); |
@@ -1356,6 +1593,34 @@ check_add_queue_message (void *cls, | |||
1356 | 1593 | ||
1357 | 1594 | ||
1358 | /** | 1595 | /** |
1596 | * Bandwidth tracker informs us that the delay until we | ||
1597 | * can transmit again changed. | ||
1598 | * | ||
1599 | * @param cls a `struct GNUNET_ATS_Session` for which the delay changed | ||
1600 | */ | ||
1601 | static void | ||
1602 | tracker_update_cb (void *cls) | ||
1603 | { | ||
1604 | struct GNUNET_ATS_Session *queue = cls; | ||
1605 | |||
1606 | // FIXME: re-schedule transmission tasks if applicable! | ||
1607 | } | ||
1608 | |||
1609 | |||
1610 | /** | ||
1611 | * Bandwidth tracker informs us that excessive bandwidth was allocated | ||
1612 | * which is not being used. | ||
1613 | * | ||
1614 | * @param cls a `struct GNUNET_ATS_Session` for which the excess was noted | ||
1615 | */ | ||
1616 | static void | ||
1617 | tracker_excess_cb (void *cls) | ||
1618 | { | ||
1619 | /* FIXME: what do we do? */ | ||
1620 | } | ||
1621 | |||
1622 | |||
1623 | /** | ||
1359 | * New queue became available. Process the request. | 1624 | * New queue became available. Process the request. |
1360 | * | 1625 | * |
1361 | * @param cls the client | 1626 | * @param cls the client |
@@ -1366,7 +1631,7 @@ handle_add_queue_message (void *cls, | |||
1366 | const struct GNUNET_TRANSPORT_AddQueueMessage *aqm) | 1631 | const struct GNUNET_TRANSPORT_AddQueueMessage *aqm) |
1367 | { | 1632 | { |
1368 | struct TransportClient *tc = cls; | 1633 | struct TransportClient *tc = cls; |
1369 | struct Queue *queue; | 1634 | struct GNUNET_ATS_Session *queue; |
1370 | struct Neighbour *neighbour; | 1635 | struct Neighbour *neighbour; |
1371 | const char *addr; | 1636 | const char *addr; |
1372 | uint16_t addr_len; | 1637 | uint16_t addr_len; |
@@ -1388,7 +1653,7 @@ handle_add_queue_message (void *cls, | |||
1388 | addr_len = ntohs (aqm->header.size) - sizeof (*aqm); | 1653 | addr_len = ntohs (aqm->header.size) - sizeof (*aqm); |
1389 | addr = (const char *) &aqm[1]; | 1654 | addr = (const char *) &aqm[1]; |
1390 | 1655 | ||
1391 | queue = GNUNET_malloc (sizeof (struct Queue) + addr_len); | 1656 | queue = GNUNET_malloc (sizeof (struct GNUNET_ATS_Session) + addr_len); |
1392 | queue->tc = tc; | 1657 | queue->tc = tc; |
1393 | queue->address = (const char *) &queue[1]; | 1658 | queue->address = (const char *) &queue[1]; |
1394 | queue->rtt = GNUNET_TIME_UNIT_FOREVER_REL; | 1659 | queue->rtt = GNUNET_TIME_UNIT_FOREVER_REL; |
@@ -1398,6 +1663,20 @@ handle_add_queue_message (void *cls, | |||
1398 | queue->nt = (enum GNUNET_NetworkType) ntohl (aqm->nt); | 1663 | queue->nt = (enum GNUNET_NetworkType) ntohl (aqm->nt); |
1399 | queue->cs = (enum GNUNET_TRANSPORT_ConnectionStatus) ntohl (aqm->cs); | 1664 | queue->cs = (enum GNUNET_TRANSPORT_ConnectionStatus) ntohl (aqm->cs); |
1400 | queue->neighbour = neighbour; | 1665 | queue->neighbour = neighbour; |
1666 | GNUNET_BANDWIDTH_tracker_init2 (&queue->tracker_in, | ||
1667 | &tracker_update_cb, | ||
1668 | queue, | ||
1669 | GNUNET_BANDWIDTH_ZERO, | ||
1670 | 0 /* FIXME: max carry in seconds! */, | ||
1671 | &tracker_excess_cb, | ||
1672 | queue); | ||
1673 | GNUNET_BANDWIDTH_tracker_init2 (&queue->tracker_out, | ||
1674 | &tracker_update_cb, | ||
1675 | queue, | ||
1676 | GNUNET_BANDWIDTH_ZERO, | ||
1677 | 0 /* FIXME: max carry in seconds! */, | ||
1678 | &tracker_excess_cb, | ||
1679 | queue); | ||
1401 | memcpy (&queue[1], | 1680 | memcpy (&queue[1], |
1402 | addr, | 1681 | addr, |
1403 | addr_len); | 1682 | addr_len); |
@@ -1414,12 +1693,12 @@ handle_add_queue_message (void *cls, | |||
1414 | &me); | 1693 | &me); |
1415 | } | 1694 | } |
1416 | GNUNET_CONTAINER_MDLL_insert (neighbour, | 1695 | GNUNET_CONTAINER_MDLL_insert (neighbour, |
1417 | neighbour->queue_head, | 1696 | neighbour->session_head, |
1418 | neighbour->queue_tail, | 1697 | neighbour->session_tail, |
1419 | queue); | 1698 | queue); |
1420 | GNUNET_CONTAINER_MDLL_insert (client, | 1699 | GNUNET_CONTAINER_MDLL_insert (client, |
1421 | tc->details.communicator.queue_head, | 1700 | tc->details.communicator.session_head, |
1422 | tc->details.communicator.queue_tail, | 1701 | tc->details.communicator.session_tail, |
1423 | queue); | 1702 | queue); |
1424 | // FIXME: possibly transmit queued messages? | 1703 | // FIXME: possibly transmit queued messages? |
1425 | GNUNET_SERVICE_client_continue (tc->client); | 1704 | GNUNET_SERVICE_client_continue (tc->client); |
@@ -1444,7 +1723,7 @@ handle_del_queue_message (void *cls, | |||
1444 | GNUNET_SERVICE_client_drop (tc->client); | 1723 | GNUNET_SERVICE_client_drop (tc->client); |
1445 | return; | 1724 | return; |
1446 | } | 1725 | } |
1447 | for (struct Queue *queue = tc->details.communicator.queue_head; | 1726 | for (struct GNUNET_ATS_Session *queue = tc->details.communicator.session_head; |
1448 | NULL != queue; | 1727 | NULL != queue; |
1449 | queue = queue->next_client) | 1728 | queue = queue->next_client) |
1450 | { | 1729 | { |
@@ -1504,7 +1783,7 @@ notify_client_queues (void *cls, | |||
1504 | struct Neighbour *neighbour = value; | 1783 | struct Neighbour *neighbour = value; |
1505 | 1784 | ||
1506 | GNUNET_assert (CT_MONITOR == tc->type); | 1785 | GNUNET_assert (CT_MONITOR == tc->type); |
1507 | for (struct Queue *q = neighbour->queue_head; | 1786 | for (struct GNUNET_ATS_Session *q = neighbour->session_head; |
1508 | NULL != q; | 1787 | NULL != q; |
1509 | q = q->next_neighbour) | 1788 | q = q->next_neighbour) |
1510 | { | 1789 | { |
@@ -1555,6 +1834,74 @@ handle_monitor_start (void *cls, | |||
1555 | 1834 | ||
1556 | 1835 | ||
1557 | /** | 1836 | /** |
1837 | * Signature of a function called by ATS with the current bandwidth | ||
1838 | * allocation to be used as determined by ATS. | ||
1839 | * | ||
1840 | * @param cls closure, NULL | ||
1841 | * @param session session this is about | ||
1842 | * @param bandwidth_out assigned outbound bandwidth for the connection, | ||
1843 | * 0 to signal disconnect | ||
1844 | * @param bandwidth_in assigned inbound bandwidth for the connection, | ||
1845 | * 0 to signal disconnect | ||
1846 | */ | ||
1847 | static void | ||
1848 | ats_allocation_cb (void *cls, | ||
1849 | struct GNUNET_ATS_Session *session, | ||
1850 | struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, | ||
1851 | struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in) | ||
1852 | { | ||
1853 | (void) cls; | ||
1854 | GNUNET_BANDWIDTH_tracker_update_quota (&session->tracker_out, | ||
1855 | bandwidth_out); | ||
1856 | GNUNET_BANDWIDTH_tracker_update_quota (&session->tracker_in, | ||
1857 | bandwidth_in); | ||
1858 | } | ||
1859 | |||
1860 | |||
1861 | /** | ||
1862 | * Find transport client providing communication service | ||
1863 | * for the protocol @a prefix. | ||
1864 | * | ||
1865 | * @param prefix communicator name | ||
1866 | * @return NULL if no such transport client is available | ||
1867 | */ | ||
1868 | static struct TransportClient * | ||
1869 | lookup_communicator (const char *prefix) | ||
1870 | { | ||
1871 | GNUNET_break (0); // FIXME: implement | ||
1872 | return NULL; | ||
1873 | } | ||
1874 | |||
1875 | |||
1876 | /** | ||
1877 | * Signature of a function called by ATS suggesting transport to | ||
1878 | * try connecting with a particular address. | ||
1879 | * | ||
1880 | * @param cls closure, NULL | ||
1881 | * @param pid target peer | ||
1882 | * @param address the address to try | ||
1883 | */ | ||
1884 | static void | ||
1885 | ats_suggestion_cb (void *cls, | ||
1886 | const struct GNUNET_PeerIdentity *pid, | ||
1887 | const char *address) | ||
1888 | { | ||
1889 | struct TransportClient *tc; | ||
1890 | char *prefix; | ||
1891 | |||
1892 | (void) cls; | ||
1893 | prefix = NULL; // FIXME | ||
1894 | tc = lookup_communicator (prefix); | ||
1895 | if (NULL == tc) | ||
1896 | { | ||
1897 | // STATS... | ||
1898 | return; | ||
1899 | } | ||
1900 | // FIXME: forward suggestion to tc | ||
1901 | } | ||
1902 | |||
1903 | |||
1904 | /** | ||
1558 | * Free neighbour entry. | 1905 | * Free neighbour entry. |
1559 | * | 1906 | * |
1560 | * @param cls NULL | 1907 | * @param cls NULL |
@@ -1579,6 +1926,28 @@ free_neighbour_cb (void *cls, | |||
1579 | 1926 | ||
1580 | 1927 | ||
1581 | /** | 1928 | /** |
1929 | * Free ephemeral entry. | ||
1930 | * | ||
1931 | * @param cls NULL | ||
1932 | * @param pid unused | ||
1933 | * @param value a `struct Neighbour` | ||
1934 | * @return #GNUNET_OK (always) | ||
1935 | */ | ||
1936 | static int | ||
1937 | free_ephemeral_cb (void *cls, | ||
1938 | const struct GNUNET_PeerIdentity *pid, | ||
1939 | void *value) | ||
1940 | { | ||
1941 | struct EphemeralCacheEntry *ece = value; | ||
1942 | |||
1943 | (void) cls; | ||
1944 | (void) pid; | ||
1945 | free_ephemeral (ece); | ||
1946 | return GNUNET_OK; | ||
1947 | } | ||
1948 | |||
1949 | |||
1950 | /** | ||
1582 | * Function called when the service shuts down. Unloads our plugins | 1951 | * Function called when the service shuts down. Unloads our plugins |
1583 | * and cancels pending validations. | 1952 | * and cancels pending validations. |
1584 | * | 1953 | * |
@@ -1592,6 +1961,11 @@ do_shutdown (void *cls) | |||
1592 | GNUNET_CONTAINER_multipeermap_iterate (neighbours, | 1961 | GNUNET_CONTAINER_multipeermap_iterate (neighbours, |
1593 | &free_neighbour_cb, | 1962 | &free_neighbour_cb, |
1594 | NULL); | 1963 | NULL); |
1964 | if (NULL != ats) | ||
1965 | { | ||
1966 | GNUNET_ATS_transport_done (ats); | ||
1967 | ats = NULL; | ||
1968 | } | ||
1595 | if (NULL != peerstore) | 1969 | if (NULL != peerstore) |
1596 | { | 1970 | { |
1597 | GNUNET_PEERSTORE_disconnect (peerstore, | 1971 | GNUNET_PEERSTORE_disconnect (peerstore, |
@@ -1610,6 +1984,14 @@ do_shutdown (void *cls) | |||
1610 | GST_my_private_key = NULL; | 1984 | GST_my_private_key = NULL; |
1611 | } | 1985 | } |
1612 | GNUNET_CONTAINER_multipeermap_destroy (neighbours); | 1986 | GNUNET_CONTAINER_multipeermap_destroy (neighbours); |
1987 | neighbours = NULL; | ||
1988 | GNUNET_CONTAINER_multipeermap_iterate (ephemeral_map, | ||
1989 | &free_ephemeral_cb, | ||
1990 | NULL); | ||
1991 | GNUNET_CONTAINER_multipeermap_destroy (ephemeral_map); | ||
1992 | ephemeral_map = NULL; | ||
1993 | GNUNET_CONTAINER_heap_destroy (ephemeral_heap); | ||
1994 | ephemeral_heap = NULL; | ||
1613 | } | 1995 | } |
1614 | 1996 | ||
1615 | 1997 | ||
@@ -1630,6 +2012,9 @@ run (void *cls, | |||
1630 | GST_cfg = c; | 2012 | GST_cfg = c; |
1631 | neighbours = GNUNET_CONTAINER_multipeermap_create (1024, | 2013 | neighbours = GNUNET_CONTAINER_multipeermap_create (1024, |
1632 | GNUNET_YES); | 2014 | GNUNET_YES); |
2015 | ephemeral_map = GNUNET_CONTAINER_multipeermap_create (32, | ||
2016 | GNUNET_YES); | ||
2017 | ephemeral_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); | ||
1633 | GST_my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (GST_cfg); | 2018 | GST_my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (GST_cfg); |
1634 | if (NULL == GST_my_private_key) | 2019 | if (NULL == GST_my_private_key) |
1635 | { | 2020 | { |
@@ -1643,19 +2028,28 @@ run (void *cls, | |||
1643 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | 2028 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, |
1644 | "My identity is `%s'\n", | 2029 | "My identity is `%s'\n", |
1645 | GNUNET_i2s_full (&GST_my_identity)); | 2030 | GNUNET_i2s_full (&GST_my_identity)); |
1646 | |||
1647 | GST_stats = GNUNET_STATISTICS_create ("transport", | 2031 | GST_stats = GNUNET_STATISTICS_create ("transport", |
1648 | GST_cfg); | 2032 | GST_cfg); |
1649 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, | 2033 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, |
1650 | NULL); | 2034 | NULL); |
1651 | peerstore = GNUNET_PEERSTORE_connect (GST_cfg); | 2035 | peerstore = GNUNET_PEERSTORE_connect (GST_cfg); |
1652 | if (NULL == peerstore) | 2036 | if (NULL == peerstore) |
1653 | { | 2037 | { |
1654 | GNUNET_break (0); | 2038 | GNUNET_break (0); |
1655 | GNUNET_SCHEDULER_shutdown (); | 2039 | GNUNET_SCHEDULER_shutdown (); |
1656 | return; | 2040 | return; |
1657 | } | 2041 | } |
1658 | /* start subsystems */ | 2042 | ats = GNUNET_ATS_transport_init (GST_cfg, |
2043 | &ats_allocation_cb, | ||
2044 | NULL, | ||
2045 | &ats_suggestion_cb, | ||
2046 | NULL); | ||
2047 | if (NULL == ats) | ||
2048 | { | ||
2049 | GNUNET_break (0); | ||
2050 | GNUNET_SCHEDULER_shutdown (); | ||
2051 | return; | ||
2052 | } | ||
1659 | } | 2053 | } |
1660 | 2054 | ||
1661 | 2055 | ||