diff options
author | Christian Grothoff <christian@grothoff.org> | 2018-11-01 15:29:10 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2018-11-01 15:29:51 +0100 |
commit | 11916b980c6f022ef4be5e34eea2a0abdce68b10 (patch) | |
tree | f4245de001e8d697f8c1dfbcddab3e2447e90507 /src | |
parent | eead33d85b73836ae23a2082326cf2ad8bfa2f7f (diff) | |
download | gnunet-11916b980c6f022ef4be5e34eea2a0abdce68b10.tar.gz gnunet-11916b980c6f022ef4be5e34eea2a0abdce68b10.zip |
attempting to fix #5464
Diffstat (limited to 'src')
-rw-r--r-- | src/cadet/.gitignore | 3 | ||||
-rw-r--r-- | src/cadet/gnunet-service-cadet_channel.c | 7 | ||||
-rw-r--r-- | src/transport/transport_api2_communication.c | 432 |
3 files changed, 439 insertions, 3 deletions
diff --git a/src/cadet/.gitignore b/src/cadet/.gitignore index 44382fde9..935049ce8 100644 --- a/src/cadet/.gitignore +++ b/src/cadet/.gitignore | |||
@@ -21,4 +21,5 @@ test_cadet_local | |||
21 | test_cadet_single | 21 | test_cadet_single |
22 | gnunet-service-cadet-new | 22 | gnunet-service-cadet-new |
23 | test_cadet_local_mq | 23 | test_cadet_local_mq |
24 | test_cadet_*_new \ No newline at end of file | 24 | test_cadet_*_newtest_cadet_2_reopen |
25 | test_cadet_5_reopen | ||
diff --git a/src/cadet/gnunet-service-cadet_channel.c b/src/cadet/gnunet-service-cadet_channel.c index 06711dc8b..8ef598132 100644 --- a/src/cadet/gnunet-service-cadet_channel.c +++ b/src/cadet/gnunet-service-cadet_channel.c | |||
@@ -500,6 +500,11 @@ channel_destroy (struct CadetChannel *ch) | |||
500 | GNUNET_free (crm->data_message); | 500 | GNUNET_free (crm->data_message); |
501 | GNUNET_free (crm); | 501 | GNUNET_free (crm); |
502 | } | 502 | } |
503 | if (CADET_CHANNEL_LOOSE == ch->state) | ||
504 | { | ||
505 | GSC_drop_loose_channel (&ch->h_port, | ||
506 | ch); | ||
507 | } | ||
503 | if (NULL != ch->owner) | 508 | if (NULL != ch->owner) |
504 | { | 509 | { |
505 | free_channel_client (ch->owner); | 510 | free_channel_client (ch->owner); |
@@ -1136,8 +1141,6 @@ GCCH_channel_local_destroy (struct CadetChannel *ch, | |||
1136 | target, but that never went anywhere. Nothing to do here. */ | 1141 | target, but that never went anywhere. Nothing to do here. */ |
1137 | break; | 1142 | break; |
1138 | case CADET_CHANNEL_LOOSE: | 1143 | case CADET_CHANNEL_LOOSE: |
1139 | GSC_drop_loose_channel (&ch->h_port, | ||
1140 | ch); | ||
1141 | break; | 1144 | break; |
1142 | default: | 1145 | default: |
1143 | GCT_send_channel_destroy (ch->t, | 1146 | GCT_send_channel_destroy (ch->t, |
diff --git a/src/transport/transport_api2_communication.c b/src/transport/transport_api2_communication.c new file mode 100644 index 000000000..e33c5f444 --- /dev/null +++ b/src/transport/transport_api2_communication.c | |||
@@ -0,0 +1,432 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2018 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 | |||
19 | /** | ||
20 | * @file transport/transport_api2_communication.c | ||
21 | * @brief implementation of the gnunet_transport_communication_service.h API | ||
22 | * @author Christian Grothoff | ||
23 | */ | ||
24 | #include "platform.h" | ||
25 | #include "gnunet_util_lib.h" | ||
26 | #include "gnunet_protocols.h" | ||
27 | #include "gnunet_transport_communication_service.h" | ||
28 | #include "transport.h" | ||
29 | |||
30 | |||
31 | /** | ||
32 | * Opaque handle to the transport service for communicators. | ||
33 | */ | ||
34 | struct GNUNET_TRANSPORT_CommunicatorHandle | ||
35 | { | ||
36 | /** | ||
37 | * Head of DLL of addresses this communicator offers to the transport service. | ||
38 | */ | ||
39 | struct GNUNET_TRANSPORT_AddressIdentifier *ai_head; | ||
40 | |||
41 | /** | ||
42 | * Tail of DLL of addresses this communicator offers to the transport service. | ||
43 | */ | ||
44 | struct GNUNET_TRANSPORT_AddressIdentifier *ai_tail; | ||
45 | |||
46 | /** | ||
47 | * Our configuration. | ||
48 | */ | ||
49 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
50 | |||
51 | /** | ||
52 | * Name of the communicator. | ||
53 | */ | ||
54 | const char *name; | ||
55 | |||
56 | /** | ||
57 | * Function to call when the transport service wants us to initiate | ||
58 | * a communication channel with another peer. | ||
59 | */ | ||
60 | GNUNET_TRANSPORT_CommunicatorMqInit mq_init; | ||
61 | |||
62 | /** | ||
63 | * Closure for @e mq_init. | ||
64 | */ | ||
65 | void *mq_init_cls; | ||
66 | |||
67 | /** | ||
68 | * MTU of the communicator | ||
69 | */ | ||
70 | size_t mtu; | ||
71 | |||
72 | /** | ||
73 | * Internal UUID for the address used in communication with the | ||
74 | * transport service. | ||
75 | */ | ||
76 | uint32_t aid_gen; | ||
77 | |||
78 | }; | ||
79 | |||
80 | |||
81 | |||
82 | /** | ||
83 | * Internal representation of an address a communicator is | ||
84 | * currently providing for the transport service. | ||
85 | */ | ||
86 | struct GNUNET_TRANSPORT_AddressIdentifier | ||
87 | { | ||
88 | |||
89 | /** | ||
90 | * Kept in a DLL. | ||
91 | */ | ||
92 | struct GNUNET_TRANSPORT_AddressIdentifier *next; | ||
93 | |||
94 | /** | ||
95 | * Kept in a DLL. | ||
96 | */ | ||
97 | struct GNUNET_TRANSPORT_AddressIdentifier *prev; | ||
98 | |||
99 | /** | ||
100 | * Transport handle where the address was added. | ||
101 | */ | ||
102 | struct GNUNET_TRANSPORT_CommunicatorHandle *ch; | ||
103 | |||
104 | /** | ||
105 | * The actual address. | ||
106 | */ | ||
107 | char *address; | ||
108 | |||
109 | /** | ||
110 | * When does the address expire? (Expected lifetime of the | ||
111 | * address.) | ||
112 | */ | ||
113 | struct GNUNET_TIME_Relative expiration; | ||
114 | |||
115 | /** | ||
116 | * Internal UUID for the address used in communication with the | ||
117 | * transport service. | ||
118 | */ | ||
119 | uint32_t aid; | ||
120 | |||
121 | /** | ||
122 | * Network type for the address. | ||
123 | */ | ||
124 | enum GNUNET_ATS_Network_Type nt; | ||
125 | |||
126 | }; | ||
127 | |||
128 | |||
129 | /** | ||
130 | * (re)connect our communicator to the transport service | ||
131 | * | ||
132 | * @param ch handle to reconnect | ||
133 | */ | ||
134 | static void | ||
135 | reconnect (struct GNUNET_TRANSPORT_CommunicatorHandle *ch); | ||
136 | |||
137 | |||
138 | /** | ||
139 | * Send message to the transport service about address @a ai | ||
140 | * being now available. | ||
141 | * | ||
142 | * @param ai address to add | ||
143 | */ | ||
144 | static void | ||
145 | send_add_address (struct GNUNET_TRANSPORT_AddressIdentifier *ai) | ||
146 | { | ||
147 | struct GNUNET_MQ_Envelope *env; | ||
148 | struct GNUNET_TRANSPORT_AddAddressMessage *aam; | ||
149 | |||
150 | if (NULL == ai->ch->mq) | ||
151 | return; | ||
152 | env = GNUNET_MQ_msg_extra (aam, | ||
153 | strlen (ai->address) + 1, | ||
154 | GNUNET_MESSAGE_TYPE_TRANSPORT_ADD_ADDRESS); | ||
155 | aam->expiration = GNUNET_TIME_relative_to_nbo (ai->expiration); | ||
156 | aam->nt = htonl ((uint32_t) ai->nt); | ||
157 | memcpy (&aam[1], | ||
158 | ai->address, | ||
159 | strlen (ai->address) + 1); | ||
160 | GNUNET_MQ_send (ai->ch->mq, | ||
161 | env); | ||
162 | } | ||
163 | |||
164 | |||
165 | /** | ||
166 | * Send message to the transport service about address @a ai | ||
167 | * being no longer available. | ||
168 | * | ||
169 | * @param ai address to delete | ||
170 | */ | ||
171 | static void | ||
172 | send_del_address (struct GNUNET_TRANSPORT_AddressIdentifier *ai) | ||
173 | { | ||
174 | struct GNUNET_MQ_Envelope *env; | ||
175 | struct GNUNET_TRANSPORT_DelAddressMessage *dam; | ||
176 | |||
177 | if (NULL == ai->ch->mq) | ||
178 | return; | ||
179 | env = GNUNET_MQ_msg (dam, | ||
180 | GNUNET_MESSAGE_TYPE_TRANSPORT_DEL_ADDRESS); | ||
181 | dam.aid = htonl (ai->aid); | ||
182 | GNUNET_MQ_send (ai->ch->mq, | ||
183 | env); | ||
184 | } | ||
185 | |||
186 | |||
187 | /** | ||
188 | * Function called on MQ errors. | ||
189 | */ | ||
190 | static void | ||
191 | error_handler (void *cls, | ||
192 | enum GNUNET_MQ_Error error) | ||
193 | { | ||
194 | struct GNUNET_TRANSPORT_CommunicatorHandle *ch = cls; | ||
195 | |||
196 | GNUNET_MQ_destroy (ch->mq); | ||
197 | ch->mq = NULL; | ||
198 | /* TODO: maybe do this with exponential backoff/delay */ | ||
199 | reconnect (ch); | ||
200 | } | ||
201 | |||
202 | |||
203 | /** | ||
204 | * (re)connect our communicator to the transport service | ||
205 | * | ||
206 | * @param ch handle to reconnect | ||
207 | */ | ||
208 | static void | ||
209 | reconnect (struct GNUNET_TRANSPORT_CommunicatorHandle *ch) | ||
210 | { | ||
211 | struct GNUNET_MQ_MessageHandler handlers[] = { | ||
212 | GNUNET_MQ_handler_end() | ||
213 | }; | ||
214 | |||
215 | ch->mq = GNUNET_CLIENT_connect (cfg, | ||
216 | "transport", | ||
217 | handlers, | ||
218 | &error_handler, | ||
219 | ch); | ||
220 | for (struct GNUNET_TRANSPORT_AddressIdentifier ai = ch->ai_head; | ||
221 | NULL != ai; | ||
222 | ai = ai->next) | ||
223 | send_add_address (ai); | ||
224 | } | ||
225 | |||
226 | |||
227 | /** | ||
228 | * Connect to the transport service. | ||
229 | * | ||
230 | * @param cfg configuration to use | ||
231 | * @param name name of the communicator that is connecting | ||
232 | * @param mtu maximum message size supported by communicator, 0 if | ||
233 | * sending is not supported, SIZE_MAX for no MTU | ||
234 | * @param mq_init function to call to initialize a message queue given | ||
235 | * the address of another peer, can be NULL if the | ||
236 | * communicator only supports receiving messages | ||
237 | * @param mq_init_cls closure for @a mq_init | ||
238 | * @return NULL on error | ||
239 | */ | ||
240 | struct GNUNET_TRANSPORT_CommunicatorHandle * | ||
241 | GNUNET_TRANSPORT_communicator_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
242 | const char *name, | ||
243 | size_t mtu, | ||
244 | GNUNET_TRANSPORT_CommunicatorMqInit mq_init, | ||
245 | void *mq_init_cls) | ||
246 | { | ||
247 | struct GNUNET_TRANSPORT_CommunicatorHandle *ch; | ||
248 | |||
249 | ch = GNUNET_new (struct GNUNET_TRANSPORT_CommunicatorHandle); | ||
250 | ch->cfg = cfg; | ||
251 | ch->name = name; | ||
252 | ch->mtu = mtu; | ||
253 | ch->mq_init = mq_init; | ||
254 | ch->mq_init_cls = mq_init_cls; | ||
255 | reconnect (ch); | ||
256 | if (NULL == ch->mq) | ||
257 | { | ||
258 | GNUNET_free (ch); | ||
259 | return NULL; | ||
260 | } | ||
261 | return ch; | ||
262 | } | ||
263 | |||
264 | |||
265 | /** | ||
266 | * Disconnect from the transport service. | ||
267 | * | ||
268 | * @param ch handle returned from connect | ||
269 | */ | ||
270 | void | ||
271 | GNUNET_TRANSPORT_communicator_disconnect (struct GNUNET_TRANSPORT_CommunicatorHandle *ch) | ||
272 | { | ||
273 | while (NULL != ch->ai_head) | ||
274 | { | ||
275 | GNUNET_break (0); /* communicator forgot to remove address, warn! */ | ||
276 | GNUNET_TRANSPORT_communicator_address_remove (ch->ai_head); | ||
277 | } | ||
278 | GNUNET_MQ_destroy (ch->mq); | ||
279 | GNUNET_free (ch); | ||
280 | } | ||
281 | |||
282 | |||
283 | /* ************************* Receiving *************************** */ | ||
284 | |||
285 | |||
286 | /** | ||
287 | * Notify transport service that the communicator has received | ||
288 | * a message. | ||
289 | * | ||
290 | * @param ch connection to transport service | ||
291 | * @param sender presumed sender of the message (details to be checked | ||
292 | * by higher layers) | ||
293 | * @param msg the message | ||
294 | * @param cb function to call once handling the message is done, NULL if | ||
295 | * flow control is not supported by this communicator | ||
296 | * @param cb_cls closure for @a cb | ||
297 | * @return #GNUNET_OK if all is well, #GNUNET_NO if the message was | ||
298 | * immediately dropped due to memory limitations (communicator | ||
299 | * should try to apply back pressure), | ||
300 | * #GNUNET_SYSERR if the message is ill formed and communicator | ||
301 | * should try to reset stream | ||
302 | */ | ||
303 | int | ||
304 | GNUNET_TRANSPORT_communicator_receive (struct GNUNET_TRANSPORT_CommunicatorHandle *ch, | ||
305 | const struct GNUNET_PeerIdentity *sender, | ||
306 | const struct GNUNET_MessageHeader *msg, | ||
307 | GNUNET_TRANSPORT_MessageCompletedCallback cb, | ||
308 | void *cb_cls) | ||
309 | { | ||
310 | struct GNUNET_MQ_Envelope *env; | ||
311 | struct GNUNET_TRANSPORT_IncomingMessage *im; | ||
312 | uint16_t msize; | ||
313 | |||
314 | if (NULL == ai->ch->mq) | ||
315 | return; | ||
316 | msize = ntohs (msg->size); | ||
317 | env = GNUNET_MQ_msg_extra (im, | ||
318 | msize, | ||
319 | GNUNET_MESSAGE_TYPE_TRANSPORT_INCOMING_MSG); | ||
320 | if (NULL == env) | ||
321 | { | ||
322 | GNUNET_break (0); | ||
323 | return; | ||
324 | } | ||
325 | im->sender = *sender; | ||
326 | memcpy (&im[1], | ||
327 | msg, | ||
328 | msize); | ||
329 | GNUNET_MQ_send (ai->ch->mq, | ||
330 | env); | ||
331 | } | ||
332 | |||
333 | |||
334 | /* ************************* Discovery *************************** */ | ||
335 | |||
336 | /** | ||
337 | * Handle returned to identify the internal data structure the transport | ||
338 | * API has created to manage a message queue to a particular peer. | ||
339 | */ | ||
340 | struct GNUNET_TRANSPORT_QueueHandle | ||
341 | { | ||
342 | }; | ||
343 | |||
344 | |||
345 | /** | ||
346 | * Notify transport service that an MQ became available due to an | ||
347 | * "inbound" connection or because the communicator discovered the | ||
348 | * presence of another peer. | ||
349 | * | ||
350 | * @param ch connection to transport service | ||
351 | * @param peer peer with which we can now communicate | ||
352 | * @param address address in human-readable format, 0-terminated, UTF-8 | ||
353 | * @param nt which network type does the @a address belong to? | ||
354 | * @param mq message queue of the @a peer | ||
355 | * @return API handle identifying the new MQ | ||
356 | */ | ||
357 | struct GNUNET_TRANSPORT_QueueHandle * | ||
358 | GNUNET_TRANSPORT_communicator_mq_add (struct GNUNET_TRANSPORT_CommunicatorHandle *ch, | ||
359 | const struct GNUNET_PeerIdentity *peer, | ||
360 | const char *address, | ||
361 | enum GNUNET_ATS_Network_Type nt, | ||
362 | struct GNUNET_MQ_Handle *mq) | ||
363 | { | ||
364 | } | ||
365 | |||
366 | |||
367 | /** | ||
368 | * Notify transport service that an MQ became unavailable due to a | ||
369 | * disconnect or timeout. | ||
370 | * | ||
371 | * @param qh handle for the queue that must be invalidated | ||
372 | */ | ||
373 | void | ||
374 | GNUNET_TRANSPORT_communicator_mq_del (struct GNUNET_TRANSPORT_QueueHandle *qh) | ||
375 | { | ||
376 | } | ||
377 | |||
378 | |||
379 | |||
380 | |||
381 | /** | ||
382 | * Notify transport service about an address that this communicator | ||
383 | * provides for this peer. | ||
384 | * | ||
385 | * @param ch connection to transport service | ||
386 | * @param address our address in human-readable format, 0-terminated, UTF-8 | ||
387 | * @param nt which network type does the address belong to? | ||
388 | * @param expiration when does the communicator forsee this address expiring? | ||
389 | */ | ||
390 | struct GNUNET_TRANSPORT_AddressIdentifier * | ||
391 | GNUNET_TRANSPORT_communicator_address_add (struct GNUNET_TRANSPORT_CommunicatorHandle *ch, | ||
392 | const char *address, | ||
393 | enum GNUNET_ATS_Network_Type nt, | ||
394 | struct GNUNET_TIME_Relative expiration) | ||
395 | { | ||
396 | struct GNUNET_TRANSPORT_AddressIdentifier *ai; | ||
397 | |||
398 | ai = GNUNET_new (struct GNUNET_TRANSPORT_AddressIdentifier); | ||
399 | ai->ch = ch; | ||
400 | ai->address = GNUNET_strdup (address); | ||
401 | ai->nt = nt; | ||
402 | ai->expiration = expiration; | ||
403 | ai->aid = handle->aid_gen++; | ||
404 | GNUNET_CONTAINER_DLL_insert (handle->ai_head, | ||
405 | handle->ai_tail, | ||
406 | ai); | ||
407 | send_add_address (ai); | ||
408 | return ai; | ||
409 | } | ||
410 | |||
411 | |||
412 | /** | ||
413 | * Notify transport service about an address that this communicator no | ||
414 | * longer provides for this peer. | ||
415 | * | ||
416 | * @param ai address that is no longer provided | ||
417 | */ | ||
418 | void | ||
419 | GNUNET_TRANSPORT_communicator_address_remove (struct GNUNET_TRANSPORT_AddressIdentifier *ai) | ||
420 | { | ||
421 | struct GNUNET_TRANSPORT_CommunicatorHandle *ch = ai->ch; | ||
422 | |||
423 | send_del_address (ai); | ||
424 | GNUNET_free (ai->address); | ||
425 | GNUNET_CONTAINER_DLL_remove (ch->ai_head, | ||
426 | ch->ai_tail, | ||
427 | ai); | ||
428 | GNUNET_free (ai); | ||
429 | } | ||
430 | |||
431 | |||
432 | /* end of transport_api2_communication.c */ | ||