aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2018-11-01 15:29:10 +0100
committerChristian Grothoff <christian@grothoff.org>2018-11-01 15:29:51 +0100
commit11916b980c6f022ef4be5e34eea2a0abdce68b10 (patch)
treef4245de001e8d697f8c1dfbcddab3e2447e90507 /src
parenteead33d85b73836ae23a2082326cf2ad8bfa2f7f (diff)
downloadgnunet-11916b980c6f022ef4be5e34eea2a0abdce68b10.tar.gz
gnunet-11916b980c6f022ef4be5e34eea2a0abdce68b10.zip
attempting to fix #5464
Diffstat (limited to 'src')
-rw-r--r--src/cadet/.gitignore3
-rw-r--r--src/cadet/gnunet-service-cadet_channel.c7
-rw-r--r--src/transport/transport_api2_communication.c432
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
21test_cadet_single 21test_cadet_single
22gnunet-service-cadet-new 22gnunet-service-cadet-new
23test_cadet_local_mq 23test_cadet_local_mq
24test_cadet_*_new \ No newline at end of file 24test_cadet_*_newtest_cadet_2_reopen
25test_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 */
34struct 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 */
86struct 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 */
134static void
135reconnect (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 */
144static void
145send_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 */
171static void
172send_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 */
190static void
191error_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 */
208static void
209reconnect (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 */
240struct GNUNET_TRANSPORT_CommunicatorHandle *
241GNUNET_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 */
270void
271GNUNET_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 */
303int
304GNUNET_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 */
340struct 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 */
357struct GNUNET_TRANSPORT_QueueHandle *
358GNUNET_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 */
373void
374GNUNET_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 */
390struct GNUNET_TRANSPORT_AddressIdentifier *
391GNUNET_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 */
418void
419GNUNET_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 */