aboutsummaryrefslogtreecommitdiff
path: root/src/transport
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport')
-rw-r--r--src/transport/.gitignore5
-rw-r--r--src/transport/Makefile.am33
-rw-r--r--src/transport/gnunet-communicator-quic.c1796
-rw-r--r--src/transport/gnunet-communicator-tcp.c93
-rw-r--r--src/transport/gnunet-communicator-udp.c1447
-rw-r--r--src/transport/gnunet-service-tng.c126
-rw-r--r--src/transport/meson.build320
-rw-r--r--src/transport/plugin_transport_http_common.c2
-rw-r--r--src/transport/plugin_transport_wlan.c3
-rw-r--r--src/transport/test_communicator_basic.c49
-rw-r--r--src/transport/test_communicator_quic_basic_peer1.conf45
-rw-r--r--src/transport/test_communicator_quic_basic_peer2.conf45
-rw-r--r--src/transport/test_communicator_udp_backchannel_peer1.conf2
-rw-r--r--src/transport/test_communicator_udp_backchannel_peer2.conf2
-rw-r--r--src/transport/test_communicator_udp_basic_peer1.conf3
-rw-r--r--src/transport/test_communicator_udp_basic_peer2.conf2
-rw-r--r--src/transport/test_communicator_udp_rekey_peer1.conf3
-rw-r--r--src/transport/test_communicator_udp_rekey_peer2.conf3
-rw-r--r--src/transport/test_transport_api2.c2
-rw-r--r--src/transport/test_transport_plugin_cmd_nat_upnp.c10
-rw-r--r--src/transport/test_transport_plugin_cmd_simple_send.c8
-rw-r--r--src/transport/test_transport_plugin_cmd_simple_send_broadcast.c17
-rw-r--r--src/transport/test_transport_plugin_cmd_simple_send_dv.c18
-rw-r--r--src/transport/test_transport_plugin_cmd_udp_backchannel.c2
-rw-r--r--src/transport/test_transport_start_with_config.c12
-rw-r--r--src/transport/transport-testing-communicator.c31
-rw-r--r--src/transport/transport-testing-communicator.h10
-rw-r--r--src/transport/transport-testing2.c1
-rw-r--r--src/transport/transport.conf.in4
-rw-r--r--src/transport/transport_api_cmd_backchannel_check.c1
-rw-r--r--src/transport/transport_api_cmd_connecting_peers.c21
-rw-r--r--src/transport/transport_api_cmd_start_peer.c2
32 files changed, 2964 insertions, 1154 deletions
diff --git a/src/transport/.gitignore b/src/transport/.gitignore
index 5a82a787b..163ffbd5d 100644
--- a/src/transport/.gitignore
+++ b/src/transport/.gitignore
@@ -87,7 +87,8 @@ gnunet-communicator-unix
87gnunet-service-tng 87gnunet-service-tng
88gnunet-communicator-tcp 88gnunet-communicator-tcp
89gnunet-communicator-udp 89gnunet-communicator-udp
90test_communicator_unix 90test_communicator_basic-*
91test_communicator_basic_unix 91test_communicator_rekey-*
92test_transport_start_with_config 92test_transport_start_with_config
93test_transport_api2_tcp 93test_transport_api2_tcp
94gnunet-communicator-quic
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am
index 5b51f3edd..d7d25b7b0 100644
--- a/src/transport/Makefile.am
+++ b/src/transport/Makefile.am
@@ -220,7 +220,12 @@ libexec_PROGRAMS = \
220 gnunet-communicator-unix \ 220 gnunet-communicator-unix \
221 gnunet-communicator-udp \ 221 gnunet-communicator-udp \
222 gnunet-communicator-tcp 222 gnunet-communicator-tcp
223 223if HAVE_EXPERIMENTAL
224if HAVE_QUICHE
225libexec_PROGRAMS += \
226 gnunet-communicator-quic
227endif
228endif
224 229
225 230
226bin_PROGRAMS = \ 231bin_PROGRAMS = \
@@ -269,6 +274,22 @@ gnunet_communicator_udp_LDADD = \
269 $(top_builddir)/src/util/libgnunetutil.la \ 274 $(top_builddir)/src/util/libgnunetutil.la \
270 $(LIBGCRYPT_LIBS) 275 $(LIBGCRYPT_LIBS)
271 276
277if HAVE_EXPERIMENTAL
278if HAVE_QUICHE
279gnunet_communicator_quic_SOURCES = \
280 gnunet-communicator-quic.c
281gnunet_communicator_quic_LDADD = \
282 libgnunettransportapplication.la \
283 libgnunettransportcommunicator.la \
284 $(top_builddir)/src/peerstore/libgnunetpeerstore.la \
285 $(top_builddir)/src/nat/libgnunetnatnew.la \
286 $(top_builddir)/src/nt/libgnunetnt.la \
287 $(top_builddir)/src/statistics/libgnunetstatistics.la \
288 $(top_builddir)/src/util/libgnunetutil.la \
289 -lquiche \
290 $(LIBGCRYPT_LIBS)
291endif
292endif
272 293
273gnunet_helper_transport_wlan_SOURCES = \ 294gnunet_helper_transport_wlan_SOURCES = \
274 gnunet-helper-transport-wlan.c 295 gnunet-helper-transport-wlan.c
@@ -690,6 +711,7 @@ check_PROGRAMS += \
690 test_communicator_basic-unix \ 711 test_communicator_basic-unix \
691 test_communicator_basic-tcp \ 712 test_communicator_basic-tcp \
692 test_communicator_basic-udp \ 713 test_communicator_basic-udp \
714 test_communicator_basic-quic \
693 test_communicator_rekey-tcp \ 715 test_communicator_rekey-tcp \
694 test_communicator_rekey-udp \ 716 test_communicator_rekey-udp \
695 test_communicator_backchannel-udp \ 717 test_communicator_backchannel-udp \
@@ -768,6 +790,7 @@ TESTS += \
768 test_quota_compliance_udp \ 790 test_quota_compliance_udp \
769 test_communicator_basic-unix \ 791 test_communicator_basic-unix \
770 test_communicator_basic-tcp \ 792 test_communicator_basic-tcp \
793 test_communicator_basic-quic \
771 test_communicator_basic-udp \ 794 test_communicator_basic-udp \
772 test_communicator_rekey-tcp \ 795 test_communicator_rekey-tcp \
773 test_communicator_rekey-udp \ 796 test_communicator_rekey-udp \
@@ -934,6 +957,14 @@ test_communicator_basic_udp_LDADD = \
934 $(top_builddir)/src/util/libgnunetutil.la \ 957 $(top_builddir)/src/util/libgnunetutil.la \
935 $(top_builddir)/src/statistics/libgnunetstatistics.la 958 $(top_builddir)/src/statistics/libgnunetstatistics.la
936 959
960test_communicator_basic_quic_SOURCES = \
961 test_communicator_basic.c
962test_communicator_basic_quic_LDADD = \
963 libgnunettransporttesting2.la \
964 $(top_builddir)/src/testing/libgnunettesting.la \
965 $(top_builddir)/src/util/libgnunetutil.la \
966 $(top_builddir)/src/statistics/libgnunetstatistics.la
967
937test_communicator_rekey_tcp_SOURCES = \ 968test_communicator_rekey_tcp_SOURCES = \
938 test_communicator_basic.c 969 test_communicator_basic.c
939test_communicator_rekey_tcp_LDADD = \ 970test_communicator_rekey_tcp_LDADD = \
diff --git a/src/transport/gnunet-communicator-quic.c b/src/transport/gnunet-communicator-quic.c
new file mode 100644
index 000000000..1225a3817
--- /dev/null
+++ b/src/transport/gnunet-communicator-quic.c
@@ -0,0 +1,1796 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2010-2014, 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/**
22 * @file transport/gnunet-communicator-quic.c
23 * @brief Transport plugin using QUIC.
24 * @author Marshall Stone
25 * @author Martin Schanzenbach
26 *
27 * TODO:
28 * - Automatically generate self-signed x509 certificates and load from config
29 * - Figure out MTU and how we have to handle fragmentation in Quiche.
30 * - Mandate timeouts
31 * - Setup stats handler properly
32 * - Doxygen documentation of methods
33 * - Refactor code shared with UDP and TCP communicator
34 * - Performance testing
35 * - Check for memory leaks with coverity/valgrind
36 */
37#include "gnunet_common.h"
38#include "gnunet_util_lib.h"
39#include "gnunet_core_service.h"
40#include "quiche.h"
41#include "platform.h"
42#include "gnunet_protocols.h"
43#include "gnunet_signatures.h"
44#include "gnunet_constants.h"
45#include "gnunet_statistics_service.h"
46#include "gnunet_transport_application_service.h"
47#include "gnunet_transport_communication_service.h"
48#include "gnunet_nt_lib.h"
49#include "gnunet_nat_service.h"
50#include "stdint.h"
51#include "inttypes.h"
52
53#define COMMUNICATOR_CONFIG_SECTION "communicator-quic"
54#define COMMUNICATOR_ADDRESS_PREFIX "quic"
55#define MAX_DATAGRAM_SIZE 1350
56
57
58/* FIXME: Review all static lengths/contents below. Maybe this can be done smarter */
59/* Currently equivalent to QUICHE_MAX_CONN_ID_LEN */
60#define LOCAL_CONN_ID_LEN 20
61#define MAX_TOKEN_LEN \
62 sizeof("quiche") - 1 \
63 + sizeof(struct sockaddr_storage) \
64 + QUICHE_MAX_CONN_ID_LEN
65#define CID_LEN sizeof(uint8_t) * QUICHE_MAX_CONN_ID_LEN
66#define TOKEN_LEN sizeof (uint8_t) * MAX_TOKEN_LEN
67
68
69/* FIXME: Why 4?
70 Generic, bidirectional, client-initiated quic stream id */
71#define STREAMID_BI 4
72
73/**
74 * How long do we believe our addresses to remain up (before
75 * the other peer should revalidate).
76 */
77#define ADDRESS_VALIDITY_PERIOD GNUNET_TIME_UNIT_HOURS
78
79/**
80 * Map of DCID (uint8_t) -> quic_conn for quickly retrieving connections to other peers.
81 */
82struct GNUNET_CONTAINER_MultiHashMap *conn_map;
83
84/**
85 * Map of sockaddr -> struct PeerAddress
86 */
87struct GNUNET_CONTAINER_MultiHashMap *addr_map;
88
89/**
90 * Handle to the config
91 */
92static const struct GNUNET_CONFIGURATION_Handle *cfg;
93
94/**
95 * FIXME undocumented
96 */
97static struct GNUNET_TIME_Relative rekey_interval;
98
99/**
100 * FIXME undocumented
101 */
102static struct GNUNET_NETWORK_Handle *udp_sock;
103
104/**
105 * FIXME undocumented
106 */
107static struct GNUNET_SCHEDULER_Task *read_task;
108
109/**
110 * FIXME undocumented
111 */
112static struct GNUNET_TRANSPORT_CommunicatorHandle *ch;
113
114/**
115 * FIXME undocumented
116 */
117static struct GNUNET_TRANSPORT_ApplicationHandle *ah;
118
119/**
120 * FIXME undocumented
121 */
122static int have_v6_socket;
123
124/**
125 * FIXME undocumented
126 */
127static uint16_t my_port;
128
129/**
130 * FIXME undocumented
131 */
132static unsigned long long rekey_max_bytes;
133
134/**
135 * FIXME undocumented
136 */
137static quiche_config *config = NULL;
138
139/**
140 * Our peer identity
141*/
142struct GNUNET_PeerIdentity my_identity;
143
144/**
145 * Our private key.
146 */
147static struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key;
148
149/**
150 * Connection to NAT service.
151 */
152static struct GNUNET_NAT_Handle *nat;
153
154/**
155 * Information we track per peer we have recently been in contact with.
156 *
157 * (Since quiche handles crypto, handshakes, etc. we don't differentiate
158 * between SenderAddress and ReceiverAddress)
159 * FIXME: But we do a handshake as well. The flag in this struct seems to
160 * indicate this. Update comment!
161 */
162struct PeerAddress
163{
164 /**
165 * To whom are we talking to.
166 */
167 struct GNUNET_PeerIdentity target;
168
169 /**
170 * Flag to indicate whether we know the PeerIdentity (target) yet
171 */
172 int id_rcvd;
173
174 /**
175 * Flag to indicate whether we have sent OUR PeerIdentity to this peer
176 */
177 int id_sent;
178
179 /**
180 * Flag to indicate if we are the initiator of the connection
181 */
182 int is_receiver;
183
184 /**
185 * Address of the receiver in the human-readable format
186 * with the #COMMUNICATOR_ADDRESS_PREFIX.
187 */
188 char *foreign_addr;
189
190 /**
191 * Address of the other peer.
192 */
193 struct sockaddr *address;
194
195 /**
196 * Length of the address.
197 */
198 socklen_t address_len;
199
200 /**
201 * The QUIC connection associated with this peer
202 */
203 struct quic_conn *conn;
204
205 /**
206 * Default message queue we are providing for the #ch.
207 */
208 struct GNUNET_MQ_Handle *d_mq;
209
210 /**
211 * handle for default queue with the #ch.
212 */
213 struct GNUNET_TRANSPORT_QueueHandle *d_qh;
214
215 /**
216 * Timeout for this peer address.
217 */
218 struct GNUNET_TIME_Absolute timeout;
219
220 /**
221 * MTU we allowed transport for this peer's default queue.
222 * FIXME: MTU from quiche
223 */
224 size_t d_mtu;
225
226 /**
227 * Which network type does this queue use?
228 */
229 enum GNUNET_NetworkType nt;
230
231 /**
232 * receiver_destroy already called on receiver.
233 */
234 int peer_destroy_called;
235
236 /**
237 * FIXME implementation missing
238 * Entry in sender expiration heap.
239 */
240 // struct GNUNET_CONTAINER_HeapNode *hn;
241};
242
243// /**
244// * FIXME: Implementation missing
245// * Expiration heap for peers (contains `struct PeerAddress`)
246// */
247// static struct GNUNET_CONTAINER_Heap *peers_heap;
248
249/**
250 * ID of timeout task
251 */
252static struct GNUNET_SCHEDULER_Task *timeout_task;
253
254/**
255 * Network scanner to determine network types.
256 */
257static struct GNUNET_NT_InterfaceScanner *is;
258
259/**
260 * For logging statistics.
261 */
262static struct GNUNET_STATISTICS_Handle *stats;
263
264/**
265 * QUIC connection object. A connection has a unique SCID/DCID pair. Here we store our SCID
266 * (incoming packet DCID field == outgoing packet SCID field) for a given connection. This
267 * is hashed for each unique quic_conn.
268*/
269struct quic_conn
270{
271 uint8_t cid[LOCAL_CONN_ID_LEN];
272
273 quiche_conn *conn;
274};
275
276/**
277 * QUIC_header is used to store information received from an incoming QUIC packet
278*/
279struct QUIC_header
280{
281 uint8_t type;
282 uint32_t version;
283
284 uint8_t scid[QUICHE_MAX_CONN_ID_LEN];
285 size_t scid_len;
286
287 uint8_t dcid[QUICHE_MAX_CONN_ID_LEN];
288 size_t dcid_len;
289
290 uint8_t odcid[QUICHE_MAX_CONN_ID_LEN];
291 size_t odcid_len;
292
293 uint8_t token[MAX_TOKEN_LEN];
294 size_t token_len;
295};
296
297
298/**
299 * Given a PeerAddress, receive data from streams after doing connection logic.
300 * ASSUMES: connection is established to peer
301*/
302static void
303recv_from_streams (struct PeerAddress *peer)
304{
305 char stream_buf[UINT16_MAX];
306 size_t buf_size = UINT16_MAX;
307 char *buf_ptr = stream_buf;
308 struct GNUNET_MessageHeader *hdr;
309
310 uint64_t s = 0;
311 quiche_stream_iter *readable;
312 bool fin;
313 ssize_t recv_len;
314
315 readable = quiche_conn_readable (peer->conn->conn);
316 while (quiche_stream_iter_next (readable, &s))
317 {
318 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "stream %" PRIu64 " is readable\n",
319 s);
320 fin = false;
321 recv_len = quiche_conn_stream_recv (peer->conn->conn, s,
322 (uint8_t *) stream_buf, buf_size,
323 &fin);
324 if (recv_len < 0)
325 {
326 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
327 "error while receiving data from stream %" PRIu64 "\n", s);
328 break;
329 }
330 /**
331 * FIXME: Do not use implicit booleans. Use GNUNET_YES, GNUNET_NO, GNUNET_SYSERR
332 * and check for that.
333 *
334 * Initial packet should contain peerid if they are the initiator
335 */
336 if (! peer->is_receiver && GNUNET_NO == peer->id_rcvd)
337 {
338 if (recv_len < sizeof(struct GNUNET_PeerIdentity))
339 {
340 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
341 "message recv len of %zd less than length of peer identity\n",
342 recv_len);
343 return;
344 }
345 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
346 "received peer identity\n");
347 struct GNUNET_PeerIdentity *pid = (struct
348 GNUNET_PeerIdentity *) stream_buf;
349 peer->target = *pid;
350 peer->id_rcvd = GNUNET_YES;
351 buf_ptr += sizeof(struct GNUNET_PeerIdentity);
352 recv_len -= sizeof(struct GNUNET_PeerIdentity);
353 }
354 /**
355 * Parse messages to pass to communicator
356 */
357 while (recv_len >= sizeof(struct GNUNET_MessageHeader))
358 {
359 hdr = (struct GNUNET_MessageHeader *) buf_ptr;
360 if (ntohs (hdr->size) > recv_len)
361 {
362 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
363 "message size stated (%d) is greater than length of rcvd data (%zd)!\n",
364 ntohs (hdr->size), recv_len);
365 return;
366 }
367 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "passing %zd bytes to core\n",
368 recv_len);
369 GNUNET_TRANSPORT_communicator_receive (ch, &peer->target, hdr,
370 ADDRESS_VALIDITY_PERIOD, NULL,
371 NULL);
372 recv_len -= ntohs (hdr->size);
373 buf_ptr += ntohs (hdr->size);
374 }
375 /**
376 * Check for leftover bytes
377 */
378 if (0 != recv_len)
379 {
380 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
381 "message recv len of %zd less than length of message header\n",
382 recv_len);
383 }
384 /**
385 * FIXME: comment useless
386 * fin
387 */
388 if (fin)
389 {
390 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
391 "fin received, closing connection\n");
392 if (0 > quiche_conn_close (peer->conn->conn, true, 0, NULL, 0))
393 {
394 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
395 "quiche failed to close connection to peer\n");
396 }
397 }
398 }
399 quiche_stream_iter_free (readable);
400}
401
402
403/**
404 * FIXME: review token generation, assure tokens are generated properly. doxygen
405 */
406static void
407mint_token (const uint8_t *dcid, size_t dcid_len,
408 struct sockaddr_storage *addr, socklen_t addr_len,
409 uint8_t *token, size_t *token_len)
410{
411 GNUNET_memcpy (token, "quiche", sizeof("quiche") - 1);
412 GNUNET_memcpy (token + sizeof("quiche") - 1, addr, addr_len);
413 GNUNET_memcpy (token + sizeof("quiche") - 1 + addr_len, dcid, dcid_len);
414
415 *token_len = sizeof("quiche") - 1 + addr_len + dcid_len;
416}
417
418
419static enum GNUNET_GenericReturnValue
420validate_token (const uint8_t *token, size_t token_len,
421 struct sockaddr_storage *addr, socklen_t addr_len,
422 uint8_t *odcid, size_t *odcid_len)
423{
424 if ((token_len < sizeof("quiche") - 1) ||
425 memcmp (token, "quiche", sizeof("quiche") - 1))
426 {
427 return GNUNET_NO;
428 }
429
430 token += sizeof("quiche") - 1;
431 token_len -= sizeof("quiche") - 1;
432
433 if ((token_len < addr_len) || memcmp (token, addr, addr_len))
434 {
435 return GNUNET_NO;
436 }
437
438 token += addr_len;
439 token_len -= addr_len;
440
441 if (*odcid_len < token_len)
442 {
443 return GNUNET_NO;
444 }
445
446 memcpy (odcid, token, token_len);
447 *odcid_len = token_len;
448
449 return GNUNET_OK;
450}
451
452
453static struct quic_conn*
454create_conn (uint8_t *scid, size_t scid_len,
455 uint8_t *odcid, size_t odcid_len,
456 struct sockaddr *local_addr,
457 socklen_t local_addr_len,
458 struct sockaddr_storage *peer_addr,
459 socklen_t peer_addr_len)
460{
461 struct quic_conn *conn;
462 quiche_conn *q_conn;
463 conn = GNUNET_new (struct quic_conn);
464 if (scid_len != LOCAL_CONN_ID_LEN)
465 {
466 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
467 "error while creating connection, scid length too short: %zu\n",
468 scid_len);
469 return NULL;
470 }
471
472 GNUNET_memcpy (conn->cid, scid, LOCAL_CONN_ID_LEN);
473 q_conn = quiche_accept (conn->cid, LOCAL_CONN_ID_LEN,
474 odcid, odcid_len,
475 local_addr,
476 local_addr_len,
477 (struct sockaddr *) peer_addr,
478 peer_addr_len,
479 config);
480 if (NULL == q_conn)
481 {
482 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
483 "quiche failed to create connection after call to quiche_accept\n");
484 return NULL;
485 }
486 conn->conn = q_conn;
487 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "new quic connection created\n");
488 return conn;
489}
490
491
492static void
493flush_egress (struct quic_conn *conn)
494{
495 static uint8_t out[MAX_DATAGRAM_SIZE];
496 quiche_send_info send_info;
497
498 ssize_t written;
499 ssize_t sent;
500
501 while (1)
502 {
503 written = quiche_conn_send (conn->conn, out, sizeof(out), &send_info);
504 if (QUICHE_ERR_DONE == written)
505 {
506 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "done writing quic packets\n");
507 break;
508 }
509 if (0 > written)
510 {
511 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
512 "quiche failed to create packet. quiche error: %zd\n",
513 written);
514 return;
515 }
516 sent = GNUNET_NETWORK_socket_sendto (udp_sock, out, written,
517 (struct sockaddr *) &send_info.to,
518 send_info.to_len);
519 if (sent != written)
520 {
521 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
522 "quiche failed to send data to peer\n");
523 return;
524 }
525 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "sent %zd bytes\n", sent);
526 }
527}
528
529
530/**
531 * Increment receiver timeout due to activity.
532 *
533 * @param receiver address for which the timeout should be rescheduled
534 */
535static void
536reschedule_peer_timeout (struct PeerAddress *peer)
537{
538 peer->timeout =
539 GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
540 // GNUNET_CONTAINER_heap_update_cost (peer->hn,
541 // peer->timeout.abs_value_us);
542}
543
544
545/**
546 * Destroys a receiving state due to timeout or shutdown.
547 *
548 * @param receiver entity to close down
549 */
550static void
551peer_destroy (struct PeerAddress *peer)
552{
553 struct GNUNET_HashCode addr_key;
554
555 peer->peer_destroy_called = GNUNET_YES;
556 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
557 "Disconnecting peer for peer `%s'\n",
558 GNUNET_i2s (&peer->target));
559 if (NULL != peer->d_qh)
560 {
561 GNUNET_TRANSPORT_communicator_mq_del (peer->d_qh);
562 peer->d_qh = NULL;
563 }
564 // GNUNET_assert (peer == GNUNET_CONTAINER_heap_remove_node (peer->hn));
565 /**
566 * Remove peer from hashmap
567 */
568 GNUNET_CRYPTO_hash (peer->address, peer->address_len, &addr_key);
569 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_remove (addr_map, &addr_key,
570 peer))
571 {
572 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
573 "tried to remove non-existent peer from addr map\n");
574 return;
575 }
576 GNUNET_STATISTICS_set (stats,
577 "# peers active",
578 GNUNET_CONTAINER_multihashmap_size (addr_map),
579 GNUNET_NO);
580 quiche_conn_free (peer->conn->conn);
581 GNUNET_free (peer->address);
582 GNUNET_free (peer->foreign_addr);
583 GNUNET_free (peer->conn);
584 GNUNET_free (peer);
585}
586
587
588/**
589 * Iterator over all peers to clean up.
590 *
591 * @param cls NULL
592 * @param key peer->address
593 * @param value the peer to destroy
594 * @return #GNUNET_OK to continue to iterate
595 */
596static int
597get_peer_delete_it (void *cls,
598 const struct GNUNET_HashCode *key,
599 void *value)
600{
601 struct PeerAddress *peer = value;
602 (void) cls;
603 (void) key;
604 peer_destroy (peer);
605 return GNUNET_OK;
606}
607
608
609/**
610 * Signature of functions implementing the sending functionality of a
611 * message queue.
612 *
613 * @param mq the message queue
614 * @param msg the message to send
615 * @param impl_state our `struct PeerAddress`
616 */
617static void
618mq_send_d (struct GNUNET_MQ_Handle *mq,
619 const struct GNUNET_MessageHeader *msg,
620 void *impl_state)
621{
622 struct PeerAddress *peer = impl_state;
623 uint16_t msize = ntohs (msg->size);
624 ssize_t send_len;
625
626 if (NULL == peer->conn->conn)
627 {
628 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
629 "peer never established quic connection\n");
630 return;
631 }
632
633 GNUNET_assert (mq == peer->d_mq);
634 if (msize > peer->d_mtu)
635 {
636 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
637 "msize: %u, mtu: %lu\n",
638 msize,
639 peer->d_mtu);
640 GNUNET_break (0);
641 if (GNUNET_YES != peer->peer_destroy_called)
642 {
643 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
644 "peer destroy called, destroying peer\n");
645 peer_destroy (peer);
646 }
647 return;
648 }
649 reschedule_peer_timeout (peer);
650
651 send_len = quiche_conn_stream_send (peer->conn->conn, 4, (uint8_t *) msg,
652 msize, false);
653 if (send_len != msize)
654 {
655 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
656 "tried to send message and quiche returned %zd", send_len);
657 return;
658 }
659 flush_egress (peer->conn);
660 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
661 "sent a message of %zd bytes\n", send_len);
662 GNUNET_MQ_impl_send_continue (mq);
663}
664
665
666/**
667 * Signature of functions implementing the destruction of a message
668 * queue. Implementations must not free @a mq, but should take care
669 * of @a impl_state.
670 *
671 * @param mq the message queue to destroy
672 * @param impl_state our `struct PeerAddress`
673 */
674static void
675mq_destroy_d (struct GNUNET_MQ_Handle *mq, void *impl_state)
676{
677 struct PeerAddress *peer = impl_state;
678 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
679 "Default MQ destroyed\n");
680 if (mq == peer->d_mq)
681 {
682 peer->d_mq = NULL;
683 if (GNUNET_YES != peer->peer_destroy_called)
684 peer_destroy (peer);
685 }
686}
687
688
689/**
690 * Implementation function that cancels the currently sent message.
691 *
692 * @param mq message queue
693 * @param impl_state our `struct PeerAddress`
694 */
695static void
696mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state)
697{
698 /* Cancellation is impossible with QUIC; bail */
699 GNUNET_assert (0);
700}
701
702
703/**
704 * Generic error handler, called with the appropriate
705 * error code and the same closure specified at the creation of
706 * the message queue.
707 * Not every message queue implementation supports an error handler.
708 *
709 * @param cls our `struct ReceiverAddress`
710 * @param error error code
711 */
712static void
713mq_error (void *cls, enum GNUNET_MQ_Error error)
714{
715 struct PeerAddress *peer = cls;
716
717 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
718 "MQ error in queue to %s: %d\n",
719 GNUNET_i2s (&peer->target),
720 (int) error);
721 peer_destroy (peer);
722}
723
724
725/**
726 * Convert UDP bind specification to a `struct sockaddr *`
727 *
728 * @param bindto bind specification to convert
729 * @param[out] sock_len set to the length of the address
730 * @return converted bindto specification
731 */
732static struct sockaddr *
733udp_address_to_sockaddr (const char *bindto, socklen_t *sock_len)
734{
735 struct sockaddr *in;
736 unsigned int port;
737 char dummy[2];
738 char *colon;
739 char *cp;
740
741 if (1 == sscanf (bindto, "%u%1s", &port, dummy))
742 {
743 /* interpreting value as just a PORT number */
744 if (port > UINT16_MAX)
745 {
746 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
747 "BINDTO specification `%s' invalid: value too large for port\n",
748 bindto);
749 return NULL;
750 }
751 if ((GNUNET_NO == GNUNET_NETWORK_test_pf (PF_INET6)) ||
752 (GNUNET_YES ==
753 GNUNET_CONFIGURATION_get_value_yesno (cfg,
754 COMMUNICATOR_CONFIG_SECTION,
755 "DISABLE_V6")))
756 {
757 struct sockaddr_in *i4;
758
759 i4 = GNUNET_malloc (sizeof(struct sockaddr_in));
760 i4->sin_family = AF_INET;
761 i4->sin_port = htons ((uint16_t) port);
762 *sock_len = sizeof(struct sockaddr_in);
763 in = (struct sockaddr *) i4;
764 }
765 else
766 {
767 struct sockaddr_in6 *i6;
768
769 i6 = GNUNET_malloc (sizeof(struct sockaddr_in6));
770 i6->sin6_family = AF_INET6;
771 i6->sin6_port = htons ((uint16_t) port);
772 *sock_len = sizeof(struct sockaddr_in6);
773 in = (struct sockaddr *) i6;
774 }
775 return in;
776 }
777 cp = GNUNET_strdup (bindto);
778 colon = strrchr (cp, ':');
779 if (NULL != colon)
780 {
781 /* interpret value after colon as port */
782 *colon = '\0';
783 colon++;
784 if (1 == sscanf (colon, "%u%1s", &port, dummy))
785 {
786 /* interpreting value as just a PORT number */
787 if (port > UINT16_MAX)
788 {
789 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
790 "BINDTO specification `%s' invalid: value too large for port\n",
791 bindto);
792 GNUNET_free (cp);
793 return NULL;
794 }
795 }
796 else
797 {
798 GNUNET_log (
799 GNUNET_ERROR_TYPE_ERROR,
800 "BINDTO specification `%s' invalid: last ':' not followed by number\n",
801 bindto);
802 GNUNET_free (cp);
803 return NULL;
804 }
805 }
806 else
807 {
808 /* interpret missing port as 0, aka pick any free one */
809 port = 0;
810 }
811 {
812 /* try IPv4 */
813 struct sockaddr_in v4;
814
815 memset (&v4, 0, sizeof(v4));
816 if (1 == inet_pton (AF_INET, cp, &v4.sin_addr))
817 {
818 v4.sin_family = AF_INET;
819 v4.sin_port = htons ((uint16_t) port);
820#if HAVE_SOCKADDR_IN_SIN_LEN
821 v4.sin_len = sizeof(struct sockaddr_in);
822#endif
823 in = GNUNET_memdup (&v4, sizeof(struct sockaddr_in));
824 *sock_len = sizeof(struct sockaddr_in);
825 GNUNET_free (cp);
826 return in;
827 }
828 }
829 {
830 /* try IPv6 */
831 struct sockaddr_in6 v6;
832 const char *start;
833
834 memset (&v6, 0, sizeof(v6));
835 start = cp;
836 if (('[' == *cp) && (']' == cp[strlen (cp) - 1]))
837 {
838 start++; /* skip over '[' */
839 cp[strlen (cp) - 1] = '\0'; /* eat ']' */
840 }
841 if (1 == inet_pton (AF_INET6, start, &v6.sin6_addr))
842 {
843 v6.sin6_family = AF_INET6;
844 v6.sin6_port = htons ((uint16_t) port);
845#if HAVE_SOCKADDR_IN_SIN_LEN
846 v6.sin6_len = sizeof(sizeof(struct sockaddr_in6));
847#endif
848 in = GNUNET_memdup (&v6, sizeof(v6));
849 *sock_len = sizeof(v6);
850 GNUNET_free (cp);
851 return in;
852 }
853 }
854 /* #5528 FIXME (feature!): maybe also try getnameinfo()? */
855 GNUNET_free (cp);
856 return NULL;
857}
858
859
860/**
861 * Setup the MQ for the @a peer. If a queue exists,
862 * the existing one is destroyed. Then the MTU is
863 * recalculated and a fresh queue is initialized.
864 *
865 * @param peer peer to setup MQ for
866 */
867static void
868setup_peer_mq (struct PeerAddress *peer)
869{
870 size_t base_mtu;
871
872 switch (peer->address->sa_family)
873 {
874 case AF_INET:
875 base_mtu = 1480 /* Ethernet MTU, 1500 - Ethernet header - VLAN tag */
876 - sizeof(struct GNUNET_TUN_IPv4Header) /* 20 */
877 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
878 break;
879
880 case AF_INET6:
881 base_mtu = 1280 /* Minimum MTU required by IPv6 */
882 - sizeof(struct GNUNET_TUN_IPv6Header) /* 40 */
883 - sizeof(struct GNUNET_TUN_UdpHeader) /* 8 */;
884 break;
885
886 default:
887 GNUNET_assert (0);
888 break;
889 }
890 /* MTU == base_mtu */
891 peer->d_mtu = base_mtu;
892
893 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
894 "Setting up MQs and QHs\n");
895 /* => Effective MTU for CORE will range from 1080 (IPv6 + KX) to
896 1404 (IPv4 + Box) bytes, depending on circumstances... */
897
898 if (NULL == peer->d_mq)
899 peer->d_mq = GNUNET_MQ_queue_for_callbacks (&mq_send_d,
900 &mq_destroy_d,
901 &mq_cancel,
902 peer,
903 NULL,
904 &mq_error,
905 peer);
906 peer->d_qh =
907 GNUNET_TRANSPORT_communicator_mq_add (ch,
908 &peer->target,
909 peer->foreign_addr,
910 1000,
911 GNUNET_TRANSPORT_QUEUE_LENGTH_UNLIMITED,
912 0, /* Priority */
913 peer->nt,
914 GNUNET_TRANSPORT_CS_OUTBOUND,
915 peer->d_mq);
916}
917
918
919/**
920 * Taken from: UDP communicator
921 * Converts @a address to the address string format used by this
922 * communicator in HELLOs.
923 *
924 * @param address the address to convert, must be AF_INET or AF_INET6.
925 * @param address_len number of bytes in @a address
926 * @return string representation of @a address
927 */
928static char *
929sockaddr_to_udpaddr_string (const struct sockaddr *address,
930 socklen_t address_len)
931{
932 char *ret;
933
934 switch (address->sa_family)
935 {
936 case AF_INET:
937 GNUNET_asprintf (&ret,
938 "%s-%s",
939 COMMUNICATOR_ADDRESS_PREFIX,
940 GNUNET_a2s (address, address_len));
941 break;
942
943 case AF_INET6:
944 GNUNET_asprintf (&ret,
945 "%s-%s",
946 COMMUNICATOR_ADDRESS_PREFIX,
947 GNUNET_a2s (address, address_len));
948 break;
949
950 default:
951 GNUNET_assert (0);
952 }
953 return ret;
954}
955
956
957/**
958 * Function called when the transport service has received a
959 * backchannel message for this communicator (!) via a different return
960 * path. Should be an acknowledgement.
961 *
962 * @param cls closure, NULL
963 * @param sender which peer sent the notification
964 * @param msg payload
965 */
966static void
967notify_cb (void *cls,
968 const struct GNUNET_PeerIdentity *sender,
969 const struct GNUNET_MessageHeader *msg)
970{
971 // const struct UDPAck *ack;
972
973 // (void) cls;
974 // GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
975 // "Storing UDPAck received from backchannel from %s\n",
976 // GNUNET_i2s_full (sender));
977 // if ((ntohs (msg->type) != GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK) ||
978 // (ntohs (msg->size) != sizeof(struct UDPAck)))
979 // {
980 // GNUNET_break_op (0);
981 // return;
982 // }
983 // ack = (const struct UDPAck *) msg;
984 // GNUNET_CONTAINER_multipeermap_get_multiple (receivers,
985 // sender,
986 // &handle_ack,
987 // (void *) ack);
988}
989
990
991/**
992 * Task run to check #receiver_heap and #sender_heap for timeouts.
993 *
994 * @param cls unused, NULL
995 */
996static void
997check_timeouts (void *cls)
998{
999 // struct GNUNET_TIME_Relative st;
1000 // struct GNUNET_TIME_Relative rt;
1001 // struct GNUNET_TIME_Relative delay;
1002 // struct ReceiverAddress *receiver;
1003 // struct SenderAddress *sender;
1004
1005 // (void) cls;
1006 // timeout_task = NULL;
1007 // rt = GNUNET_TIME_UNIT_FOREVER_REL;
1008 // while (NULL != (receiver = GNUNET_CONTAINER_heap_peek (receivers_heap)))
1009 // {
1010 // /* if (GNUNET_YES != receiver->receiver_destroy_called) */
1011 // /* { */
1012 // rt = GNUNET_TIME_absolute_get_remaining (receiver->timeout);
1013 // if (0 != rt.rel_value_us)
1014 // break;
1015 // GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1016 // "Receiver timed out\n");
1017 // receiver_destroy (receiver);
1018 // // }
1019 // }
1020 // st = GNUNET_TIME_UNIT_FOREVER_REL;
1021 // while (NULL != (sender = GNUNET_CONTAINER_heap_peek (senders_heap)))
1022 // {
1023 // if (GNUNET_YES != sender->sender_destroy_called)
1024 // {
1025 // st = GNUNET_TIME_absolute_get_remaining (sender->timeout);
1026 // if (0 != st.rel_value_us)
1027 // break;
1028 // sender_destroy (sender);
1029 // }
1030 // }
1031 // delay = GNUNET_TIME_relative_min (rt, st);
1032 // if (delay.rel_value_us < GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
1033 // timeout_task = GNUNET_SCHEDULER_add_delayed (delay, &check_timeouts, NULL);
1034}
1035
1036
1037/**
1038 * Function called by the transport service to initialize a
1039 * message queue given address information about another peer.
1040 * If and when the communication channel is established, the
1041 * communicator must call #GNUNET_TRANSPORT_communicator_mq_add()
1042 * to notify the service that the channel is now up. It is
1043 * the responsibility of the communicator to manage sane
1044 * retries and timeouts for any @a peer/@a address combination
1045 * provided by the transport service. Timeouts and retries
1046 * do not need to be signalled to the transport service.
1047 *
1048 * @param cls closure
1049 * @param peer identity of the other peer
1050 * @param address where to send the message, human-readable
1051 * communicator-specific format, 0-terminated, UTF-8
1052 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the provided address is
1053 * invalid
1054 */
1055static int
1056mq_init (void *cls, const struct GNUNET_PeerIdentity *peer_id, const
1057 char *address)
1058{
1059 struct PeerAddress *peer;
1060 const char *path;
1061 struct sockaddr *in;
1062 socklen_t in_len;
1063 struct GNUNET_HashCode addr_key;
1064 uint8_t scid[LOCAL_CONN_ID_LEN];
1065
1066 struct quic_conn *q_conn;
1067 char *bindto;
1068 socklen_t local_in_len;
1069 struct sockaddr *local_addr;
1070
1071 if (GNUNET_OK !=
1072 GNUNET_CONFIGURATION_get_value_string (cfg,
1073 COMMUNICATOR_CONFIG_SECTION,
1074 "BINDTO",
1075 &bindto))
1076 {
1077 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
1078 COMMUNICATOR_CONFIG_SECTION,
1079 "BINDTO");
1080 return GNUNET_SYSERR;
1081 }
1082 local_addr = udp_address_to_sockaddr (bindto, &local_in_len);
1083
1084 if (0 != strncmp (address,
1085 COMMUNICATOR_ADDRESS_PREFIX "-",
1086 strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
1087 {
1088 GNUNET_break_op (0);
1089 return GNUNET_SYSERR;
1090 }
1091 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
1092 in = udp_address_to_sockaddr (path, &in_len);
1093 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "mq_init in_len length before: %d\n",
1094 in_len);
1095 /**
1096 * If we already have a queue with this peer, ignore
1097 */
1098 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "address string in mq_init: %s\n",
1099 address);
1100 GNUNET_CRYPTO_hash (address, strlen (address), &addr_key);
1101 peer = GNUNET_CONTAINER_multihashmap_get (addr_map, &addr_key);
1102 if (NULL != peer)
1103 {
1104 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1105 "ignoring transport service mq request, we already have an mq with this peer (address)\n");
1106 return GNUNET_SYSERR;
1107 }
1108 peer = GNUNET_new (struct PeerAddress);
1109 peer->address = in;
1110 peer->address_len = in_len;
1111 peer->target = *peer_id;
1112 peer->id_rcvd = GNUNET_YES;
1113 peer->is_receiver = GNUNET_YES;
1114 peer->nt = GNUNET_NT_scanner_get_type (is, in, in_len);
1115 peer->timeout =
1116 GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
1117 GNUNET_STATISTICS_set (stats,
1118 "# peers active",
1119 GNUNET_CONTAINER_multihashmap_size (addr_map),
1120 GNUNET_NO);
1121 peer->foreign_addr =
1122 sockaddr_to_udpaddr_string (peer->address, peer->address_len);
1123 /**
1124 * Insert peer into hashmap
1125 */
1126 GNUNET_CONTAINER_multihashmap_put (addr_map, &addr_key,
1127 peer,
1128 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
1129 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1130 "mq_init added new peer to the addr map\n");
1131 /**
1132 * Before setting up peer mq, initiate a quic connection to the target (perform handshake w/ quiche)
1133 */
1134 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG, scid,
1135 LOCAL_CONN_ID_LEN);
1136 q_conn = GNUNET_new (struct quic_conn);
1137 GNUNET_memcpy (q_conn->cid, scid, LOCAL_CONN_ID_LEN);
1138 peer->conn = q_conn;
1139 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1140 "attempting to perform QUIC handshake with peer\n");
1141 q_conn->conn = quiche_connect (peer->foreign_addr, scid, LOCAL_CONN_ID_LEN,
1142 local_addr,
1143 local_in_len, peer->address, peer->address_len,
1144 config);
1145 flush_egress (peer->conn);
1146 GNUNET_free (local_addr);
1147 return GNUNET_OK;
1148 /**
1149 * TODO: handle this
1150 */
1151 // if (NULL == timeout_task)
1152 // timeout_task = GNUNET_SCHEDULER_add_now (&check_timeouts, NULL);
1153}
1154
1155
1156static void
1157try_connection_reversal (void *cls,
1158 const struct sockaddr *addr,
1159 socklen_t addrlen)
1160{
1161 /* FIXME: support reversal: #5529 */
1162 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1163 "No connection reversal implemented!");
1164}
1165
1166
1167/**
1168 * Signature of the callback passed to #GNUNET_NAT_register() for
1169 * a function to call whenever our set of 'valid' addresses changes.
1170 *
1171 * @param cls closure
1172 * @param app_ctx[in,out] location where the app can store stuff
1173 * on add and retrieve it on remove
1174 * @param add_remove #GNUNET_YES to add a new public IP address,
1175 * #GNUNET_NO to remove a previous (now invalid) one
1176 * @param ac address class the address belongs to
1177 * @param addr either the previous or the new public IP address
1178 * @param addrlen actual length of the @a addr
1179 */
1180static void
1181nat_address_cb (void *cls,
1182 void **app_ctx,
1183 int add_remove,
1184 enum GNUNET_NAT_AddressClass ac,
1185 const struct sockaddr *addr,
1186 socklen_t addrlen)
1187{
1188 char *my_addr;
1189 struct GNUNET_TRANSPORT_AddressIdentifier *ai;
1190
1191 if (GNUNET_YES == add_remove)
1192 {
1193 enum GNUNET_NetworkType nt;
1194
1195 GNUNET_asprintf (&my_addr,
1196 "%s-%s",
1197 COMMUNICATOR_ADDRESS_PREFIX,
1198 GNUNET_a2s (addr, addrlen));
1199 nt = GNUNET_NT_scanner_get_type (is, addr, addrlen);
1200 ai =
1201 GNUNET_TRANSPORT_communicator_address_add (ch,
1202 my_addr,
1203 nt,
1204 GNUNET_TIME_UNIT_FOREVER_REL);
1205 GNUNET_free (my_addr);
1206 *app_ctx = ai;
1207 }
1208 else
1209 {
1210 ai = *app_ctx;
1211 GNUNET_TRANSPORT_communicator_address_remove (ai);
1212 *app_ctx = NULL;
1213 }
1214}
1215
1216
1217/**
1218 * Shutdown the QUIC communicator.
1219 *
1220 * @param cls NULL (always)
1221 */
1222static void
1223do_shutdown (void *cls)
1224{
1225 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1226 "do_shutdown\n");
1227 GNUNET_CONTAINER_multihashmap_iterate (addr_map, &get_peer_delete_it, NULL);
1228 GNUNET_CONTAINER_multihashmap_destroy (addr_map);
1229 quiche_config_free (config);
1230
1231 if (NULL != timeout_task)
1232 {
1233 GNUNET_SCHEDULER_cancel (timeout_task);
1234 timeout_task = NULL;
1235 }
1236 if (NULL != read_task)
1237 {
1238 GNUNET_SCHEDULER_cancel (read_task);
1239 read_task = NULL;
1240 }
1241 if (NULL != udp_sock)
1242 {
1243 GNUNET_break (GNUNET_OK ==
1244 GNUNET_NETWORK_socket_close (udp_sock));
1245 udp_sock = NULL;
1246 }
1247 if (NULL != ch)
1248 {
1249 GNUNET_TRANSPORT_communicator_disconnect (ch);
1250 ch = NULL;
1251 }
1252 if (NULL != ah)
1253 {
1254 GNUNET_TRANSPORT_application_done (ah);
1255 ah = NULL;
1256 }
1257 if (NULL != my_private_key)
1258 {
1259 GNUNET_free (my_private_key);
1260 my_private_key = NULL;
1261 }
1262 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1263 "do_shutdown finished\n");
1264}
1265
1266
1267static void
1268sock_read (void *cls)
1269{
1270 struct sockaddr_storage sa;
1271 struct sockaddr_in *addr_verify;
1272 socklen_t salen = sizeof(sa);
1273 uint8_t buf[UINT16_MAX];
1274 uint8_t out[MAX_DATAGRAM_SIZE];
1275 ssize_t rcvd;
1276
1277 ssize_t process_pkt;
1278 struct QUIC_header quic_header;
1279 uint8_t new_cid[LOCAL_CONN_ID_LEN];
1280
1281 struct PeerAddress *peer;
1282 struct GNUNET_HashCode addr_key;
1283
1284 (void) cls;
1285 quic_header.scid_len = sizeof(quic_header.scid);
1286 quic_header.dcid_len = sizeof(quic_header.dcid);
1287 quic_header.odcid_len = sizeof(quic_header.odcid);
1288 quic_header.token_len = sizeof(quic_header.token);
1289 /**
1290 * Get local_addr, in_len for quiche
1291 */
1292 char *bindto;
1293 socklen_t in_len;
1294 if (GNUNET_OK !=
1295 GNUNET_CONFIGURATION_get_value_string (cfg,
1296 COMMUNICATOR_CONFIG_SECTION,
1297 "BINDTO",
1298 &bindto))
1299 {
1300 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
1301 COMMUNICATOR_CONFIG_SECTION,
1302 "BINDTO");
1303 return;
1304 }
1305 struct sockaddr *local_addr = udp_address_to_sockaddr (bindto, &in_len);
1306
1307 read_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
1308 udp_sock,
1309 &sock_read,
1310 NULL);
1311 while (1)
1312 {
1313 rcvd = GNUNET_NETWORK_socket_recvfrom (udp_sock,
1314 buf,
1315 sizeof(buf),
1316 (struct sockaddr *) &sa,
1317 &salen);
1318 if (-1 == rcvd)
1319 {
1320 if (EAGAIN == errno)
1321 break; // We are done reading data
1322 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG, "recv");
1323 return;
1324 }
1325
1326 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1327 "Read %lu bytes\n", rcvd);
1328
1329 if (-1 == rcvd)
1330 {
1331 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG, "recv");
1332 return;
1333 }
1334 /**
1335 * FIXME: hashing address string vs ip/port. It is not ideal that
1336 * we hash the string, instead of the binary representation, but
1337 * for now it is certainly less code.
1338 * Note that simply hashing the sockaddr does NOT work because the
1339 * the struct is not portable.
1340 */
1341 const char *addr_string = sockaddr_to_udpaddr_string ((const struct
1342 sockaddr *) &sa,
1343 salen);
1344 GNUNET_CRYPTO_hash (addr_string, strlen (addr_string),
1345 &addr_key);
1346 GNUNET_free (addr_string);
1347 peer = GNUNET_CONTAINER_multihashmap_get (addr_map, &addr_key);
1348
1349 if (NULL == peer)
1350 {
1351 /**
1352 * Create new PeerAddress (receiver) with id_rcvd = false
1353 */
1354 peer = GNUNET_new (struct PeerAddress);
1355 peer->address = GNUNET_memdup (&sa, salen);
1356 peer->address_len = salen;
1357 peer->id_rcvd = GNUNET_NO;
1358 peer->id_sent = GNUNET_NO;
1359 peer->is_receiver = GNUNET_NO;
1360 peer->conn = NULL;
1361 peer->foreign_addr = sockaddr_to_udpaddr_string (peer->address,
1362 peer->address_len);
1363 /**
1364 * TODO: after connection established
1365 */
1366 // setup_peer_mq (peer);
1367 if (GNUNET_SYSERR == GNUNET_CONTAINER_multihashmap_put (addr_map,
1368 &addr_key,
1369 peer,
1370 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
1371 {
1372 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1373 "tried to add duplicate address into address map\n");
1374 return;
1375 }
1376 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1377 "sock_read added new peer to address map\n");
1378 }
1379
1380 /**
1381 * Parse QUIC info
1382 */
1383 int rc = quiche_header_info (buf, rcvd, LOCAL_CONN_ID_LEN,
1384 &quic_header.version,
1385 &quic_header.type, quic_header.scid,
1386 &quic_header.scid_len, quic_header.dcid,
1387 &quic_header.dcid_len,
1388 quic_header.token, &quic_header.token_len);
1389 if (0 > rc)
1390 {
1391 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1392 "failed to parse quic header: %d\n",
1393 rc);
1394 return;
1395 }
1396
1397 /**
1398 * New QUIC connection with peer
1399 */
1400 if (NULL == peer->conn)
1401 {
1402 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1403 "attempting to create new connection\n");
1404 if (0 == quiche_version_is_supported (quic_header.version))
1405 {
1406 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1407 "quic version negotiation initiated\n");
1408 /**
1409 * FIXME variables are redeclared often. Refactor either
1410 * to declare variables once in the beginning or refactor into
1411 * method.
1412 *
1413 * Write a version negotiation packet to "out"
1414 */
1415 ssize_t written = quiche_negotiate_version (quic_header.scid,
1416 quic_header.scid_len,
1417 quic_header.dcid,
1418 quic_header.dcid_len,
1419 out, sizeof(out));
1420 if (0 > written)
1421 {
1422 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1423 "quiche failed to generate version negotiation packet\n");
1424 return;
1425 }
1426 ssize_t sent = GNUNET_NETWORK_socket_sendto (udp_sock,
1427 out,
1428 written,
1429 (struct sockaddr*) &sa,
1430 salen);
1431 if (sent != written)
1432 {
1433 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1434 "failed to send version negotiation packet to peer\n");
1435 return;
1436 }
1437 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1438 "sent %zd bytes to peer during version negotiation\n",
1439 sent);
1440 return;
1441 }
1442
1443 if (0 == quic_header.token_len)
1444 {
1445 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "quic stateless retry\n");
1446 mint_token (quic_header.dcid, quic_header.dcid_len, &sa, salen,
1447 quic_header.token, &quic_header.token_len);
1448
1449 uint8_t new_cid[LOCAL_CONN_ID_LEN];
1450 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG, new_cid,
1451 LOCAL_CONN_ID_LEN);
1452
1453 ssize_t written = quiche_retry (quic_header.scid, quic_header.scid_len,
1454 quic_header.dcid, quic_header.dcid_len,
1455 new_cid, LOCAL_CONN_ID_LEN,
1456 quic_header.token,
1457 quic_header.token_len,
1458 quic_header.version, out, sizeof(out));
1459 if (0 > written)
1460 {
1461 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1462 "quiche failed to write retry packet\n");
1463 return;
1464 }
1465 ssize_t sent = GNUNET_NETWORK_socket_sendto (udp_sock,
1466 out,
1467 written,
1468 (struct sockaddr*) &sa,
1469 salen);
1470 if (written != sent)
1471 {
1472 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "failed to send retry packet\n");
1473 return;
1474 }
1475
1476 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "sent %zd bytes\n", sent);
1477 continue;
1478 }
1479
1480 if (GNUNET_OK != validate_token (quic_header.token, quic_header.token_len,
1481 &sa, salen,
1482 quic_header.odcid,
1483 &quic_header.odcid_len))
1484 {
1485 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1486 "invalid address validation token created\n");
1487 return;
1488 }
1489 peer->conn = create_conn (quic_header.dcid, quic_header.dcid_len,
1490 quic_header.odcid, quic_header.odcid_len,
1491 local_addr, in_len,
1492 &sa, salen);
1493 if (NULL == peer->conn)
1494 {
1495 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1496 "failed to create quic connection with peer\n");
1497 return;
1498 }
1499 } // null connection
1500
1501 quiche_recv_info recv_info = {
1502 (struct sockaddr *) &sa,
1503 salen,
1504
1505 local_addr,
1506 in_len,
1507 };
1508 /**
1509 * Send our PeerIdentity if the connection is established now
1510 */
1511 if (quiche_conn_is_established (peer->conn->conn) && ! peer->id_sent &&
1512 peer->is_receiver)
1513 {
1514 ssize_t send_len;
1515
1516 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1517 "handshake established with peer, sending our peer id\n");
1518 send_len = quiche_conn_stream_send (peer->conn->conn, STREAMID_BI,
1519 (const uint8_t *) &my_identity,
1520 sizeof(my_identity),
1521 false);
1522 if (0 > send_len)
1523 {
1524 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1525 "failed to write peer identity packet. quiche error: %zd\n",
1526 send_len);
1527 return;
1528 }
1529 flush_egress (peer->conn);
1530 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "peer identity sent to peer\n");
1531 peer->id_sent = GNUNET_YES;
1532 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "setting up peer mq\n");
1533 setup_peer_mq (peer);
1534 /**
1535 * After this, we should be all good to send/recv data
1536 */
1537 }
1538 process_pkt = quiche_conn_recv (peer->conn->conn, buf, rcvd, &recv_info);
1539 if (0 > process_pkt)
1540 {
1541 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1542 "quiche failed to process received packet: %zd\n",
1543 process_pkt);
1544 return;
1545 }
1546 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1547 "quiche processed %zd bytes\n", process_pkt);
1548 // Check for data on all available streams if the connection is established
1549 if (GNUNET_YES == quiche_conn_is_established (peer->conn->conn))
1550 {
1551 recv_from_streams (peer);
1552 }
1553 /**
1554 * TODO: Should we use a list instead of hashmap?
1555 * Overhead for hashing function, O(1) retrieval vs O(n) iteration with n=30?
1556 *
1557 * TODO: Is iteration necessary as in the quiche server example?
1558 */
1559 quiche_stats stats;
1560 quiche_path_stats path_stats;
1561
1562 flush_egress (peer->conn);
1563
1564 if (quiche_conn_is_closed (peer->conn->conn))
1565 {
1566 quiche_conn_stats (peer->conn->conn, &stats);
1567 quiche_conn_path_stats (peer->conn->conn, 0, &path_stats);
1568
1569 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1570 "connection closed. quiche stats: sent=%zu, recv=%zu\n",
1571 stats.sent, stats.recv);
1572 peer_destroy (peer);
1573 }
1574 }
1575 GNUNET_free (local_addr);
1576}
1577
1578
1579/**
1580 * Setup communicator and launch network interactions.
1581 *
1582 * @param cls NULL (always)
1583 * @param args remaining command-line arguments
1584 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
1585 * @param c configuration
1586 */
1587static void
1588run (void *cls,
1589 char *const *args,
1590 const char *cfgfile,
1591 const struct GNUNET_CONFIGURATION_Handle *c)
1592{
1593 char *bindto;
1594 struct sockaddr *in;
1595 socklen_t in_len;
1596 struct sockaddr_storage in_sto;
1597 socklen_t sto_len;
1598
1599 (void) cls;
1600 cfg = c;
1601
1602 if (GNUNET_OK !=
1603 GNUNET_CONFIGURATION_get_value_string (cfg,
1604 COMMUNICATOR_CONFIG_SECTION,
1605 "BINDTO",
1606 &bindto))
1607 {
1608 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
1609 COMMUNICATOR_CONFIG_SECTION,
1610 "BINDTO");
1611 return;
1612 }
1613
1614 in = udp_address_to_sockaddr (bindto, &in_len);
1615
1616 if (NULL == in)
1617 {
1618 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1619 "Failed to setup UDP socket address with path `%s'\n",
1620 bindto);
1621 GNUNET_free (bindto);
1622 return;
1623 }
1624 udp_sock =
1625 GNUNET_NETWORK_socket_create (in->sa_family,
1626 SOCK_DGRAM,
1627 IPPROTO_UDP);
1628 if (NULL == udp_sock)
1629 {
1630 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket");
1631 GNUNET_free (in);
1632 GNUNET_free (bindto);
1633 return;
1634 }
1635 if (AF_INET6 == in->sa_family)
1636 have_v6_socket = GNUNET_YES;
1637 if (GNUNET_OK !=
1638 GNUNET_NETWORK_socket_bind (udp_sock,
1639 in,
1640 in_len))
1641 {
1642 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
1643 "bind",
1644 bindto);
1645 GNUNET_NETWORK_socket_close (udp_sock);
1646 udp_sock = NULL;
1647 GNUNET_free (in);
1648 GNUNET_free (bindto);
1649 return;
1650 }
1651 sto_len = sizeof(in_sto);
1652 if (0 != getsockname (GNUNET_NETWORK_get_fd (udp_sock),
1653 (struct sockaddr *) &in_sto,
1654 &sto_len))
1655 {
1656 memcpy (&in_sto, in, in_len);
1657 sto_len = in_len;
1658 }
1659 GNUNET_free (in);
1660 GNUNET_free (bindto);
1661 in = (struct sockaddr *) &in_sto;
1662 in_len = sto_len;
1663 GNUNET_log_from_nocheck (GNUNET_ERROR_TYPE_DEBUG,
1664 "transport",
1665 "Bound to `%s'\n",
1666 GNUNET_a2s ((const struct sockaddr *) &in_sto,
1667 sto_len));
1668 switch (in->sa_family)
1669 {
1670 case AF_INET:
1671 my_port = ntohs (((struct sockaddr_in *) in)->sin_port);
1672 break;
1673
1674 case AF_INET6:
1675 my_port = ntohs (((struct sockaddr_in6 *) in)->sin6_port);
1676 break;
1677
1678 default:
1679 GNUNET_break (0);
1680 my_port = 0;
1681 }
1682 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
1683 /**
1684 * Setup QUICHE configuration
1685 */
1686 config = quiche_config_new (QUICHE_PROTOCOL_VERSION);
1687 quiche_config_verify_peer (config, false);
1688 /**
1689 * TODO: configure TLS cert
1690 */
1691 quiche_config_load_cert_chain_from_pem_file (config, "./cert.crt");
1692 quiche_config_load_priv_key_from_pem_file (config, "./cert.key");
1693 quiche_config_set_application_protos (config,
1694 (uint8_t *)
1695 "\x0ahq-interop\x05hq-29\x05hq-28\x05hq-27\x08http/0.9",
1696 38);
1697 quiche_config_set_max_idle_timeout (config, 5000);
1698 quiche_config_set_max_recv_udp_payload_size (config, 1200);
1699 quiche_config_set_max_send_udp_payload_size (config, 1200);
1700 quiche_config_set_initial_max_data (config, 10000000);
1701 quiche_config_set_initial_max_stream_data_bidi_local (config, 1000000);
1702 quiche_config_set_initial_max_stream_data_bidi_remote (config, 1000000);
1703 quiche_config_set_initial_max_stream_data_uni (config, 1000000);
1704 quiche_config_set_initial_max_streams_bidi (config, 100);
1705 quiche_config_set_initial_max_streams_uni (config, 100);
1706 quiche_config_set_cc_algorithm (config, QUICHE_CC_RENO);
1707 quiche_config_set_disable_active_migration (config, true);
1708 addr_map = GNUNET_CONTAINER_multihashmap_create (2, GNUNET_NO);
1709 /**
1710 * Get our public key for initial packet
1711 */
1712 my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (cfg);
1713 if (NULL == my_private_key)
1714 {
1715 GNUNET_log (
1716 GNUNET_ERROR_TYPE_ERROR,
1717 _ (
1718 "Transport service is lacking key configuration settings. Exiting.\n"));
1719 GNUNET_SCHEDULER_shutdown ();
1720 return;
1721 }
1722 GNUNET_CRYPTO_eddsa_key_get_public (my_private_key, &my_identity.public_key);
1723 /* start reading */
1724 read_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
1725 udp_sock,
1726 &sock_read,
1727 NULL);
1728 ch = GNUNET_TRANSPORT_communicator_connect (cfg,
1729 COMMUNICATOR_CONFIG_SECTION,
1730 COMMUNICATOR_ADDRESS_PREFIX,
1731 GNUNET_TRANSPORT_CC_RELIABLE,
1732 &mq_init,
1733 NULL,
1734 &notify_cb,
1735 NULL);
1736 is = GNUNET_NT_scanner_init ();
1737 nat = GNUNET_NAT_register (cfg,
1738 COMMUNICATOR_CONFIG_SECTION,
1739 IPPROTO_UDP,
1740 1 /* one address */,
1741 (const struct sockaddr **) &in,
1742 &in_len,
1743 &nat_address_cb,
1744 try_connection_reversal,
1745 NULL /* closure */);
1746 if (NULL == ch)
1747 {
1748 GNUNET_break (0);
1749 GNUNET_SCHEDULER_shutdown ();
1750 return;
1751 }
1752 ah = GNUNET_TRANSPORT_application_init (cfg);
1753 if (NULL == ah)
1754 {
1755 GNUNET_break (0);
1756 GNUNET_SCHEDULER_shutdown ();
1757 return;
1758 }
1759
1760 /* start broadcasting */
1761 // if (GNUNET_YES !=
1762 // GNUNET_CONFIGURATION_get_value_yesno (cfg,
1763 // COMMUNICATOR_CONFIG_SECTION,
1764 // "DISABLE_BROADCAST"))
1765 // {
1766 // broadcast_task = GNUNET_SCHEDULER_add_now (&do_broadcast, NULL);
1767 // }
1768}
1769
1770
1771int
1772main (int argc, char *const *argv)
1773{
1774 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
1775 GNUNET_GETOPT_OPTION_END
1776 };
1777 int ret;
1778
1779 GNUNET_log_from_nocheck (GNUNET_ERROR_TYPE_DEBUG,
1780 "transport",
1781 "Starting quic communicator\n");
1782 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
1783 return 2;
1784
1785 ret = (GNUNET_OK == GNUNET_PROGRAM_run (argc,
1786 argv,
1787 "gnunet-communicator-quic",
1788 _ ("GNUnet QUIC communicator"),
1789 options,
1790 &run,
1791 NULL))
1792 ? 0
1793 : 1;
1794 GNUNET_free_nz ((void *) argv);
1795 return ret;
1796}
diff --git a/src/transport/gnunet-communicator-tcp.c b/src/transport/gnunet-communicator-tcp.c
index e2f1e4507..1273465c3 100644
--- a/src/transport/gnunet-communicator-tcp.c
+++ b/src/transport/gnunet-communicator-tcp.c
@@ -82,9 +82,9 @@
82 82
83/** 83/**
84 * How often do we rekey based on number of bytes transmitted? 84 * How often do we rekey based on number of bytes transmitted?
85 * (additionally randomized). 85 * (additionally randomized). Currently 400 MB
86 */ 86 */
87#define REKEY_MAX_BYTES (1024LLU * 1024 * 1024 * 4LLU) 87#define REKEY_MAX_BYTES (1024LLU * 1024 * 400)
88 88
89/** 89/**
90 * Size of the initial key exchange message sent first in both 90 * Size of the initial key exchange message sent first in both
@@ -469,12 +469,6 @@ struct Queue
469 struct GNUNET_HashCode out_hmac; 469 struct GNUNET_HashCode out_hmac;
470 470
471 /** 471 /**
472 * Our ephemeral key. Stored here temporarily during rekeying / key
473 * generation.
474 */
475 struct GNUNET_CRYPTO_EcdhePrivateKey ephemeral;
476
477 /**
478 * ID of read task for this connection. 472 * ID of read task for this connection.
479 */ 473 */
480 struct GNUNET_SCHEDULER_Task *read_task; 474 struct GNUNET_SCHEDULER_Task *read_task;
@@ -667,6 +661,17 @@ struct Queue
667 * Store Context for retrieving the monotonic time send with the handshake ack. 661 * Store Context for retrieving the monotonic time send with the handshake ack.
668 */ 662 */
669 struct GNUNET_PEERSTORE_StoreContext *handshake_ack_monotime_sc; 663 struct GNUNET_PEERSTORE_StoreContext *handshake_ack_monotime_sc;
664
665 /**
666 * Size of data received without KX challenge played back.
667 */
668 // TODO remove?
669 size_t unverified_size;
670
671 /**
672 * Has the initial (core) handshake already happened?
673 */
674 int initial_core_kx_done;
670}; 675};
671 676
672 677
@@ -893,11 +898,6 @@ struct ListenTask *lts_tail;
893 */ 898 */
894int addrs_lens; 899int addrs_lens;
895 900
896/**
897 * Size of data received without KX challenge played back.
898 */
899// TODO remove?
900size_t unverified_size;
901 901
902/** 902/**
903 * Database for peer's HELLOs. 903 * Database for peer's HELLOs.
@@ -1357,10 +1357,10 @@ static void
1357setup_in_cipher (const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral, 1357setup_in_cipher (const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral,
1358 struct Queue *queue) 1358 struct Queue *queue)
1359{ 1359{
1360 struct GNUNET_HashCode dh; 1360 struct GNUNET_HashCode k;
1361 1361
1362 GNUNET_CRYPTO_eddsa_ecdh (my_private_key, ephemeral, &dh); 1362 GNUNET_CRYPTO_eddsa_kem_decaps (my_private_key, ephemeral, &k);
1363 setup_cipher (&dh, &my_identity, &queue->in_cipher, &queue->in_hmac); 1363 setup_cipher (&k, &my_identity, &queue->in_cipher, &queue->in_hmac);
1364} 1364}
1365 1365
1366 1366
@@ -1557,14 +1557,9 @@ send_challenge (struct GNUNET_CRYPTO_ChallengeNonceP challenge,
1557 * @param queue queue to setup outgoing (encryption) cipher for 1557 * @param queue queue to setup outgoing (encryption) cipher for
1558 */ 1558 */
1559static void 1559static void
1560setup_out_cipher (struct Queue *queue) 1560setup_out_cipher (struct Queue *queue, struct GNUNET_HashCode *dh)
1561{ 1561{
1562 struct GNUNET_HashCode dh; 1562 setup_cipher (dh, &queue->target, &queue->out_cipher, &queue->out_hmac);
1563
1564 GNUNET_CRYPTO_ecdh_eddsa (&queue->ephemeral, &queue->target.public_key, &dh);
1565 /* we don't need the private key anymore, drop it! */
1566 memset (&queue->ephemeral, 0, sizeof(queue->ephemeral));
1567 setup_cipher (&dh, &queue->target, &queue->out_cipher, &queue->out_hmac);
1568 queue->rekey_time = GNUNET_TIME_relative_to_absolute (rekey_interval); 1563 queue->rekey_time = GNUNET_TIME_relative_to_absolute (rekey_interval);
1569 queue->rekey_left_bytes = 1564 queue->rekey_left_bytes =
1570 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, REKEY_MAX_BYTES); 1565 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, REKEY_MAX_BYTES);
@@ -1582,13 +1577,14 @@ inject_rekey (struct Queue *queue)
1582{ 1577{
1583 struct TCPRekey rekey; 1578 struct TCPRekey rekey;
1584 struct TcpRekeySignature thp; 1579 struct TcpRekeySignature thp;
1580 struct GNUNET_HashCode k;
1585 1581
1586 GNUNET_assert (0 == queue->pwrite_off); 1582 GNUNET_assert (0 == queue->pwrite_off);
1587 memset (&rekey, 0, sizeof(rekey)); 1583 memset (&rekey, 0, sizeof(rekey));
1588 GNUNET_CRYPTO_ecdhe_key_create (&queue->ephemeral); 1584 GNUNET_CRYPTO_eddsa_kem_encaps (&queue->target.public_key, &rekey.ephemeral,
1585 &k);
1589 rekey.header.type = ntohs (GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY); 1586 rekey.header.type = ntohs (GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY);
1590 rekey.header.size = ntohs (sizeof(rekey)); 1587 rekey.header.size = ntohs (sizeof(rekey));
1591 GNUNET_CRYPTO_ecdhe_key_get_public (&queue->ephemeral, &rekey.ephemeral);
1592 rekey.monotonic_time = 1588 rekey.monotonic_time =
1593 GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (cfg)); 1589 GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (cfg));
1594 thp.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_REKEY); 1590 thp.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_TCP_REKEY);
@@ -1627,9 +1623,10 @@ inject_rekey (struct Queue *queue)
1627 queue->cwrite_off += sizeof(rekey); 1623 queue->cwrite_off += sizeof(rekey);
1628 /* Setup new cipher for successive messages */ 1624 /* Setup new cipher for successive messages */
1629 gcry_cipher_close (queue->out_cipher); 1625 gcry_cipher_close (queue->out_cipher);
1630 setup_out_cipher (queue); 1626 setup_out_cipher (queue, &k);
1631} 1627}
1632 1628
1629
1633static int 1630static int
1634pending_reversals_delete_it (void *cls, 1631pending_reversals_delete_it (void *cls,
1635 const struct GNUNET_HashCode *key, 1632 const struct GNUNET_HashCode *key,
@@ -1829,7 +1826,7 @@ queue_write (void *cls)
1829 if (((0 == queue->rekey_left_bytes) || 1826 if (((0 == queue->rekey_left_bytes) ||
1830 (0 == GNUNET_TIME_absolute_get_remaining ( 1827 (0 == GNUNET_TIME_absolute_get_remaining (
1831 queue->rekey_time).rel_value_us)) && 1828 queue->rekey_time).rel_value_us)) &&
1832 (((0 == queue->pwrite_off) || ! we_do_not_need_to_rekey)&& 1829 (((0 == queue->pwrite_off) || ! we_do_not_need_to_rekey) &&
1833 (queue->cwrite_off + sizeof (struct TCPRekey) <= BUF_SIZE))) 1830 (queue->cwrite_off + sizeof (struct TCPRekey) <= BUF_SIZE)))
1834 { 1831 {
1835 inject_rekey (queue); 1832 inject_rekey (queue);
@@ -1868,24 +1865,23 @@ queue_write (void *cls)
1868static size_t 1865static size_t
1869try_handle_plaintext (struct Queue *queue) 1866try_handle_plaintext (struct Queue *queue)
1870{ 1867{
1871 const struct GNUNET_MessageHeader *hdr = 1868 const struct GNUNET_MessageHeader *hdr;
1872 (const struct GNUNET_MessageHeader *) queue->pread_buf; 1869 const struct TCPConfirmationAck *tca;
1873 const struct TCPConfirmationAck *tca = (const struct 1870 const struct TCPBox *box;
1874 TCPConfirmationAck *) queue->pread_buf; 1871 const struct TCPRekey *rekey;
1875 const struct TCPBox *box = (const struct TCPBox *) queue->pread_buf; 1872 const struct TCPFinish *fin;
1876 const struct TCPRekey *rekey = (const struct TCPRekey *) queue->pread_buf;
1877 const struct TCPFinish *fin = (const struct TCPFinish *) queue->pread_buf;
1878 struct TCPRekey rekeyz; 1873 struct TCPRekey rekeyz;
1879 struct TCPFinish finz; 1874 struct TCPFinish finz;
1880 struct GNUNET_ShortHashCode tmac; 1875 struct GNUNET_ShortHashCode tmac;
1881 uint16_t type; 1876 uint16_t type;
1882 size_t size = 0; /* make compiler happy */ 1877 size_t size = 0;
1883 struct TcpHandshakeAckSignature thas; 1878 struct TcpHandshakeAckSignature thas;
1884 const struct GNUNET_CRYPTO_ChallengeNonceP challenge = queue->challenge; 1879 const struct GNUNET_CRYPTO_ChallengeNonceP challenge = queue->challenge;
1885 1880
1886 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1881 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1887 "try handle plaintext!\n"); 1882 "try handle plaintext!\n");
1888 1883
1884 hdr = (const struct GNUNET_MessageHeader *) queue->pread_buf;
1889 if ((sizeof(*hdr) > queue->pread_off)) 1885 if ((sizeof(*hdr) > queue->pread_off))
1890 { 1886 {
1891 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1887 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1893,11 +1889,12 @@ try_handle_plaintext (struct Queue *queue)
1893 return 0; /* not even a header */ 1889 return 0; /* not even a header */
1894 } 1890 }
1895 1891
1896 if ((-1 != unverified_size) && (unverified_size > INITIAL_CORE_KX_SIZE)) 1892 if ((GNUNET_YES != queue->initial_core_kx_done) && (queue->unverified_size >
1893 INITIAL_CORE_KX_SIZE))
1897 { 1894 {
1898 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1895 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1899 "Already received data of size %lu bigger than KX size %lu!\n", 1896 "Already received data of size %lu bigger than KX size %lu!\n",
1900 unverified_size, 1897 queue->unverified_size,
1901 INITIAL_CORE_KX_SIZE); 1898 INITIAL_CORE_KX_SIZE);
1902 GNUNET_break_op (0); 1899 GNUNET_break_op (0);
1903 queue_finish (queue); 1900 queue_finish (queue);
@@ -1908,6 +1905,7 @@ try_handle_plaintext (struct Queue *queue)
1908 switch (type) 1905 switch (type)
1909 { 1906 {
1910 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_CONFIRMATION_ACK: 1907 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_CONFIRMATION_ACK:
1908 tca = (const struct TCPConfirmationAck *) queue->pread_buf;
1911 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1909 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1912 "start processing ack\n"); 1910 "start processing ack\n");
1913 if (sizeof(*tca) > queue->pread_off) 1911 if (sizeof(*tca) > queue->pread_off)
@@ -1980,7 +1978,11 @@ try_handle_plaintext (struct Queue *queue)
1980 queue->address->sa_family, NULL); 1978 queue->address->sa_family, NULL);
1981 } 1979 }
1982 1980
1983 unverified_size = -1; 1981 /**
1982 * Once we received this ack, we consider this a verified connection.
1983 * FIXME: I am not sure this logic is sane here.
1984 */
1985 queue->initial_core_kx_done = GNUNET_YES;
1984 1986
1985 char *foreign_addr; 1987 char *foreign_addr;
1986 1988
@@ -2020,6 +2022,7 @@ try_handle_plaintext (struct Queue *queue)
2020 break; 2022 break;
2021 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX: 2023 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_BOX:
2022 /* Special case: header size excludes box itself! */ 2024 /* Special case: header size excludes box itself! */
2025 box = (const struct TCPBox *) queue->pread_buf;
2023 if (ntohs (hdr->size) + sizeof(struct TCPBox) > queue->pread_off) 2026 if (ntohs (hdr->size) + sizeof(struct TCPBox) > queue->pread_off)
2024 return 0; 2027 return 0;
2025 calculate_hmac (&queue->in_hmac, &box[1], ntohs (hdr->size), &tmac); 2028 calculate_hmac (&queue->in_hmac, &box[1], ntohs (hdr->size), &tmac);
@@ -2036,6 +2039,7 @@ try_handle_plaintext (struct Queue *queue)
2036 break; 2039 break;
2037 2040
2038 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY: 2041 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_REKEY:
2042 rekey = (const struct TCPRekey *) queue->pread_buf;
2039 if (sizeof(*rekey) > queue->pread_off) 2043 if (sizeof(*rekey) > queue->pread_off)
2040 return 0; 2044 return 0;
2041 if (ntohs (hdr->size) != sizeof(*rekey)) 2045 if (ntohs (hdr->size) != sizeof(*rekey))
@@ -2060,6 +2064,7 @@ try_handle_plaintext (struct Queue *queue)
2060 break; 2064 break;
2061 2065
2062 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH: 2066 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_TCP_FINISH:
2067 fin = (const struct TCPFinish *) queue->pread_buf;
2063 if (sizeof(*fin) > queue->pread_off) 2068 if (sizeof(*fin) > queue->pread_off)
2064 return 0; 2069 return 0;
2065 if (ntohs (hdr->size) != sizeof(*fin)) 2070 if (ntohs (hdr->size) != sizeof(*fin))
@@ -2091,8 +2096,8 @@ try_handle_plaintext (struct Queue *queue)
2091 return 0; 2096 return 0;
2092 } 2097 }
2093 GNUNET_assert (0 != size); 2098 GNUNET_assert (0 != size);
2094 if (-1 != unverified_size) 2099 if (-1 != queue->unverified_size)
2095 unverified_size += size; 2100 queue->unverified_size += size;
2096 return size; 2101 return size;
2097} 2102}
2098 2103
@@ -2712,10 +2717,10 @@ static void
2712start_initial_kx_out (struct Queue *queue) 2717start_initial_kx_out (struct Queue *queue)
2713{ 2718{
2714 struct GNUNET_CRYPTO_EcdhePublicKey epub; 2719 struct GNUNET_CRYPTO_EcdhePublicKey epub;
2720 struct GNUNET_HashCode k;
2715 2721
2716 GNUNET_CRYPTO_ecdhe_key_create (&queue->ephemeral); 2722 GNUNET_CRYPTO_eddsa_kem_encaps (&queue->target.public_key, &epub, &k);
2717 GNUNET_CRYPTO_ecdhe_key_get_public (&queue->ephemeral, &epub); 2723 setup_out_cipher (queue, &k);
2718 setup_out_cipher (queue);
2719 transmit_kx (queue, &epub); 2724 transmit_kx (queue, &epub);
2720} 2725}
2721 2726
@@ -3060,6 +3065,7 @@ proto_read_kx (void *cls)
3060 GNUNET_free (pq); 3065 GNUNET_free (pq);
3061} 3066}
3062 3067
3068
3063static struct ProtoQueue * 3069static struct ProtoQueue *
3064create_proto_queue (struct GNUNET_NETWORK_Handle *sock, 3070create_proto_queue (struct GNUNET_NETWORK_Handle *sock,
3065 struct sockaddr *in, 3071 struct sockaddr *in,
@@ -3120,7 +3126,6 @@ listen_cb (void *cls)
3120 struct sockaddr_storage in; 3126 struct sockaddr_storage in;
3121 socklen_t addrlen; 3127 socklen_t addrlen;
3122 struct GNUNET_NETWORK_Handle *sock; 3128 struct GNUNET_NETWORK_Handle *sock;
3123 struct ProtoQueue *pq;
3124 struct ListenTask *lt; 3129 struct ListenTask *lt;
3125 struct sockaddr *in_addr; 3130 struct sockaddr *in_addr;
3126 3131
diff --git a/src/transport/gnunet-communicator-udp.c b/src/transport/gnunet-communicator-udp.c
index 4657a7220..a58423c95 100644
--- a/src/transport/gnunet-communicator-udp.c
+++ b/src/transport/gnunet-communicator-udp.c
@@ -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
@@ -38,6 +38,7 @@
38 * - support other UDP-specific NAT traversal methods (#) 38 * - support other UDP-specific NAT traversal methods (#)
39 */ 39 */
40#include "platform.h" 40#include "platform.h"
41#include "gnunet_common.h"
41#include "gnunet_util_lib.h" 42#include "gnunet_util_lib.h"
42#include "gnunet_protocols.h" 43#include "gnunet_protocols.h"
43#include "gnunet_signatures.h" 44#include "gnunet_signatures.h"
@@ -67,7 +68,7 @@
67 * How often do we scan for changes to our network interfaces? 68 * How often do we scan for changes to our network interfaces?
68 */ 69 */
69#define INTERFACE_SCAN_FREQUENCY \ 70#define INTERFACE_SCAN_FREQUENCY \
70 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5) 71 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
71 72
72/** 73/**
73 * How long do we believe our addresses to remain up (before 74 * How long do we believe our addresses to remain up (before
@@ -76,7 +77,7 @@
76#define ADDRESS_VALIDITY_PERIOD GNUNET_TIME_UNIT_HOURS 77#define ADDRESS_VALIDITY_PERIOD GNUNET_TIME_UNIT_HOURS
77 78
78#define WORKING_QUEUE_INTERVALL \ 79#define WORKING_QUEUE_INTERVALL \
79 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MICROSECONDS,1) 80 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MICROSECONDS,1)
80 81
81/** 82/**
82 * AES key size. 83 * AES key size.
@@ -93,7 +94,7 @@
93 */ 94 */
94#define GCM_TAG_SIZE (128 / 8) 95#define GCM_TAG_SIZE (128 / 8)
95 96
96#define GENERATE_AT_ONCE 2 97#define GENERATE_AT_ONCE 16
97 98
98/** 99/**
99 * If we fall below this number of available KCNs, 100 * If we fall below this number of available KCNs,
@@ -104,7 +105,7 @@
104 * arrive before the sender runs out. So really this 105 * arrive before the sender runs out. So really this
105 * should ideally be based on the RTT. 106 * should ideally be based on the RTT.
106 */ 107 */
107#define KCN_THRESHOLD 92 108#define KCN_THRESHOLD 96
108 109
109/** 110/**
110 * How many KCNs do we keep around *after* we hit 111 * How many KCNs do we keep around *after* we hit
@@ -134,7 +135,7 @@
134 * sense. Might make sense to adapt to RTT if we had 135 * sense. Might make sense to adapt to RTT if we had
135 * a good measurement... 136 * a good measurement...
136 */ 137 */
137#define MAX_SECRETS 128000 138#define MAX_SECRETS 256
138 139
139/** 140/**
140 * Default value for how often we do rekey based on number of bytes transmitted? 141 * Default value for how often we do rekey based on number of bytes transmitted?
@@ -206,12 +207,8 @@ struct InitialKX
206 * HMAC for the following encrypted message, using GCM. HMAC uses 207 * HMAC for the following encrypted message, using GCM. HMAC uses
207 * key derived from the handshake with sequence number zero. 208 * key derived from the handshake with sequence number zero.
208 */ 209 */
209 char gcm_tag[GCM_TAG_SIZE]; 210 uint8_t gcm_tag[GCM_TAG_SIZE];
210 211
211 /**
212 * A flag indicating, if the sender is doing rekeying.
213 */
214 int rekeying;
215}; 212};
216 213
217 214
@@ -258,13 +255,7 @@ struct UDPAck
258 * Sequence acknowledgement limit. Specifies current maximum sequence 255 * Sequence acknowledgement limit. Specifies current maximum sequence
259 * number supported by receiver. 256 * number supported by receiver.
260 */ 257 */
261 uint32_t sequence_max GNUNET_PACKED; 258 uint32_t sequence_ack GNUNET_PACKED;
262
263 /**
264 * Sequence acknowledgement limit. Specifies current maximum sequence
265 * number supported by receiver.
266 */
267 uint32_t acks_available GNUNET_PACKED;
268 259
269 /** 260 /**
270 * CMAC of the base key being acknowledged. 261 * CMAC of the base key being acknowledged.
@@ -343,42 +334,24 @@ struct UDPBox
343 * wrong, the receiver should check if the message might be a 334 * wrong, the receiver should check if the message might be a
344 * `struct UdpHandshakeSignature`. 335 * `struct UdpHandshakeSignature`.
345 */ 336 */
346 char gcm_tag[GCM_TAG_SIZE]; 337 uint8_t gcm_tag[GCM_TAG_SIZE];
347 338
348 /**
349 * A flag indicating, if the sender is doing rekeying.
350 */
351 int rekeying;
352}; 339};
353 340
354/** 341/**
355 * UDP message box. Always sent encrypted, only allowed after 342 * Plaintext of a rekey payload in a UDPBox.
356 * the receiver sent a `struct UDPAck` for the base key!
357 */ 343 */
358struct UDPRekey 344struct UDPRekey
359{ 345{
360 /** 346 /**
361 * Key and IV identification code. KDF applied to an acknowledged 347 * Type is #GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_REKEY.
362 * base key and a sequence number. Sequence numbers must be used
363 * monotonically increasing up to the maximum specified in
364 * `struct UDPAck`. Without further `struct UDPAck`s, the sender
365 * must fall back to sending handshakes!
366 */
367 struct GNUNET_ShortHashCode kid;
368
369 /**
370 * 128-bit authentication tag for the following encrypted message,
371 * from GCM. MAC starts at the @e body_start that follows and
372 * extends until the end of the UDP payload. If the @e hmac is
373 * wrong, the receiver should check if the message might be a
374 * `struct UdpHandshakeSignature`.
375 */ 348 */
376 char gcm_tag[GCM_TAG_SIZE]; 349 struct GNUNET_MessageHeader header;
377 350
378 /** 351 /**
379 * Sender's identity 352 * Ephemeral key to rekey with.
380 */ 353 */
381 struct GNUNET_PeerIdentity sender; 354 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral;
382}; 355};
383 356
384GNUNET_NETWORK_STRUCT_END 357GNUNET_NETWORK_STRUCT_END
@@ -500,6 +473,21 @@ struct SharedSecret
500 * Number of active KCN entries. 473 * Number of active KCN entries.
501 */ 474 */
502 unsigned int active_kce_count; 475 unsigned int active_kce_count;
476
477 /**
478 * Bytes sent with this shared secret
479 */
480 size_t bytes_sent;
481
482 /**
483 * rekey initiated for this secret?
484 */
485 int rekey_initiated;
486
487 /**
488 * Also precompute keys despite sufficient acks (for rekey)
489 */
490 int override_available_acks;
503}; 491};
504 492
505 493
@@ -510,16 +498,6 @@ struct SharedSecret
510struct SenderAddress 498struct SenderAddress
511{ 499{
512 /** 500 /**
513 * Shared secret we use with @e target for rekeying.
514 */
515 struct SharedSecret *ss_rekey;
516
517 /**
518 * Flag indicating sender is initiated rekeying for this receiver.
519 */
520 int rekeying;
521
522 /**
523 * To whom are we talking to. 501 * To whom are we talking to.
524 */ 502 */
525 struct GNUNET_PeerIdentity target; 503 struct GNUNET_PeerIdentity target;
@@ -575,21 +553,20 @@ struct SenderAddress
575 */ 553 */
576 int sender_destroy_called; 554 int sender_destroy_called;
577 555
578
579 /** 556 /**
580 * ID of kce working queue task 557 * ID of kce working queue task
581 */ 558 */
582 struct GNUNET_SCHEDULER_Task *kce_task; 559 struct GNUNET_SCHEDULER_Task *kce_task;
583 560
584 /** 561 /**
585 * ID of kce rekey working queue task 562 * Is the kce_task finished?
586 */ 563 */
587 struct GNUNET_SCHEDULER_Task *kce_task_rekey; 564 int kce_task_finished;
588 565
589 /** 566 /**
590 * Is the kce_task finished? 567 * When KCE finishes, send ACK if GNUNET_YES
591 */ 568 */
592 int kce_task_finished; 569 int kce_send_ack_on_finish;
593}; 570};
594 571
595 572
@@ -599,38 +576,12 @@ struct SenderAddress
599 */ 576 */
600struct ReceiverAddress 577struct ReceiverAddress
601{ 578{
602
603 /**
604 * Shared secret we use with @e target for rekeying.
605 */
606 struct SharedSecret *ss_rekey;
607
608 /**
609 * Acks available when we started rekeying.
610 */
611 unsigned int rekey_acks_available;
612
613 /**
614 * Send bytes for this receiver address.
615 */
616 uint64_t rekey_send_bytes;
617
618 /** 579 /**
619 * Timeout for this receiver address. 580 * Timeout for this receiver address.
620 */ 581 */
621 struct GNUNET_TIME_Absolute rekey_timeout; 582 struct GNUNET_TIME_Absolute rekey_timeout;
622 583
623 /** 584 /**
624 * Flag indicating sender is initiated rekeying for this receiver.
625 */
626 int rekeying;
627
628 /**
629 * Number of kce we retain for sending the rekeying shared secret.
630 */
631 int number_rekeying_kce;
632
633 /**
634 * To whom are we talking to. 585 * To whom are we talking to.
635 */ 586 */
636 struct GNUNET_PeerIdentity target; 587 struct GNUNET_PeerIdentity target;
@@ -784,10 +735,6 @@ static struct GNUNET_TIME_Relative rekey_interval;
784 * How often we do rekey based on number of bytes transmitted 735 * How often we do rekey based on number of bytes transmitted
785 */ 736 */
786static unsigned long long rekey_max_bytes; 737static unsigned long long rekey_max_bytes;
787/**
788 * Shared secret we finished the last kce working queue for.
789 */
790struct SharedSecret *ss_finished;
791 738
792/** 739/**
793 * Cache of pre-generated key IDs. 740 * Cache of pre-generated key IDs.
@@ -1050,35 +997,37 @@ kce_generate (struct SharedSecret *ss, uint32_t seq)
1050 * @param withoutKce If GNUNET_YES shared secrets with kce will not be destroyed. 997 * @param withoutKce If GNUNET_YES shared secrets with kce will not be destroyed.
1051 */ 998 */
1052static int 999static int
1053secret_destroy (struct SharedSecret *ss, int withoutKce) 1000secret_destroy (struct SharedSecret *ss)
1054{ 1001{
1055 struct SenderAddress *sender; 1002 struct SenderAddress *sender;
1056 struct ReceiverAddress *receiver; 1003 struct ReceiverAddress *receiver;
1057 struct KeyCacheEntry *kce; 1004 struct KeyCacheEntry *kce;
1058 1005
1059 if (withoutKce && (ss->sequence_allowed > 0))
1060 return GNUNET_NO;
1061
1062 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1006 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1063 "secret %s destroy %u %u\n", 1007 "secret %s destroy %u\n",
1064 GNUNET_h2s (&ss->master), 1008 GNUNET_h2s (&ss->master),
1065 withoutKce,
1066 ss->sequence_allowed); 1009 ss->sequence_allowed);
1067 if (NULL != (sender = ss->sender)) 1010 if (NULL != (sender = ss->sender))
1068 { 1011 {
1069 GNUNET_CONTAINER_DLL_remove (sender->ss_head, sender->ss_tail, ss); 1012 GNUNET_CONTAINER_DLL_remove (sender->ss_head, sender->ss_tail, ss);
1070 sender->num_secrets--; 1013 sender->num_secrets--;
1014 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1015 "%u sender->num_secrets\n",
1016 receiver->num_secrets);
1017 if (NULL != ss->sender->kce_task)
1018 {
1019 GNUNET_SCHEDULER_cancel (ss->sender->kce_task);
1020 ss->sender->kce_task = NULL;
1021 }
1071 } 1022 }
1072 if (NULL != (receiver = ss->receiver)) 1023 if (NULL != (receiver = ss->receiver))
1073 { 1024 {
1074 GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss); 1025 GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
1075 receiver->num_secrets--; 1026 receiver->num_secrets--;
1076 // Uncomment this for alternativ 1 of backchannel functionality
1077 receiver->acks_available -= (ss->sequence_allowed - ss->sequence_used); 1027 receiver->acks_available -= (ss->sequence_allowed - ss->sequence_used);
1078 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1028 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1079 "%u receiver->acks_available 3\n", 1029 "%u receiver->num_secrets\n",
1080 receiver->acks_available); 1030 receiver->num_secrets);
1081 // Until here for alternativ 1
1082 } 1031 }
1083 while (NULL != (kce = ss->kce_head)) 1032 while (NULL != (kce = ss->kce_head))
1084 kce_destroy (kce); 1033 kce_destroy (kce);
@@ -1337,7 +1286,7 @@ setup_cipher (const struct GNUNET_HashCode *msec,
1337 */ 1286 */
1338static int 1287static int
1339try_decrypt (const struct SharedSecret *ss, 1288try_decrypt (const struct SharedSecret *ss,
1340 const char tag[GCM_TAG_SIZE], 1289 const uint8_t *tag,
1341 uint32_t serial, 1290 uint32_t serial,
1342 const char *in_buf, 1291 const char *in_buf,
1343 size_t in_buf_size, 1292 size_t in_buf_size,
@@ -1375,28 +1324,29 @@ setup_shared_secret_dec (const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral)
1375 struct SharedSecret *ss; 1324 struct SharedSecret *ss;
1376 1325
1377 ss = GNUNET_new (struct SharedSecret); 1326 ss = GNUNET_new (struct SharedSecret);
1378 GNUNET_CRYPTO_eddsa_ecdh (my_private_key, ephemeral, &ss->master); 1327 GNUNET_CRYPTO_eddsa_kem_decaps (my_private_key, ephemeral, &ss->master);
1328 calculate_cmac (ss);
1379 return ss; 1329 return ss;
1380} 1330}
1381 1331
1382 1332
1383/** 1333/**
1384 * Setup shared secret for encryption. 1334 * Setup new shared secret for encryption using KEM.
1385 * 1335 *
1386 * @param ephemeral ephemeral key we are sending to the other peer 1336 * @param[out] ephemeral ephemeral key to be sent to other peer (encapsulated key from KEM)
1387 * @param[in,out] receiver queue to initialize encryption key for 1337 * @param[in,out] receiver queue to initialize encryption key for
1388 * @return new shared secret 1338 * @return new shared secret
1389 */ 1339 */
1390static struct SharedSecret * 1340static struct SharedSecret *
1391setup_shared_secret_enc (const struct GNUNET_CRYPTO_EcdhePrivateKey *ephemeral, 1341setup_shared_secret_ephemeral (struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral,
1392 struct ReceiverAddress *receiver, int add_to_receiver) 1342 struct ReceiverAddress *receiver)
1393{ 1343{
1394 struct SharedSecret *ss; 1344 struct SharedSecret *ss;
1345 struct GNUNET_HashCode k;
1395 1346
1347 GNUNET_CRYPTO_eddsa_kem_encaps (&receiver->target.public_key, ephemeral, &k);
1396 ss = GNUNET_new (struct SharedSecret); 1348 ss = GNUNET_new (struct SharedSecret);
1397 GNUNET_CRYPTO_ecdh_eddsa (ephemeral, 1349 memcpy (&ss->master, &k, sizeof (k));
1398 &receiver->target.public_key,
1399 &ss->master);
1400 calculate_cmac (ss); 1350 calculate_cmac (ss);
1401 ss->receiver = receiver; 1351 ss->receiver = receiver;
1402 GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss); 1352 GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
@@ -1416,60 +1366,39 @@ setup_shared_secret_enc (const struct GNUNET_CRYPTO_EcdhePrivateKey *ephemeral,
1416static void 1366static void
1417setup_receiver_mq (struct ReceiverAddress *receiver); 1367setup_receiver_mq (struct ReceiverAddress *receiver);
1418 1368
1369
1419/** 1370/**
1420 * Destroying all secrets. Depending on parameter we keep those secrets having a kce. 1371 * Best effort try to purge some secrets.
1372 * Ideally those, not ACKed.
1421 * 1373 *
1422 * @param ss The secret we will not destroy. 1374 * @param ss_list_tail the oldest secret in the list of interest.
1423 * @param withoutKce If GNUNET_YES shared secrets with kce will not be destroyed. 1375 * @return number of deleted secrets.
1424 */ 1376 */
1425static void 1377unsigned int
1426destroy_all_secrets (struct SharedSecret *ss, int withoutKce) 1378purge_secrets (struct SharedSecret *ss_list_tail)
1427{ 1379{
1428 struct SenderAddress *sender;
1429 struct ReceiverAddress *receiver;
1430 struct SharedSecret *ss_to_destroy;
1431 struct SharedSecret *ss_start;
1432 struct SharedSecret *pos; 1380 struct SharedSecret *pos;
1433 int at_least_one_destroyed = GNUNET_NO; 1381 struct SharedSecret *ss_to_purge;
1382 unsigned int deleted = 0;
1434 1383
1435 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1384 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1436 "Starting destroy all withoutKce: %u.\n", 1385 "Purging secrets.\n");
1437 withoutKce); 1386 pos = ss_list_tail;
1438
1439 if (NULL != (sender = ss->sender))
1440 {
1441 ss_start = sender->ss_head;
1442 }
1443 else if (NULL != (receiver = ss->receiver))
1444 {
1445 ss_start = receiver->ss_head;
1446 }
1447 else
1448 {
1449 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1450 "Shared secret has no sender or receiver!\n");
1451 return;
1452 }
1453
1454 pos = ss_start;
1455 while (NULL != pos) 1387 while (NULL != pos)
1456 { 1388 {
1457 ss_to_destroy = pos; 1389 ss_to_purge = pos;
1458 pos = pos->next; 1390 pos = pos->prev;
1459
1460 if (ss != ss_to_destroy)
1461 at_least_one_destroyed = secret_destroy (ss_to_destroy, withoutKce);
1462 }
1463 1391
1464 if ((ss != ss_start) && ! at_least_one_destroyed) 1392 // FIXME we may also want to purge old unacked.
1465 { 1393 if (rekey_max_bytes <= ss_to_purge->bytes_sent)
1466 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1394 {
1467 "Really destroying all.\n"); 1395 secret_destroy (ss_to_purge);
1468 destroy_all_secrets (ss_start, GNUNET_NO); 1396 deleted++;
1397 }
1469 } 1398 }
1470
1471 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1399 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1472 "Finished destroy all.\n"); 1400 "Finished purging all, deleted %u.\n", deleted);
1401 return deleted;
1473} 1402}
1474 1403
1475 1404
@@ -1506,9 +1435,6 @@ add_acks (struct SharedSecret *ss, int acks_to_add)
1506 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1435 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1507 "Tell transport we have %u more acks!\n", 1436 "Tell transport we have %u more acks!\n",
1508 acks_to_add); 1437 acks_to_add);
1509 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1510 "%u kce for rekeying.\n",
1511 receiver->number_rekeying_kce);
1512 1438
1513 // Until here for alternativ 1 1439 // Until here for alternativ 1
1514 1440
@@ -1516,63 +1442,6 @@ add_acks (struct SharedSecret *ss, int acks_to_add)
1516 1442
1517 GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss); 1443 GNUNET_CONTAINER_DLL_remove (receiver->ss_head, receiver->ss_tail, ss);
1518 GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss); 1444 GNUNET_CONTAINER_DLL_insert (receiver->ss_head, receiver->ss_tail, ss);
1519 destroy_all_secrets (ss, GNUNET_YES);
1520}
1521
1522
1523static uint32_t
1524reset_rekey_kces (struct ReceiverAddress *receiver,
1525 uint32_t acks_to_add)
1526{
1527 int needed_for_rekeying;
1528
1529 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1530 "%u kce for rekeying and %u acks_to_add\n",
1531 receiver->number_rekeying_kce,
1532 acks_to_add);
1533
1534 needed_for_rekeying = (3 - receiver->number_rekeying_kce);
1535 if (acks_to_add <= needed_for_rekeying)
1536 {
1537 receiver->number_rekeying_kce += acks_to_add;
1538 acks_to_add = 0;
1539 }
1540 else
1541 {
1542 acks_to_add -= (3 - receiver->number_rekeying_kce);
1543 receiver->number_rekeying_kce = 3;
1544 }
1545
1546 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1547 "%u kce for rekeying and %u acks_to_add\n",
1548 receiver->number_rekeying_kce,
1549 acks_to_add);
1550 return acks_to_add;
1551}
1552
1553
1554static void
1555add_acks_rekey (struct ReceiverAddress *receiver)
1556{
1557 uint32_t acks_to_add = receiver->ss_rekey->sequence_allowed;
1558
1559 if (receiver->number_rekeying_kce < 3)
1560 acks_to_add = reset_rekey_kces (receiver, acks_to_add);
1561 receiver->acks_available = receiver->ss_rekey->sequence_allowed;
1562 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1563 "%u receiver->acks_available 4\n",
1564 receiver->acks_available);
1565 if (0 != acks_to_add)
1566 {
1567 add_acks (receiver->ss_rekey, acks_to_add);
1568 }
1569 receiver->ss_rekey = NULL;
1570 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1571 "# rekeying successful\n");
1572 GNUNET_STATISTICS_update (stats,
1573 "# rekeying successful",
1574 1,
1575 GNUNET_NO);
1576} 1445}
1577 1446
1578 1447
@@ -1598,36 +1467,6 @@ handle_ack (void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
1598 "in handle ack with cmac %s\n", 1467 "in handle ack with cmac %s\n",
1599 GNUNET_h2s (&ack->cmac)); 1468 GNUNET_h2s (&ack->cmac));
1600 1469
1601 if (NULL != receiver->ss_rekey)
1602 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1603 "We have rekey secret with cmac %s \n",
1604 GNUNET_h2s (&receiver->ss_rekey->cmac));
1605
1606 if ((NULL != receiver->ss_rekey) && (0 == memcmp (&ack->cmac,
1607 &receiver->ss_rekey->cmac,
1608 sizeof(struct
1609 GNUNET_HashCode))) )
1610 {
1611 allowed = ntohl (ack->sequence_max);
1612
1613 if (allowed > receiver->ss_rekey->sequence_allowed)
1614 {
1615 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1616 "%u > %u (%u %u) for rekey secrect %s\n", allowed,
1617 receiver->ss_rekey->sequence_allowed,
1618 receiver->acks_available,
1619 ack->acks_available,
1620 GNUNET_h2s (&receiver->ss_rekey->master));
1621
1622 receiver->ss_rekey->sequence_allowed = allowed;
1623
1624 if (GNUNET_NO == receiver->rekeying)
1625 add_acks_rekey (receiver);
1626
1627 return GNUNET_NO;
1628 }
1629 }
1630
1631 (void) pid; 1470 (void) pid;
1632 for (struct SharedSecret *ss = receiver->ss_head; NULL != ss; ss = ss->next) 1471 for (struct SharedSecret *ss = receiver->ss_head; NULL != ss; ss = ss->next)
1633 { 1472 {
@@ -1635,90 +1474,76 @@ handle_ack (void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
1635 { 1474 {
1636 1475
1637 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1476 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1638 "Found matching mac\n"); 1477 "Found matching cmac\n");
1639 1478
1640 allowed = ntohl (ack->sequence_max); 1479 allowed = ntohl (ack->sequence_ack);
1641 1480
1642 if (allowed > ss->sequence_allowed) 1481 if (allowed <= ss->sequence_allowed)
1643 { 1482 {
1644 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1483 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1645 "%u > %u (%u %u) for secrect %s\n", allowed, 1484 "Ignoring ack, not giving us increased window\n.");
1646 ss->sequence_allowed, 1485 return GNUNET_NO;
1647 receiver->acks_available,
1648 ack->acks_available,
1649 GNUNET_h2s (&ss->master));
1650 acks_to_add = (allowed - ss->sequence_allowed);
1651 if ((GNUNET_NO == receiver->rekeying) &&
1652 (receiver->number_rekeying_kce < 3) )
1653 acks_to_add = reset_rekey_kces (receiver, acks_to_add);
1654
1655 if ((0 != acks_to_add) && (GNUNET_NO == receiver->rekeying))
1656 {
1657 receiver->acks_available += (allowed - ss->sequence_allowed);
1658 ss->sequence_allowed = allowed;
1659 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1660 "%u receiver->acks_available 5\n",
1661 receiver->acks_available);
1662 add_acks (ss, acks_to_add);
1663 }
1664 } 1486 }
1487 acks_to_add = (allowed - ss->sequence_allowed);
1488 GNUNET_assert (0 != acks_to_add);
1489 receiver->acks_available += (allowed - ss->sequence_allowed);
1490 ss->sequence_allowed = allowed;
1491 add_acks (ss, acks_to_add);
1492 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1493 "New sequence allows until %u (+%u). Acks available to us: %u. For secret %s\n",
1494 allowed,
1495 acks_to_add,
1496 receiver->acks_available,
1497 GNUNET_h2s (&ss->master));
1665 return GNUNET_NO; 1498 return GNUNET_NO;
1666 } 1499 }
1667 } 1500 }
1501 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1502 "Matching cmac not found for ack!\n");
1668 return GNUNET_YES; 1503 return GNUNET_YES;
1669} 1504}
1670 1505
1671 1506
1672/** 1507/**
1673 * Test if we have received a valid message in plaintext. 1508 * We established a shared secret with a sender. We should try to send
1674 * If so, handle it. 1509 * the sender an `struct UDPAck` at the next opportunity to allow the
1510 * sender to use @a ss longer (assuming we did not yet already
1511 * recently).
1675 * 1512 *
1676 * @param sender peer to process inbound plaintext for 1513 * @param ss shared secret to generate ACKs for
1677 * @param buf buffer we received
1678 * @param buf_size number of bytes in @a buf
1679 */ 1514 */
1680static void 1515static void
1681try_handle_plaintext (struct SenderAddress *sender, 1516consider_ss_ack (struct SharedSecret *ss)
1682 const void *buf,
1683 size_t buf_size)
1684{ 1517{
1685 const struct GNUNET_MessageHeader *hdr = 1518 struct UDPAck ack;
1686 (const struct GNUNET_MessageHeader *) buf; 1519 GNUNET_assert (NULL != ss->sender);
1687 const struct UDPAck *ack = (const struct UDPAck *) buf; 1520 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1688 uint16_t type; 1521 "Considering SS UDPAck %s\n",
1522 GNUNET_i2s_full (&ss->sender->target));
1689 1523
1690 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1524 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1691 "try_handle_plaintext of size %lu (%u %lu) and type %u\n", 1525 "Sender has %u acks available.\n",
1692 buf_size, 1526 ss->sender->acks_available);
1693 ntohs (hdr->size), 1527 /* drop ancient KeyCacheEntries */
1694 sizeof(*hdr), 1528 while ((NULL != ss->kce_head) &&
1695 ntohs (hdr->type)); 1529 (MAX_SQN_DELTA <
1696 if (sizeof(*hdr) > buf_size) 1530 ss->kce_head->sequence_number - ss->kce_tail->sequence_number))
1697 return; /* not even a header */ 1531 kce_destroy (ss->kce_tail);
1698 if (ntohs (hdr->size) > buf_size)
1699 return; /* not even a header */
1700 type = ntohs (hdr->type);
1701 switch (type)
1702 {
1703 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK:
1704 /* lookup master secret by 'cmac', then update sequence_max */
1705 GNUNET_CONTAINER_multipeermap_get_multiple (receivers,
1706 &sender->target,
1707 &handle_ack,
1708 (void *) ack);
1709 /* There could be more messages after the ACK, handle those as well */
1710 buf += ntohs (hdr->size);
1711 buf_size -= ntohs (hdr->size);
1712 pass_plaintext_to_core (sender, buf, buf_size);
1713 break;
1714 1532
1715 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_PAD:
1716 /* skip padding */
1717 break;
1718 1533
1719 default: 1534 ack.header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK);
1720 pass_plaintext_to_core (sender, buf, buf_size); 1535 ack.header.size = htons (sizeof(ack));
1721 } 1536 ack.sequence_ack = htonl (ss->sequence_allowed);
1537 ack.cmac = ss->cmac;
1538 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1539 "Notifying transport with UDPAck %s, sequence %u and master %s\n",
1540 GNUNET_i2s_full (&ss->sender->target),
1541 ss->sequence_allowed,
1542 GNUNET_h2s (&(ss->master)));
1543 GNUNET_TRANSPORT_communicator_notify (ch,
1544 &ss->sender->target,
1545 COMMUNICATOR_ADDRESS_PREFIX,
1546 &ack.header);
1722} 1547}
1723 1548
1724 1549
@@ -1726,173 +1551,139 @@ static void
1726kce_generate_cb (void *cls) 1551kce_generate_cb (void *cls)
1727{ 1552{
1728 struct SharedSecret *ss = cls; 1553 struct SharedSecret *ss = cls;
1729
1730 ss->sender->kce_task = NULL; 1554 ss->sender->kce_task = NULL;
1731 1555
1732 if (((GNUNET_NO == ss->sender->rekeying) && (ss->sender->acks_available < 1556 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1733 KCN_TARGET) ) || 1557 "Precomputing %u keys for master %s\n",
1734 ((ss->sender->ss_rekey == ss) && (GNUNET_YES == ss->sender->rekeying) && 1558 GENERATE_AT_ONCE,
1735 (ss->sender->acks_available < KCN_TARGET))) 1559 GNUNET_h2s (&(ss->master)));
1736 { 1560 if ((ss->override_available_acks != GNUNET_YES) &&
1737 1561 (KCN_TARGET < ss->sender->acks_available))
1738 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1562 return;
1739 "Precomputing keys for master %s\n", 1563 for (int i = 0; i < GENERATE_AT_ONCE; i++)
1740 GNUNET_h2s (&(ss->master))); 1564 kce_generate (ss, ++ss->sequence_allowed);
1741
1742 for (int i = 0; i < GENERATE_AT_ONCE; i++)
1743 kce_generate (ss, ++ss->sequence_allowed);
1744
1745 if (KCN_TARGET > ss->sender->acks_available)
1746 {
1747 ss->sender->kce_task = GNUNET_SCHEDULER_add_delayed (
1748 WORKING_QUEUE_INTERVALL,
1749 kce_generate_cb,
1750 ss);
1751 }
1752 else
1753 {
1754 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1755 "We have enough keys.\n");
1756 ss_finished = ss;
1757 ss->sender->kce_task_finished = GNUNET_YES;
1758 }
1759 }
1760
1761
1762}
1763
1764
1765static void
1766kce_generate_rekey_cb (void *cls)
1767{
1768 struct SharedSecret *ss = cls;
1769
1770 ss->sender->kce_task_rekey = NULL;
1771 1565
1772 if (NULL == ss->sender->kce_task) 1566 /**
1567 * As long as we loose over 30% of max acks in reschedule,
1568 * We keep generating acks for this ss.
1569 */
1570 if (KCN_TARGET > ss->sender->acks_available)
1773 { 1571 {
1774
1775 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1776 "Precomputing keys for rekey master %s\n",
1777 GNUNET_h2s (&(ss->master)));
1778
1779 for (int i = 0; i < GENERATE_AT_ONCE; i++)
1780 kce_generate (ss, ++ss->sequence_allowed);
1781
1782 ss->sender->kce_task = GNUNET_SCHEDULER_add_delayed ( 1572 ss->sender->kce_task = GNUNET_SCHEDULER_add_delayed (
1783 WORKING_QUEUE_INTERVALL, 1573 WORKING_QUEUE_INTERVALL,
1784 kce_generate_cb, 1574 kce_generate_cb,
1785 ss); 1575 ss);
1786 ss->sender->kce_task_rekey = NULL; 1576 return;
1787 }
1788 else
1789 {
1790 ss->sender->kce_task_rekey = GNUNET_SCHEDULER_add_delayed (
1791 WORKING_QUEUE_INTERVALL,
1792 kce_generate_rekey_cb,
1793 ss);
1794 } 1577 }
1578 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1579 "We have enough keys (ACKs: %u).\n", ss->sender->acks_available);
1580 ss->sender->kce_task_finished = GNUNET_YES;
1581 ss->override_available_acks = GNUNET_NO;
1582 if (ss->sender->kce_send_ack_on_finish == GNUNET_YES)
1583 consider_ss_ack (ss);
1795} 1584}
1796 1585
1797 1586
1798/** 1587/**
1799 * We established a shared secret with a sender. We should try to send 1588 * Test if we have received a valid message in plaintext.
1800 * the sender an `struct UDPAck` at the next opportunity to allow the 1589 * If so, handle it.
1801 * sender to use @a ss longer (assuming we did not yet already
1802 * recently).
1803 * 1590 *
1804 * @param ss shared secret to generate ACKs for 1591 * @param sender peer to process inbound plaintext for
1805 * @param initial The SharedSecret came with initial KX. 1592 * @param buf buffer we received
1593 * @param buf_size number of bytes in @a buf
1806 */ 1594 */
1807static void 1595static void
1808consider_ss_ack (struct SharedSecret *ss, int initial) 1596try_handle_plaintext (struct SenderAddress *sender,
1597 const void *buf,
1598 size_t buf_size)
1809{ 1599{
1810 struct GNUNET_SCHEDULER_Task *kce_task_rekey; 1600 const struct GNUNET_MessageHeader *hdr;
1811 struct GNUNET_SCHEDULER_Task *kce_task; 1601 const struct UDPAck *ack;
1812 int kce_task_finished; 1602 const struct UDPRekey *rekey;
1813 1603 struct SharedSecret *ss_rekey;
1814 kce_task_rekey = ss->sender->kce_task_rekey; 1604 const char *buf_pos = buf;
1815 kce_task_finished = ss->sender->kce_task_finished; 1605 size_t bytes_remaining = buf_size;
1816 kce_task = ss->sender->kce_task; 1606 uint16_t type;
1817
1818 GNUNET_assert (NULL != ss->sender);
1819 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1820 "Considering SS UDPAck %s\n",
1821 GNUNET_i2s_full (&ss->sender->target));
1822 1607
1608 hdr = (struct GNUNET_MessageHeader*) buf_pos;
1609 if (sizeof(*hdr) > bytes_remaining)
1610 {
1611 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Plaintext too short, dropping...\n");
1612 return; /* no data left */
1613 }
1823 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1614 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1824 "We have %u acks available.\n", 1615 "try_handle_plaintext of size %lu (%u %lu) and type %u\n",
1825 ss->sender->acks_available); 1616 bytes_remaining,
1826 /* drop ancient KeyCacheEntries */ 1617 ntohs (hdr->size),
1827 while ((NULL != ss->kce_head) && 1618 sizeof(*hdr),
1828 (MAX_SQN_DELTA < 1619 ntohs (hdr->type));
1829 ss->kce_head->sequence_number - ss->kce_tail->sequence_number)) 1620 if (ntohs (hdr->size) > bytes_remaining)
1830 kce_destroy (ss->kce_tail); 1621 return; /* buffer too short for indicated message length */
1831 1622 type = ntohs (hdr->type);
1832 1623 switch (type)
1833 if (GNUNET_NO == initial) 1624 {
1834 kce_generate (ss, ++ss->sequence_allowed); 1625 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_REKEY:
1835 1626 rekey = (struct UDPRekey*) buf_pos;
1836 if (NULL != kce_task) 1627 ss_rekey = setup_shared_secret_dec (&rekey->ephemeral);
1628 ss_rekey->sender = sender;
1629 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss_rekey);
1630 sender->num_secrets++;
1631 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1632 "Received rekey secret with cmac %s\n",
1633 GNUNET_h2s (&(ss_rekey->cmac)));
1837 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1634 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1838 "kce_task is not NULL\n"); 1635 "Received secret with master %s.\n",
1839 if (kce_task_finished) 1636 GNUNET_h2s (&(ss_rekey->master)));
1840 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1637 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1841 "kce_task_finished: GNUNET_YES\n"); 1638 "We have %u sequence_allowed.\n",
1842 if (initial) 1639 ss_rekey->sequence_allowed);
1843 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1640 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1844 "initial: GNUNET_YES\n"); 1641 "We have a sender %p\n",
1845 1642 ss_rekey->sender);
1846 if (kce_task_finished || (GNUNET_NO == initial))
1847 {
1848 struct UDPAck ack;
1849 struct SharedSecret *ss_tell;
1850
1851 if (GNUNET_NO != initial)
1852 ss_tell = ss_finished;
1853 else
1854 ss_tell = ss;
1855
1856 ack.header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK);
1857 ack.header.size = htons (sizeof(ack));
1858 ack.sequence_max = htonl (ss_tell->sequence_allowed);
1859 ack.acks_available = ss->sender->acks_available;
1860 ack.cmac = ss_tell->cmac;
1861 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1643 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1862 "Notifying transport of UDPAck %s with initial %u and master %s\n", 1644 "We have %u acks available.\n",
1863 GNUNET_i2s_full (&ss_tell->sender->target), 1645 ss_rekey->sender->acks_available);
1864 initial, 1646 ss_rekey->sender->kce_send_ack_on_finish = GNUNET_YES;
1865 GNUNET_h2s (&(ss_tell->master))); 1647 ss_rekey->override_available_acks = GNUNET_YES;
1866 GNUNET_TRANSPORT_communicator_notify (ch, 1648 // FIXME
1867 &ss_tell->sender->target, 1649 ss_rekey->sender->kce_task = GNUNET_SCHEDULER_add_delayed (
1868 COMMUNICATOR_ADDRESS_PREFIX, 1650 WORKING_QUEUE_INTERVALL,
1869 &ack.header); 1651 kce_generate_cb,
1870 if (GNUNET_NO != initial) 1652 ss_rekey);
1653 // FIXME: Theoretically, this could be an Ack
1654 buf_pos += ntohs (hdr->size);
1655 bytes_remaining -= ntohs (hdr->size);
1656 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1657 if (sender->num_secrets > MAX_SECRETS)
1871 { 1658 {
1872 destroy_all_secrets (ss, GNUNET_YES); 1659 if (0 == purge_secrets (sender->ss_tail))
1873 ss->sender->kce_task_finished = GNUNET_NO; 1660 {
1661 // No secret purged. Delete oldest.
1662 secret_destroy (sender->ss_tail);
1663 }
1874 } 1664 }
1875 } 1665 break;
1876 else if ((NULL == kce_task) && ((KCN_THRESHOLD > 1666 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_ACK:
1877 ss->sender->acks_available) || 1667 /* lookup master secret by 'cmac', then update sequence_max */
1878 (GNUNET_YES == ss->sender->rekeying) || 1668 ack = (struct UDPAck*) buf_pos;
1879 (ss->sender->num_secrets > MAX_SECRETS) )) 1669 GNUNET_CONTAINER_multipeermap_get_multiple (receivers,
1880 { 1670 &sender->target,
1671 &handle_ack,
1672 (void *) ack);
1673 /* There could be more messages after the ACK, handle those as well */
1674 buf_pos += ntohs (hdr->size);
1675 bytes_remaining -= ntohs (hdr->size);
1676 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1677 break;
1881 1678
1882 // TODO This task must be per sender! FIXME: This is a nice todo, but I do not know what must be done here to fix. 1679 case GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_PAD:
1883 kce_task = GNUNET_SCHEDULER_add_delayed (WORKING_QUEUE_INTERVALL, 1680 /* skip padding */
1884 kce_generate_cb, 1681 break;
1885 ss);
1886 kce_task_finished = GNUNET_NO;
1887 1682
1683 default:
1684 pass_plaintext_to_core (sender, buf_pos, bytes_remaining);
1888 } 1685 }
1889 else if ((NULL == kce_task_rekey) && (GNUNET_YES == 1686 return;
1890 ss->sender->rekeying) )
1891 {
1892 kce_task_rekey = GNUNET_SCHEDULER_add_delayed (WORKING_QUEUE_INTERVALL,
1893 kce_generate_rekey_cb,
1894 ss);
1895 }
1896} 1687}
1897 1688
1898 1689
@@ -1919,6 +1710,7 @@ decrypt_box (const struct UDPBox *box,
1919 sizeof(out_buf), 1710 sizeof(out_buf),
1920 out_buf)) 1711 out_buf))
1921 { 1712 {
1713 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed decryption.\n");
1922 GNUNET_STATISTICS_update (stats, 1714 GNUNET_STATISTICS_update (stats,
1923 "# Decryption failures with valid KCE", 1715 "# Decryption failures with valid KCE",
1924 1, 1716 1,
@@ -1927,6 +1719,7 @@ decrypt_box (const struct UDPBox *box,
1927 return; 1719 return;
1928 } 1720 }
1929 kce_destroy (kce); 1721 kce_destroy (kce);
1722 kce = NULL;
1930 GNUNET_STATISTICS_update (stats, 1723 GNUNET_STATISTICS_update (stats,
1931 "# bytes decrypted with BOX", 1724 "# bytes decrypted with BOX",
1932 sizeof(out_buf), 1725 sizeof(out_buf),
@@ -1939,95 +1732,18 @@ decrypt_box (const struct UDPBox *box,
1939 "decrypted UDPBox with kid %s\n", 1732 "decrypted UDPBox with kid %s\n",
1940 GNUNET_sh2s (&box->kid)); 1733 GNUNET_sh2s (&box->kid));
1941 try_handle_plaintext (ss->sender, out_buf, sizeof(out_buf)); 1734 try_handle_plaintext (ss->sender, out_buf, sizeof(out_buf));
1942 if ((GNUNET_NO == box->rekeying) && (GNUNET_YES == ss->sender->rekeying)) 1735 if ((KCN_THRESHOLD > ss->sender->acks_available) &&
1943 { 1736 (NULL == ss->sender->kce_task) &&
1944 ss->sender->rekeying = GNUNET_NO; 1737 (GNUNET_YES == ss->sender->kce_task_finished))
1945 ss->sender->ss_rekey = NULL;
1946 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1947 "Receiver stopped rekeying.\n");
1948 }
1949 else
1950 {
1951 ss->sender->rekeying = GNUNET_YES;
1952 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1953 "Got Box: Receiver doing rekeying.\n");
1954 }
1955}
1956
1957
1958/**
1959 * We received a @a rekey with matching @a kce. Decrypt and process it.
1960 *
1961 * @param rekey the data we received
1962 * @param rekey_len number of bytes in @a rekey
1963 * @param kce key index to decrypt @a rekey
1964 */
1965static void
1966decrypt_rekey (const struct UDPRekey *rekey,
1967 size_t rekey_len,
1968 struct KeyCacheEntry *kce,
1969 struct SenderAddress *sender)
1970{
1971 struct SharedSecret *ss = kce->ss;
1972 struct SharedSecret *ss_rekey;
1973 char out_buf[rekey_len - sizeof(*rekey)];
1974 struct GNUNET_HashCode *master;
1975
1976
1977 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1978 "decrypt_rekey.\n");
1979
1980 GNUNET_assert (NULL != ss->sender);
1981 if (GNUNET_OK != try_decrypt (ss,
1982 rekey->gcm_tag,
1983 kce->sequence_number,
1984 (const char *) &rekey[1],
1985 sizeof(out_buf),
1986 out_buf))
1987 { 1738 {
1988 GNUNET_STATISTICS_update (stats,
1989 "# Decryption failures with valid KCE",
1990 1,
1991 GNUNET_NO);
1992 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1739 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1993 "Decryption with kid %s failed\n", 1740 "Sender has %u ack left which is under threshold.\n",
1994 GNUNET_sh2s (&rekey->kid)); 1741 ss->sender->acks_available);
1995 kce_destroy (kce); 1742 ss->sender->kce_send_ack_on_finish = GNUNET_YES;
1996 return; 1743 ss->sender->kce_task = GNUNET_SCHEDULER_add_now (
1744 kce_generate_cb,
1745 ss);
1997 } 1746 }
1998 kce_destroy (kce);
1999 GNUNET_STATISTICS_update (stats,
2000 "# bytes decrypted with Rekey",
2001 sizeof(out_buf),
2002 GNUNET_NO);
2003 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2004 "decrypted UDPRekey with kid %s\n",
2005 GNUNET_sh2s (&rekey->kid));
2006 master = (struct GNUNET_HashCode *) out_buf;
2007 ss_rekey = GNUNET_new (struct SharedSecret);
2008 ss_rekey->master = *master;
2009 calculate_cmac (ss_rekey);
2010 ss_rekey->sender = sender;
2011 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss_rekey);
2012 sender->ss_rekey = ss_rekey;
2013 sender->num_secrets++;
2014 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2015 "Received secret with cmac %s\n",
2016 GNUNET_h2s (&(ss_rekey->cmac)));
2017 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2018 "Received secret with master %s.\n",
2019 GNUNET_h2s (&(ss_rekey->master)));
2020 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2021 "We have %u sequence_allowed.\n",
2022 ss_rekey->sequence_allowed);
2023 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2024 "We have a sender %p\n",
2025 ss_rekey->sender);
2026 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2027 "We have %u acks available.\n",
2028 ss_rekey->sender->acks_available);
2029 consider_ss_ack (ss_rekey, GNUNET_YES);
2030
2031} 1747}
2032 1748
2033 1749
@@ -2218,222 +1934,196 @@ sock_read (void *cls)
2218 udp_sock, 1934 udp_sock,
2219 &sock_read, 1935 &sock_read,
2220 NULL); 1936 NULL);
2221 rcvd = GNUNET_NETWORK_socket_recvfrom (udp_sock, 1937 while (1)
2222 buf, 1938 {
2223 sizeof(buf), 1939 rcvd = GNUNET_NETWORK_socket_recvfrom (udp_sock,
2224 (struct sockaddr *) &sa, 1940 buf,
2225 &salen); 1941 sizeof(buf),
2226 if (-1 == rcvd) 1942 (struct sockaddr *) &sa,
2227 { 1943 &salen);
2228 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG, "recv"); 1944 if (-1 == rcvd)
2229 return;
2230 }
2231 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2232 "Read %lu bytes\n", rcvd);
2233
2234 if (rcvd > sizeof(struct UDPRekey))
2235 {
2236 const struct UDPRekey *rekey;
2237 const struct UDPBox *box;
2238 struct KeyCacheEntry *kce;
2239 struct SenderAddress *sender;
2240 int do_decrypt = GNUNET_NO;
2241
2242 rekey = (const struct UDPRekey *) buf;
2243 box = (const struct UDPBox *) buf;
2244 kce = GNUNET_CONTAINER_multishortmap_get (key_cache, &rekey->kid);
2245
2246 if ((GNUNET_YES == box->rekeying) || (GNUNET_NO == box->rekeying))
2247 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2248 "UDPRekey has rekeying %u\n",
2249 box->rekeying);
2250 else
2251 do_decrypt = GNUNET_YES;
2252
2253 if ((GNUNET_YES == do_decrypt) && (NULL != kce) && (GNUNET_YES ==
2254 kce->ss->sender->
2255 rekeying))
2256 { 1945 {
2257 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1946 if (EAGAIN == errno)
2258 "UDPRekey with kid %s\n", 1947 break; // We are done reading data
2259 GNUNET_sh2s (&rekey->kid)); 1948 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG, "recv");
2260 sender = setup_sender (&rekey->sender, (const struct sockaddr *) &sa,
2261 salen);
2262
2263 if (NULL != sender->ss_rekey)
2264 return;
2265
2266 decrypt_rekey (rekey, (size_t) rcvd, kce, sender);
2267 return; 1949 return;
2268 } 1950 }
2269 } 1951 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2270 1952 "Read %lu bytes\n", rcvd);
2271 /* first, see if it is a UDPBox */
2272 if (rcvd > sizeof(struct UDPBox))
2273 {
2274 const struct UDPBox *box;
2275 struct KeyCacheEntry *kce;
2276 1953
2277 box = (const struct UDPBox *) buf; 1954 /* first, see if it is a UDPBox */
2278 kce = GNUNET_CONTAINER_multishortmap_get (key_cache, &box->kid); 1955 if (rcvd > sizeof(struct UDPBox))
2279 if (NULL != kce)
2280 { 1956 {
2281 decrypt_box (box, (size_t) rcvd, kce); 1957 const struct UDPBox *box;
2282 return; 1958 struct KeyCacheEntry *kce;
2283 }
2284 }
2285 1959
2286 /* next, check if it is a broadcast */ 1960 box = (const struct UDPBox *) buf;
2287 if (sizeof(struct UDPBroadcast) == rcvd) 1961 kce = GNUNET_CONTAINER_multishortmap_get (key_cache, &box->kid);
2288 { 1962 if (NULL != kce)
2289 const struct UDPBroadcast *ub; 1963 {
2290 struct UdpBroadcastSignature uhs; 1964 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2291 struct GNUNET_PeerIdentity sender; 1965 "Found KCE with kid %s\n",
1966 GNUNET_sh2s (&box->kid));
1967 decrypt_box (box, (size_t) rcvd, kce);
1968 continue;
1969 }
1970 }
2292 1971
2293 addr_verify = GNUNET_memdup (&sa, salen); 1972 /* next, check if it is a broadcast */
2294 addr_verify->sin_port = 0; 1973 if (sizeof(struct UDPBroadcast) == rcvd)
2295 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2296 "received UDPBroadcast from %s\n",
2297 GNUNET_a2s ((const struct sockaddr *) addr_verify, salen));
2298 ub = (const struct UDPBroadcast *) buf;
2299 uhs.purpose.purpose = htonl (
2300 GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST);
2301 uhs.purpose.size = htonl (sizeof(uhs));
2302 uhs.sender = ub->sender;
2303 sender = ub->sender;
2304 if (0 == memcmp (&sender, &my_identity, sizeof (struct
2305 GNUNET_PeerIdentity)))
2306 { 1974 {
1975 const struct UDPBroadcast *ub;
1976 struct UdpBroadcastSignature uhs;
1977 struct GNUNET_PeerIdentity sender;
1978
1979 addr_verify = GNUNET_memdup (&sa, salen);
1980 addr_verify->sin_port = 0;
2307 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1981 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2308 "Received our own broadcast\n"); 1982 "received UDPBroadcast from %s\n",
2309 GNUNET_free (addr_verify); 1983 GNUNET_a2s ((const struct sockaddr *) addr_verify, salen));
2310 return; 1984 ub = (const struct UDPBroadcast *) buf;
2311 } 1985 uhs.purpose.purpose = htonl (
2312 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1986 GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST);
2313 "checking UDPBroadcastSignature for %s\n", 1987 uhs.purpose.size = htonl (sizeof(uhs));
2314 GNUNET_i2s (&sender)); 1988 uhs.sender = ub->sender;
2315 GNUNET_CRYPTO_hash ((struct sockaddr *) addr_verify, salen, &uhs.h_address); 1989 sender = ub->sender;
2316 if (GNUNET_OK == 1990 if (0 == memcmp (&sender, &my_identity, sizeof (struct
2317 GNUNET_CRYPTO_eddsa_verify ( 1991 GNUNET_PeerIdentity)))
2318 GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST, 1992 {
2319 &uhs, 1993 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2320 &ub->sender_sig, 1994 "Received our own broadcast\n");
2321 &ub->sender.public_key)) 1995 GNUNET_free (addr_verify);
2322 { 1996 continue;
2323 char *addr_s; 1997 }
2324 enum GNUNET_NetworkType nt;
2325
2326 addr_s =
2327 sockaddr_to_udpaddr_string ((const struct sockaddr *) &sa, salen);
2328 GNUNET_STATISTICS_update (stats, "# broadcasts received", 1, GNUNET_NO);
2329 /* use our own mechanism to determine network type */
2330 nt =
2331 GNUNET_NT_scanner_get_type (is, (const struct sockaddr *) &sa, salen);
2332 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1998 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2333 "validating address %s received from UDPBroadcast\n", 1999 "checking UDPBroadcastSignature for %s\n",
2334 GNUNET_i2s (&sender)); 2000 GNUNET_i2s (&sender));
2335 GNUNET_TRANSPORT_application_validate (ah, &sender, nt, addr_s); 2001 GNUNET_CRYPTO_hash ((struct sockaddr *) addr_verify, salen,
2336 GNUNET_free (addr_s); 2002 &uhs.h_address);
2003 if (GNUNET_OK ==
2004 GNUNET_CRYPTO_eddsa_verify (
2005 GNUNET_SIGNATURE_PURPOSE_COMMUNICATOR_UDP_BROADCAST,
2006 &uhs,
2007 &ub->sender_sig,
2008 &ub->sender.public_key))
2009 {
2010 char *addr_s;
2011 enum GNUNET_NetworkType nt;
2012
2013 addr_s =
2014 sockaddr_to_udpaddr_string ((const struct sockaddr *) &sa, salen);
2015 GNUNET_STATISTICS_update (stats, "# broadcasts received", 1, GNUNET_NO);
2016 /* use our own mechanism to determine network type */
2017 nt =
2018 GNUNET_NT_scanner_get_type (is, (const struct sockaddr *) &sa, salen);
2019 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2020 "validating address %s received from UDPBroadcast\n",
2021 GNUNET_i2s (&sender));
2022 GNUNET_TRANSPORT_application_validate (ah, &sender, nt, addr_s);
2023 GNUNET_free (addr_s);
2024 GNUNET_free (addr_verify);
2025 continue;
2026 }
2027 else
2028 {
2029 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2030 "VerifyingPeer %s is verifying UDPBroadcast\n",
2031 GNUNET_i2s (&my_identity));
2032 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2033 "Verifying UDPBroadcast from %s failed\n",
2034 GNUNET_i2s (&ub->sender));
2035 }
2337 GNUNET_free (addr_verify); 2036 GNUNET_free (addr_verify);
2338 return; 2037 /* continue with KX, mostly for statistics... */
2339 } 2038 }
2340 else
2341 {
2342 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2343 "VerifyingPeer %s is verifying UDPBroadcast\n",
2344 GNUNET_i2s (&my_identity));
2345 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2346 "Verifying UDPBroadcast from %s failed\n",
2347 GNUNET_i2s (&ub->sender));
2348 }
2349 GNUNET_free (addr_verify);
2350 /* continue with KX, mostly for statistics... */
2351 }
2352
2353
2354 /* finally, test if it is a KX */
2355 if (rcvd < sizeof(struct UDPConfirmation) + sizeof(struct InitialKX))
2356 {
2357 GNUNET_STATISTICS_update (stats,
2358 "# messages dropped (no kid, too small for KX)",
2359 1,
2360 GNUNET_NO);
2361 return;
2362 }
2363 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2364 "Got KX\n");
2365 {
2366 const struct InitialKX *kx;
2367 struct SharedSecret *ss;
2368 char pbuf[rcvd - sizeof(struct InitialKX)];
2369 const struct UDPConfirmation *uc;
2370 struct SenderAddress *sender;
2371 2039
2372 kx = (const struct InitialKX *) buf;
2373 ss = setup_shared_secret_dec (&kx->ephemeral);
2374 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2375 "Before DEC\n");
2376
2377 if (GNUNET_OK != try_decrypt (ss,
2378 kx->gcm_tag,
2379 0,
2380 &buf[sizeof(*kx)],
2381 sizeof(pbuf),
2382 pbuf))
2383 {
2384 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2385 "Unable to decrypt tag, dropping...\n");
2386 GNUNET_free (ss);
2387 GNUNET_STATISTICS_update (
2388 stats,
2389 "# messages dropped (no kid, AEAD decryption failed)",
2390 1,
2391 GNUNET_NO);
2392 return;
2393 }
2394 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2395 "Before VERIFY\n");
2396 2040
2397 uc = (const struct UDPConfirmation *) pbuf; 2041 /* finally, test if it is a KX */
2398 if (GNUNET_OK != verify_confirmation (&kx->ephemeral, uc)) 2042 if (rcvd < sizeof(struct UDPConfirmation) + sizeof(struct InitialKX))
2399 { 2043 {
2400 GNUNET_break_op (0);
2401 GNUNET_free (ss);
2402 GNUNET_STATISTICS_update (stats, 2044 GNUNET_STATISTICS_update (stats,
2403 "# messages dropped (sender signature invalid)", 2045 "# messages dropped (no kid, too small for KX)",
2404 1, 2046 1,
2405 GNUNET_NO); 2047 GNUNET_NO);
2406 return; 2048 continue;
2407 } 2049 }
2408 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2050 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2409 "Before SETUP_SENDER\n"); 2051 "Got KX\n");
2410
2411 calculate_cmac (ss);
2412 sender = setup_sender (&uc->sender, (const struct sockaddr *) &sa, salen);
2413 ss->sender = sender;
2414 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss);
2415 sender->num_secrets++;
2416 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
2417 GNUNET_STATISTICS_update (stats,
2418 "# messages decrypted without BOX",
2419 1,
2420 GNUNET_NO);
2421 try_handle_plaintext (sender, &uc[1], sizeof(pbuf) - sizeof(*uc));
2422 if ((GNUNET_NO == kx->rekeying) && (GNUNET_YES == ss->sender->rekeying))
2423 { 2052 {
2424 ss->sender->rekeying = GNUNET_NO; 2053 const struct InitialKX *kx;
2425 sender->ss_rekey = NULL; 2054 struct SharedSecret *ss;
2426 // destroy_all_secrets (ss, GNUNET_NO); 2055 char pbuf[rcvd - sizeof(struct InitialKX)];
2056 const struct UDPConfirmation *uc;
2057 struct SenderAddress *sender;
2058
2059 kx = (const struct InitialKX *) buf;
2060 ss = setup_shared_secret_dec (&kx->ephemeral);
2427 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2061 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2428 "Receiver stopped rekeying.\n"); 2062 "Before DEC\n");
2429 } 2063
2430 else if (GNUNET_NO == kx->rekeying) 2064 if (GNUNET_OK != try_decrypt (ss,
2431 consider_ss_ack (ss, GNUNET_YES); 2065 kx->gcm_tag,
2432 else 2066 0,
2433 { 2067 &buf[sizeof(*kx)],
2434 ss->sender->rekeying = GNUNET_YES; 2068 sizeof(pbuf),
2069 pbuf))
2070 {
2071 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2072 "Unable to decrypt tag, dropping...\n");
2073 GNUNET_free (ss);
2074 GNUNET_STATISTICS_update (
2075 stats,
2076 "# messages dropped (no kid, AEAD decryption failed)",
2077 1,
2078 GNUNET_NO);
2079 continue;
2080 }
2081 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2082 "Before VERIFY\n");
2083
2084 uc = (const struct UDPConfirmation *) pbuf;
2085 if (GNUNET_OK != verify_confirmation (&kx->ephemeral, uc))
2086 {
2087 GNUNET_break_op (0);
2088 GNUNET_free (ss);
2089 GNUNET_STATISTICS_update (stats,
2090 "# messages dropped (sender signature invalid)",
2091 1,
2092 GNUNET_NO);
2093 continue;
2094 }
2435 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2095 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2436 "Got KX: Receiver doing rekeying.\n"); 2096 "Before SETUP_SENDER\n");
2097
2098 calculate_cmac (ss);
2099 sender = setup_sender (&uc->sender, (const struct sockaddr *) &sa, salen);
2100 ss->sender = sender;
2101 GNUNET_CONTAINER_DLL_insert (sender->ss_head, sender->ss_tail, ss);
2102 if ((KCN_THRESHOLD > ss->sender->acks_available) &&
2103 (NULL == ss->sender->kce_task) &&
2104 (GNUNET_NO == ss->sender->kce_task_finished))
2105 {
2106 // TODO This task must be per sender! FIXME: This is a nice todo, but I do not know what must be done here to fix.
2107 ss->sender->kce_send_ack_on_finish = GNUNET_YES;
2108 ss->sender->kce_task = GNUNET_SCHEDULER_add_now (
2109 kce_generate_cb,
2110 ss);
2111 }
2112 sender->num_secrets++;
2113 GNUNET_STATISTICS_update (stats, "# Secrets active", 1, GNUNET_NO);
2114 GNUNET_STATISTICS_update (stats,
2115 "# messages decrypted without BOX",
2116 1,
2117 GNUNET_NO);
2118 try_handle_plaintext (sender, &uc[1], sizeof(pbuf) - sizeof(*uc));
2119 if (sender->num_secrets > MAX_SECRETS)
2120 {
2121 if (0 == purge_secrets (sender->ss_tail))
2122 {
2123 // No secret purged. Delete oldest.
2124 secret_destroy (sender->ss_tail);
2125 }
2126 }
2437 } 2127 }
2438 } 2128 }
2439} 2129}
@@ -2601,31 +2291,19 @@ do_pad (gcry_cipher_hd_t out_cipher, char *dgram, size_t pad_size)
2601} 2291}
2602 2292
2603 2293
2604/**
2605 * Signature of functions implementing the sending functionality of a
2606 * message queue.
2607 *
2608 * @param mq the message queue
2609 * @param msg the message to send
2610 * @param impl_state our `struct ReceiverAddress`
2611 */
2612static void 2294static void
2613mq_send_kx (struct GNUNET_MQ_Handle *mq, 2295send_msg_with_kx (const struct GNUNET_MessageHeader *msg, struct
2614 const struct GNUNET_MessageHeader *msg, 2296 ReceiverAddress *receiver)
2615 void *impl_state)
2616{ 2297{
2617 struct ReceiverAddress *receiver = impl_state;
2618 uint16_t msize = ntohs (msg->size); 2298 uint16_t msize = ntohs (msg->size);
2619 struct UdpHandshakeSignature uhs; 2299 struct UdpHandshakeSignature uhs;
2620 struct UDPConfirmation uc; 2300 struct UDPConfirmation uc;
2621 struct InitialKX kx; 2301 struct InitialKX kx;
2622 struct GNUNET_CRYPTO_EcdhePrivateKey epriv;
2623 char dgram[receiver->kx_mtu + sizeof(uc) + sizeof(kx)]; 2302 char dgram[receiver->kx_mtu + sizeof(uc) + sizeof(kx)];
2624 size_t dpos; 2303 size_t dpos;
2625 gcry_cipher_hd_t out_cipher; 2304 gcry_cipher_hd_t out_cipher;
2626 struct SharedSecret *ss; 2305 struct SharedSecret *ss;
2627 2306
2628 GNUNET_assert (mq == receiver->kx_mq);
2629 if (msize > receiver->kx_mtu) 2307 if (msize > receiver->kx_mtu)
2630 { 2308 {
2631 GNUNET_break (0); 2309 GNUNET_break (0);
@@ -2636,13 +2314,16 @@ mq_send_kx (struct GNUNET_MQ_Handle *mq,
2636 reschedule_receiver_timeout (receiver); 2314 reschedule_receiver_timeout (receiver);
2637 2315
2638 /* setup key material */ 2316 /* setup key material */
2639 GNUNET_CRYPTO_ecdhe_key_create (&epriv);
2640 2317
2641 ss = setup_shared_secret_enc (&epriv, receiver, GNUNET_YES); 2318 ss = setup_shared_secret_ephemeral (&uhs.ephemeral, receiver);
2642 2319
2643 if (receiver->num_secrets > MAX_SECRETS) 2320 if (receiver->num_secrets > MAX_SECRETS)
2644 { 2321 {
2645 destroy_all_secrets (ss, GNUNET_YES); 2322 if (0 == purge_secrets (receiver->ss_tail))
2323 {
2324 // No secret purged. Delete oldest.
2325 secret_destroy (receiver->ss_tail);
2326 }
2646 } 2327 }
2647 2328
2648 setup_cipher (&ss->master, 0, &out_cipher); 2329 setup_cipher (&ss->master, 0, &out_cipher);
@@ -2655,7 +2336,6 @@ mq_send_kx (struct GNUNET_MQ_Handle *mq,
2655 uhs.purpose.size = htonl (sizeof(uhs)); 2336 uhs.purpose.size = htonl (sizeof(uhs));
2656 uhs.sender = my_identity; 2337 uhs.sender = my_identity;
2657 uhs.receiver = receiver->target; 2338 uhs.receiver = receiver->target;
2658 GNUNET_CRYPTO_ecdhe_key_get_public (&epriv, &uhs.ephemeral);
2659 uhs.monotonic_time = uc.monotonic_time; 2339 uhs.monotonic_time = uc.monotonic_time;
2660 GNUNET_CRYPTO_eddsa_sign (my_private_key, 2340 GNUNET_CRYPTO_eddsa_sign (my_private_key,
2661 &uhs, 2341 &uhs,
@@ -2679,10 +2359,6 @@ mq_send_kx (struct GNUNET_MQ_Handle *mq,
2679 GNUNET_assert ( 2359 GNUNET_assert (
2680 0 == gcry_cipher_gettag (out_cipher, kx.gcm_tag, sizeof(kx.gcm_tag))); 2360 0 == gcry_cipher_gettag (out_cipher, kx.gcm_tag, sizeof(kx.gcm_tag)));
2681 gcry_cipher_close (out_cipher); 2361 gcry_cipher_close (out_cipher);
2682 if (GNUNET_NO == receiver->rekeying)
2683 kx.rekeying = GNUNET_NO;
2684 else
2685 kx.rekeying = GNUNET_YES;
2686 memcpy (dgram, &kx, sizeof(kx)); 2362 memcpy (dgram, &kx, sizeof(kx));
2687 if (-1 == GNUNET_NETWORK_socket_sendto (udp_sock, 2363 if (-1 == GNUNET_NETWORK_socket_sendto (udp_sock,
2688 dgram, 2364 dgram,
@@ -2695,168 +2371,51 @@ mq_send_kx (struct GNUNET_MQ_Handle *mq,
2695 msize, 2371 msize,
2696 GNUNET_a2s (receiver->address, 2372 GNUNET_a2s (receiver->address,
2697 receiver->address_len)); 2373 receiver->address_len));
2698 GNUNET_MQ_impl_send_continue (mq);
2699} 2374}
2700 2375
2701 2376
2377/**
2378 * Signature of functions implementing the sending functionality of a
2379 * message queue.
2380 *
2381 * @param mq the message queue
2382 * @param msg the message to send
2383 * @param impl_state our `struct ReceiverAddress`
2384 */
2702static void 2385static void
2703check_for_rekeying (struct ReceiverAddress *receiver, struct UDPBox *box) 2386mq_send_kx (struct GNUNET_MQ_Handle *mq,
2387 const struct GNUNET_MessageHeader *msg,
2388 void *impl_state)
2704{ 2389{
2390 struct ReceiverAddress *receiver = impl_state;
2705 2391
2706 struct GNUNET_TIME_Relative rt; 2392 GNUNET_assert (mq == receiver->kx_mq);
2707 2393 send_msg_with_kx (msg, receiver);
2708 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2394 GNUNET_MQ_impl_send_continue (mq);
2709 "Timeout is %llu\n.",
2710 (unsigned long long) receiver->rekey_timeout.abs_value_us);
2711
2712 if (0 == receiver->rekey_timeout.abs_value_us)
2713 {
2714 receiver->rekey_timeout = GNUNET_TIME_relative_to_absolute (
2715 rekey_interval);
2716 }
2717 else
2718 {
2719 rt = GNUNET_TIME_absolute_get_remaining (receiver->rekey_timeout);
2720 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2721 "Relative time is %llu and timeout is %llu\n.",
2722 (unsigned long long) rt.rel_value_us,
2723 (unsigned long long) receiver->rekey_timeout.abs_value_us);
2724
2725 if ((0 == rt.rel_value_us) || (receiver->rekey_send_bytes >
2726 rekey_max_bytes) )
2727 {
2728 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2729 "Bytes send %llu greater than %llu max bytes\n.",
2730 (unsigned long long) receiver->rekey_send_bytes,
2731 rekey_max_bytes);
2732 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2733 "Relative time is %llu and timeout is %llu\n.",
2734 (unsigned long long) rt.rel_value_us,
2735 (unsigned long long) receiver->rekey_timeout.abs_value_us);
2736
2737 receiver->rekey_timeout.abs_value_us = 0;
2738 receiver->rekey_send_bytes = 0;
2739 receiver->ss_rekey = NULL;
2740 // destroy_all_secrets (ss, GNUNET_NO);
2741 receiver->rekeying = GNUNET_YES;
2742 receiver->rekey_acks_available = receiver->acks_available;
2743 box->rekeying = GNUNET_YES;
2744 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2745 "Sender started rekeying.\n");
2746 if (GNUNET_YES == box->rekeying)
2747 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2748 "Sending rekeying with kid %s\n",
2749 GNUNET_sh2s (&box->kid));
2750 }
2751 }
2752} 2395}
2753 2396
2754 2397
2755static void 2398static void
2756send_UDPRekey (struct ReceiverAddress *receiver, struct SharedSecret *ss) 2399create_rekey (struct ReceiverAddress *receiver, struct SharedSecret *ss, struct
2757{ 2400 UDPRekey *rekey)
2758 uint8_t is_ss_rekey_sequence_allowed_zero = GNUNET_NO; 2401{
2759 uint8_t is_acks_available_below = GNUNET_NO; 2402 struct SharedSecret *ss_rekey;
2760 uint8_t send_rekey = GNUNET_NO;
2761 uint16_t not_below;
2762 struct GNUNET_CRYPTO_EcdhePrivateKey epriv;
2763 struct UDPRekey *rekey;
2764 size_t dpos;
2765
2766 char rekey_dgram[sizeof(struct UDPRekey) + receiver->d_mtu];
2767
2768 if (NULL != receiver->ss_rekey)
2769 {
2770 not_below = (receiver->rekey_acks_available
2771 - (receiver->rekey_acks_available % 3)) / 3;
2772 is_ss_rekey_sequence_allowed_zero = (0 ==
2773 receiver->ss_rekey->sequence_allowed);
2774 is_acks_available_below = (receiver->acks_available >= not_below);
2775 send_rekey = (0 == (receiver->acks_available - not_below) % not_below) &&
2776 is_acks_available_below && is_ss_rekey_sequence_allowed_zero;
2777 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2778 "send_rekey: %u, %u, %u\n",
2779 send_rekey,
2780 receiver->rekey_acks_available,
2781 receiver->acks_available);
2782 }
2783 else if (NULL == receiver->ss_rekey)
2784 {
2785 /* setup key material */
2786 GNUNET_CRYPTO_ecdhe_key_create (&epriv);
2787 receiver->ss_rekey = setup_shared_secret_enc (&epriv, receiver,
2788 GNUNET_NO);
2789 receiver->ss_rekey->sequence_allowed = 0;
2790 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2791 "Setup secret with cmac %s\n",
2792 GNUNET_h2s (&(receiver->ss_rekey->cmac)));
2793 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2794 "Setup secret with master %s.\n",
2795 GNUNET_h2s (&(receiver->ss_rekey->master)));
2796 }
2797
2798 if (send_rekey)
2799 {
2800 GNUNET_assert (0 != receiver->number_rekeying_kce);
2801 gcry_cipher_hd_t rekey_out_cipher;
2802
2803 while (NULL != ss && ss->sequence_used >= ss->sequence_allowed)
2804 {
2805 ss = ss->prev;
2806 }
2807
2808 if (NULL != ss)
2809 {
2810 rekey = (struct UDPRekey *) rekey_dgram;
2811 rekey->sender = my_identity;
2812 ss->sequence_used++;
2813 get_kid (&ss->master, ss->sequence_used, &rekey->kid);
2814 receiver->number_rekeying_kce--;
2815 setup_cipher (&ss->master, ss->sequence_used, &rekey_out_cipher);
2816 /* Append encrypted payload to dgram */
2817 dpos = sizeof(struct UDPRekey);
2818
2819 GNUNET_assert (
2820 0 == gcry_cipher_encrypt (rekey_out_cipher, &rekey_dgram[dpos],
2821 sizeof(receiver->ss_rekey->master),
2822 &(receiver->ss_rekey->master),
2823 sizeof(receiver->ss_rekey->master)));
2824 dpos += sizeof(receiver->ss_rekey->master);
2825 do_pad (rekey_out_cipher, &rekey_dgram[dpos], sizeof(rekey_dgram)
2826 - dpos);
2827 GNUNET_assert (0 == gcry_cipher_gettag (rekey_out_cipher,
2828 rekey->gcm_tag,
2829 sizeof(rekey->gcm_tag)));
2830 gcry_cipher_close (rekey_out_cipher);
2831
2832 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2833 "Sending rekey with kid %s and master %s\n",
2834 GNUNET_sh2s (&rekey->kid),
2835 GNUNET_h2s (&(receiver->ss_rekey->master)));
2836 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2837 "Sending rekey with cmac %s\n",
2838 GNUNET_h2s (&(receiver->ss_rekey->cmac)));
2839 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2840 "%u rekey kces left.\n",
2841 receiver->number_rekeying_kce);
2842 2403
2843 if (-1 == GNUNET_NETWORK_socket_sendto (udp_sock, 2404 ss->rekey_initiated = GNUNET_YES;
2844 rekey_dgram, 2405 /* setup key material */
2845 sizeof(rekey_dgram), 2406 ss_rekey = setup_shared_secret_ephemeral (&rekey->ephemeral,
2846 receiver->address, 2407 receiver);
2847 receiver->address_len)) 2408 ss_rekey->sequence_allowed = 0;
2848 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "send"); 2409 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2410 "Setup secret with k = %s\n",
2411 GNUNET_h2s (&(ss_rekey->master)));
2412 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2413 "Setup secret with H(k) = %s\n",
2414 GNUNET_h2s (&(ss_rekey->cmac)));
2849 2415
2850 receiver->acks_available--; 2416 /* Append encrypted payload to dgram */
2851 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2417 rekey->header.type = htons (GNUNET_MESSAGE_TYPE_COMMUNICATOR_UDP_REKEY);
2852 "%u receiver->acks_available 1\n", 2418 rekey->header.size = htons (sizeof (struct UDPRekey));
2853 receiver->acks_available);
2854 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2855 "Sending UDPRekey to %s\n", GNUNET_a2s (receiver->address,
2856 receiver->
2857 address_len));
2858 }
2859 }
2860} 2419}
2861 2420
2862 2421
@@ -2874,6 +2433,9 @@ mq_send_d (struct GNUNET_MQ_Handle *mq,
2874 void *impl_state) 2433 void *impl_state)
2875{ 2434{
2876 struct ReceiverAddress *receiver = impl_state; 2435 struct ReceiverAddress *receiver = impl_state;
2436 struct UDPRekey rekey;
2437 struct SharedSecret *ss;
2438 int inject_rekey = GNUNET_NO;
2877 uint16_t msize = ntohs (msg->size); 2439 uint16_t msize = ntohs (msg->size);
2878 2440
2879 GNUNET_assert (mq == receiver->d_mq); 2441 GNUNET_assert (mq == receiver->d_mq);
@@ -2893,19 +2455,52 @@ mq_send_d (struct GNUNET_MQ_Handle *mq,
2893 } 2455 }
2894 reschedule_receiver_timeout (receiver); 2456 reschedule_receiver_timeout (receiver);
2895 2457
2458 if (receiver->num_secrets > MAX_SECRETS)
2459 {
2460 if (0 == purge_secrets (receiver->ss_tail))
2461 {
2462 // No secret purged. Delete oldest.
2463 secret_destroy (receiver->ss_tail);
2464 }
2465 }
2896 /* begin "BOX" encryption method, scan for ACKs from tail! */ 2466 /* begin "BOX" encryption method, scan for ACKs from tail! */
2897 for (struct SharedSecret *ss = receiver->ss_tail; NULL != ss; ss = ss->prev) 2467 for (ss = receiver->ss_tail; NULL != ss; ss = ss->prev)
2898 { 2468 {
2469 size_t payload_len = sizeof(struct UDPBox) + receiver->d_mtu;
2470 if (ss->sequence_used >= ss->sequence_allowed)
2471 {
2472 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2473 "Skipping ss because no acks to use.\n");
2474 continue;
2475 }
2476 if (ss->bytes_sent >= rekey_max_bytes)
2477 {
2478 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2479 "Skipping ss because rekey bytes reached.\n");
2480 // FIXME cleanup ss with too many bytes sent!
2481 continue;
2482 }
2483 if (ss->bytes_sent > rekey_max_bytes * 0.7)
2484 {
2485 if (ss->rekey_initiated == GNUNET_NO)
2486 {
2487 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2488 "Injecting rekey for ss with byte sent %lu\n",
2489 (unsigned long) ss->bytes_sent);
2490 create_rekey (receiver, ss, &rekey);
2491 inject_rekey = GNUNET_YES;
2492 payload_len += sizeof (rekey);
2493 ss->rekey_initiated = GNUNET_YES;
2494 }
2495 }
2899 if (0 < ss->sequence_used) 2496 if (0 < ss->sequence_used)
2900 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2497 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2901 "Trying to send UDPBox with shared secrect %s sequence_used %u and ss->sequence_allowed %u\n", 2498 "Trying to send UDPBox with shared secrect %s sequence_used %u and ss->sequence_allowed %u\n",
2902 GNUNET_h2s (&ss->master), 2499 GNUNET_h2s (&ss->master),
2903 ss->sequence_used, 2500 ss->sequence_used,
2904 ss->sequence_allowed); 2501 ss->sequence_allowed);
2905 if (ss->sequence_used >= ss->sequence_allowed)
2906 continue;
2907 2502
2908 char dgram[sizeof(struct UDPBox) + receiver->d_mtu]; 2503 char dgram[payload_len];
2909 struct UDPBox *box; 2504 struct UDPBox *box;
2910 gcry_cipher_hd_t out_cipher; 2505 gcry_cipher_hd_t out_cipher;
2911 size_t dpos; 2506 size_t dpos;
@@ -2916,6 +2511,13 @@ mq_send_d (struct GNUNET_MQ_Handle *mq,
2916 setup_cipher (&ss->master, ss->sequence_used, &out_cipher); 2511 setup_cipher (&ss->master, ss->sequence_used, &out_cipher);
2917 /* Append encrypted payload to dgram */ 2512 /* Append encrypted payload to dgram */
2918 dpos = sizeof(struct UDPBox); 2513 dpos = sizeof(struct UDPBox);
2514 if (GNUNET_YES == inject_rekey)
2515 {
2516 GNUNET_assert (
2517 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], sizeof (rekey),
2518 &rekey, sizeof (rekey)));
2519 dpos += sizeof (rekey);
2520 }
2919 GNUNET_assert ( 2521 GNUNET_assert (
2920 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize)); 2522 0 == gcry_cipher_encrypt (out_cipher, &dgram[dpos], msize, msg, msize));
2921 dpos += msize; 2523 dpos += msize;
@@ -2925,53 +2527,26 @@ mq_send_d (struct GNUNET_MQ_Handle *mq,
2925 sizeof(box->gcm_tag))); 2527 sizeof(box->gcm_tag)));
2926 gcry_cipher_close (out_cipher); 2528 gcry_cipher_close (out_cipher);
2927 2529
2928 receiver->rekey_send_bytes += sizeof(struct UDPBox) + receiver->d_mtu;
2929
2930 if (GNUNET_NO == receiver->rekeying)
2931 box->rekeying = GNUNET_NO;
2932 else
2933 box->rekeying = GNUNET_YES;
2934
2935 if (-1 == GNUNET_NETWORK_socket_sendto (udp_sock, 2530 if (-1 == GNUNET_NETWORK_socket_sendto (udp_sock,
2936 dgram, 2531 dgram,
2937 sizeof(dgram), 2532 payload_len, // FIXME why always send sizeof dgram?
2938 receiver->address, 2533 receiver->address,
2939 receiver->address_len)) 2534 receiver->address_len))
2940 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "send"); 2535 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "send");
2941 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2536 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2942 "Sending UDPBox with payload size %u, %u acks left\n", 2537 "Sending UDPBox with payload size %u, %u acks left, %lu bytes sent\n",
2943 msize, 2538 msize,
2944 receiver->acks_available); 2539 receiver->acks_available,
2945 GNUNET_MQ_impl_send_continue (mq); 2540 (unsigned long) ss->bytes_sent);
2541 ss->bytes_sent += sizeof (dgram);
2946 receiver->acks_available--; 2542 receiver->acks_available--;
2947 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2543 GNUNET_MQ_impl_send_continue (mq);
2948 "%u receiver->acks_available 2\n",
2949 receiver->acks_available);
2950 check_for_rekeying (receiver, box);
2951 if (0 == receiver->acks_available - receiver->number_rekeying_kce)
2952 {
2953 /* We have no more ACKs */
2954 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2955 "No more acks\n");
2956 if (GNUNET_YES == receiver->rekeying)
2957 {
2958 receiver->rekeying = GNUNET_NO;
2959 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2960 "Sender stopped rekeying\n");
2961
2962 if ((NULL != receiver->ss_rekey) && (0 <
2963 receiver->ss_rekey->
2964 sequence_allowed) )
2965 add_acks_rekey (receiver);
2966 }
2967 }
2968 else if ((GNUNET_YES == receiver->rekeying) )
2969 {
2970 send_UDPRekey (receiver, ss);
2971 }
2972
2973 return; 2544 return;
2974 } 2545 }
2546 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2547 "No suitable ss found, sending as KX...\n");
2548 send_msg_with_kx (msg, receiver);
2549 GNUNET_MQ_impl_send_continue (mq);
2975} 2550}
2976 2551
2977 2552
@@ -3234,16 +2809,6 @@ get_sender_delete_it (void *cls,
3234 (void) cls; 2809 (void) cls;
3235 (void) target; 2810 (void) target;
3236 2811
3237 if (NULL != sender->kce_task_rekey)
3238 {
3239 GNUNET_SCHEDULER_cancel (sender->kce_task_rekey);
3240 sender->kce_task_rekey = NULL;
3241 }
3242 if (NULL != sender->kce_task)
3243 {
3244 GNUNET_SCHEDULER_cancel (sender->kce_task);
3245 sender->kce_task = NULL;
3246 }
3247 2812
3248 sender_destroy (sender); 2813 sender_destroy (sender);
3249 return GNUNET_OK; 2814 return GNUNET_OK;
diff --git a/src/transport/gnunet-service-tng.c b/src/transport/gnunet-service-tng.c
index c4711e6fe..f2ee685bc 100644
--- a/src/transport/gnunet-service-tng.c
+++ b/src/transport/gnunet-service-tng.c
@@ -187,20 +187,20 @@
187 * the value chosen here might be too aggressively low! 187 * the value chosen here might be too aggressively low!
188 */ 188 */
189#define DELAY_WARN_THRESHOLD \ 189#define DELAY_WARN_THRESHOLD \
190 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) 190 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
191 191
192/** 192/**
193 * If a DVBox could not be forwarded after this number of 193 * If a DVBox could not be forwarded after this number of
194 * seconds we drop it. 194 * seconds we drop it.
195 */ 195 */
196#define DV_FORWARD_TIMEOUT \ 196#define DV_FORWARD_TIMEOUT \
197 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60) 197 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60)
198 198
199/** 199/**
200 * Default value for how long we wait for reliability ack. 200 * Default value for how long we wait for reliability ack.
201 */ 201 */
202#define DEFAULT_ACK_WAIT_DURATION \ 202#define DEFAULT_ACK_WAIT_DURATION \
203 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1) 203 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1)
204 204
205/** 205/**
206 * We only consider queues as "quality" connections when 206 * We only consider queues as "quality" connections when
@@ -208,53 +208,53 @@
208 * the latency of the queue is below this threshold. 208 * the latency of the queue is below this threshold.
209 */ 209 */
210#define DV_QUALITY_RTT_THRESHOLD \ 210#define DV_QUALITY_RTT_THRESHOLD \
211 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1) 211 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1)
212 212
213/** 213/**
214 * How long do we consider a DV path valid if we see no 214 * How long do we consider a DV path valid if we see no
215 * further updates on it? Note: the value chosen here might be too low! 215 * further updates on it? Note: the value chosen here might be too low!
216 */ 216 */
217#define DV_PATH_VALIDITY_TIMEOUT \ 217#define DV_PATH_VALIDITY_TIMEOUT \
218 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5) 218 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
219 219
220/** 220/**
221 * How long do we cache backchannel (struct Backtalker) information 221 * How long do we cache backchannel (struct Backtalker) information
222 * after a backchannel goes inactive? 222 * after a backchannel goes inactive?
223 */ 223 */
224#define BACKCHANNEL_INACTIVITY_TIMEOUT \ 224#define BACKCHANNEL_INACTIVITY_TIMEOUT \
225 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5) 225 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
226 226
227/** 227/**
228 * How long before paths expire would we like to (re)discover DV paths? Should 228 * How long before paths expire would we like to (re)discover DV paths? Should
229 * be below #DV_PATH_VALIDITY_TIMEOUT. 229 * be below #DV_PATH_VALIDITY_TIMEOUT.
230 */ 230 */
231#define DV_PATH_DISCOVERY_FREQUENCY \ 231#define DV_PATH_DISCOVERY_FREQUENCY \
232 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 4) 232 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 4)
233 233
234/** 234/**
235 * How long are ephemeral keys valid? 235 * How long are ephemeral keys valid?
236 */ 236 */
237#define EPHEMERAL_VALIDITY \ 237#define EPHEMERAL_VALIDITY \
238 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4) 238 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4)
239 239
240/** 240/**
241 * How long do we keep partially reassembled messages around before giving up? 241 * How long do we keep partially reassembled messages around before giving up?
242 */ 242 */
243#define REASSEMBLY_EXPIRATION \ 243#define REASSEMBLY_EXPIRATION \
244 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 4) 244 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 4)
245 245
246/** 246/**
247 * What is the fastest rate at which we send challenges *if* we keep learning 247 * What is the fastest rate at which we send challenges *if* we keep learning
248 * an address (gossip, DHT, etc.)? 248 * an address (gossip, DHT, etc.)?
249 */ 249 */
250#define FAST_VALIDATION_CHALLENGE_FREQ \ 250#define FAST_VALIDATION_CHALLENGE_FREQ \
251 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 1) 251 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 1)
252 252
253/** 253/**
254 * What is the slowest rate at which we send challenges? 254 * What is the slowest rate at which we send challenges?
255 */ 255 */
256#define MAX_VALIDATION_CHALLENGE_FREQ \ 256#define MAX_VALIDATION_CHALLENGE_FREQ \
257 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_DAYS, 1) 257 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_DAYS, 1)
258 258
259/** 259/**
260 * How long until we forget about historic accumulators and thus 260 * How long until we forget about historic accumulators and thus
@@ -262,7 +262,7 @@
262 * active connection experiences without an ACK. 262 * active connection experiences without an ACK.
263 */ 263 */
264#define ACK_CUMMULATOR_TIMEOUT \ 264#define ACK_CUMMULATOR_TIMEOUT \
265 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4) 265 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4)
266 266
267/** 267/**
268 * What is the non-randomized base frequency at which we 268 * What is the non-randomized base frequency at which we
@@ -280,13 +280,13 @@
280 * When do we forget an invalid address for sure? 280 * When do we forget an invalid address for sure?
281 */ 281 */
282#define MAX_ADDRESS_VALID_UNTIL \ 282#define MAX_ADDRESS_VALID_UNTIL \
283 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MONTHS, 1) 283 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MONTHS, 1)
284 284
285/** 285/**
286 * How long do we consider an address valid if we just checked? 286 * How long do we consider an address valid if we just checked?
287 */ 287 */
288#define ADDRESS_VALIDATION_LIFETIME \ 288#define ADDRESS_VALIDATION_LIFETIME \
289 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4) 289 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4)
290 290
291/** 291/**
292 * What is the maximum frequency at which we do address validation? 292 * What is the maximum frequency at which we do address validation?
@@ -1774,10 +1774,6 @@ struct DistanceVector
1774 */ 1774 */
1775 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key; 1775 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key;
1776 1776
1777 /**
1778 * Our private ephemeral key.
1779 */
1780 struct GNUNET_CRYPTO_EcdhePrivateKey private_key;
1781}; 1777};
1782 1778
1783 1779
@@ -4411,24 +4407,18 @@ check_communicator_backchannel (
4411 4407
4412 4408
4413/** 4409/**
4414 * Ensure ephemeral keys in our @a dv are current. If no current one exists, 4410 * Sign ephemeral keys in our @a dv are current.
4415 * set it up.
4416 * 4411 *
4417 * @param[in,out] dv virtual link to update ephemeral for 4412 * @param[in,out] dv virtual link to update ephemeral for
4418 */ 4413 */
4419static void 4414static void
4420update_ephemeral (struct DistanceVector *dv) 4415sign_ephemeral (struct DistanceVector *dv)
4421{ 4416{
4422 struct EphemeralConfirmationPS ec; 4417 struct EphemeralConfirmationPS ec;
4423 4418
4424 if (0 !=
4425 GNUNET_TIME_absolute_get_remaining (dv->ephemeral_validity).rel_value_us)
4426 return;
4427 dv->monotime = GNUNET_TIME_absolute_get_monotonic (GST_cfg); 4419 dv->monotime = GNUNET_TIME_absolute_get_monotonic (GST_cfg);
4428 dv->ephemeral_validity = 4420 dv->ephemeral_validity =
4429 GNUNET_TIME_absolute_add (dv->monotime, EPHEMERAL_VALIDITY); 4421 GNUNET_TIME_absolute_add (dv->monotime, EPHEMERAL_VALIDITY);
4430 GNUNET_CRYPTO_ecdhe_key_create (&dv->private_key);
4431 GNUNET_CRYPTO_ecdhe_key_get_public (&dv->private_key, &dv->ephemeral_key);
4432 ec.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_EPHEMERAL); 4422 ec.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_EPHEMERAL);
4433 ec.target = dv->target; 4423 ec.target = dv->target;
4434 ec.ephemeral_key = dv->ephemeral_key; 4424 ec.ephemeral_key = dv->ephemeral_key;
@@ -4681,7 +4671,7 @@ dv_setup_key_state_from_km (const struct GNUNET_HashCode *km,
4681 const struct GNUNET_ShortHashCode *iv, 4671 const struct GNUNET_ShortHashCode *iv,
4682 struct DVKeyState *key) 4672 struct DVKeyState *key)
4683{ 4673{
4684 /* must match #dh_key_derive_eph_pub */ 4674 /* must match what we defive from decapsulated key */
4685 GNUNET_assert (GNUNET_YES == 4675 GNUNET_assert (GNUNET_YES ==
4686 GNUNET_CRYPTO_kdf (&key->material, 4676 GNUNET_CRYPTO_kdf (&key->material,
4687 sizeof(key->material), 4677 sizeof(key->material),
@@ -4710,62 +4700,6 @@ dv_setup_key_state_from_km (const struct GNUNET_HashCode *km,
4710 4700
4711 4701
4712/** 4702/**
4713 * Derive backchannel encryption key material from @a priv_ephemeral
4714 * and @a target and @a iv.
4715 *
4716 * @param priv_ephemeral ephemeral private key to use
4717 * @param target the target peer to encrypt to
4718 * @param iv unique IV to use
4719 * @param[out] key set to the key material
4720 * @return GNUNET_OK on success
4721 */
4722static enum GNUNET_GenericReturnValue
4723dh_key_derive_eph_pid (
4724 const struct GNUNET_CRYPTO_EcdhePrivateKey *priv_ephemeral,
4725 const struct GNUNET_PeerIdentity *target,
4726 const struct GNUNET_ShortHashCode *iv,
4727 struct DVKeyState *key)
4728{
4729 struct GNUNET_HashCode km;
4730
4731 if (GNUNET_YES != GNUNET_CRYPTO_ecdh_eddsa (priv_ephemeral,
4732 &target->public_key,
4733 &km))
4734 return GNUNET_SYSERR;
4735 // FIXME: Possibly also add return values here. We are processing
4736 // Input from other peers...
4737 dv_setup_key_state_from_km (&km, iv, key);
4738 return GNUNET_OK;
4739}
4740
4741
4742/**
4743 * Derive backchannel encryption key material from #GST_my_private_key
4744 * and @a pub_ephemeral and @a iv.
4745 *
4746 * @param priv_ephemeral ephemeral private key to use
4747 * @param target the target peer to encrypt to
4748 * @param iv unique IV to use
4749 * @param[out] key set to the key material
4750 * @return GNUNET_OK on success
4751 */
4752static enum GNUNET_GenericReturnValue
4753dh_key_derive_eph_pub (const struct GNUNET_CRYPTO_EcdhePublicKey *pub_ephemeral,
4754 const struct GNUNET_ShortHashCode *iv,
4755 struct DVKeyState *key)
4756{
4757 struct GNUNET_HashCode km;
4758
4759 if (GNUNET_YES != GNUNET_CRYPTO_eddsa_ecdh (GST_my_private_key,
4760 pub_ephemeral,
4761 &km))
4762 return GNUNET_SYSERR;
4763 dv_setup_key_state_from_km (&km, iv, key);
4764 return GNUNET_OK;
4765}
4766
4767
4768/**
4769 * Do HMAC calculation for backchannel messages over @a data using key 4703 * Do HMAC calculation for backchannel messages over @a data using key
4770 * material from @a key. 4704 * material from @a key.
4771 * 4705 *
@@ -4882,13 +4816,22 @@ encapsulate_for_dv (struct DistanceVector *dv,
4882 char enc[sizeof(struct TransportDVBoxPayloadP) + enc_body_size] GNUNET_ALIGN; 4816 char enc[sizeof(struct TransportDVBoxPayloadP) + enc_body_size] GNUNET_ALIGN;
4883 struct DVKeyState *key; 4817 struct DVKeyState *key;
4884 struct GNUNET_TIME_Relative rtt; 4818 struct GNUNET_TIME_Relative rtt;
4819 struct GNUNET_HashCode k;
4885 4820
4886 key = GNUNET_new (struct DVKeyState); 4821 key = GNUNET_new (struct DVKeyState);
4887 /* Encrypt payload */ 4822 /* Encrypt payload */
4888 box_hdr.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DV_BOX); 4823 box_hdr.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DV_BOX);
4889 box_hdr.total_hops = htons (0); 4824 box_hdr.total_hops = htons (0);
4890 box_hdr.without_fc = htons (without_fc); 4825 box_hdr.without_fc = htons (without_fc);
4891 update_ephemeral (dv); 4826 // update_ephemeral (dv);
4827 if (0 ==
4828 GNUNET_TIME_absolute_get_remaining (dv->ephemeral_validity).rel_value_us)
4829 {
4830 GNUNET_CRYPTO_eddsa_kem_encaps (&dv->target.public_key,
4831 &dv->ephemeral_key,
4832 &k);
4833 sign_ephemeral (dv);
4834 }
4892 box_hdr.ephemeral_key = dv->ephemeral_key; 4835 box_hdr.ephemeral_key = dv->ephemeral_key;
4893 payload_hdr.sender_sig = dv->sender_sig; 4836 payload_hdr.sender_sig = dv->sender_sig;
4894 4837
@@ -4896,10 +4839,9 @@ encapsulate_for_dv (struct DistanceVector *dv,
4896 &box_hdr.iv, 4839 &box_hdr.iv,
4897 sizeof(box_hdr.iv)); 4840 sizeof(box_hdr.iv));
4898 // We are creating this key, so this must work. 4841 // We are creating this key, so this must work.
4899 GNUNET_assert (GNUNET_OK == 4842 // FIXME: Possibly also add return values here. We are processing
4900 dh_key_derive_eph_pid (&dv->private_key, 4843 // Input from other peers...
4901 &dv->target, 4844 dv_setup_key_state_from_km (&k, &box_hdr.iv, key);
4902 &box_hdr.iv, key));
4903 payload_hdr.sender = GST_my_identity; 4845 payload_hdr.sender = GST_my_identity;
4904 payload_hdr.monotonic_time = GNUNET_TIME_absolute_hton (dv->monotime); 4846 payload_hdr.monotonic_time = GNUNET_TIME_absolute_hton (dv->monotime);
4905 dv_encrypt (key, &payload_hdr, enc, sizeof(payload_hdr)); 4847 dv_encrypt (key, &payload_hdr, enc, sizeof(payload_hdr));
@@ -8322,13 +8264,17 @@ handle_dv_box (void *cls, const struct TransportDVBoxMessage *dvb)
8322 cmc->total_hops = ntohs (dvb->total_hops); 8264 cmc->total_hops = ntohs (dvb->total_hops);
8323 8265
8324 // DH key derivation with received DV, could be garbage. 8266 // DH key derivation with received DV, could be garbage.
8325 if (GNUNET_OK != 8267 struct GNUNET_HashCode km;
8326 dh_key_derive_eph_pub (&dvb->ephemeral_key, &dvb->iv, &key)) 8268
8269 if (GNUNET_YES != GNUNET_CRYPTO_eddsa_kem_decaps (GST_my_private_key,
8270 &dvb->ephemeral_key,
8271 &km))
8327 { 8272 {
8328 GNUNET_break_op (0); 8273 GNUNET_break_op (0);
8329 finish_cmc_handling (cmc); 8274 finish_cmc_handling (cmc);
8330 return; 8275 return;
8331 } 8276 }
8277 dv_setup_key_state_from_km (&km, &dvb->iv, &key);
8332 hdr = (const char *) &dvb[1]; 8278 hdr = (const char *) &dvb[1];
8333 hdr_len = ntohs (dvb->orig_size) - sizeof(*dvb) - sizeof(struct 8279 hdr_len = ntohs (dvb->orig_size) - sizeof(*dvb) - sizeof(struct
8334 GNUNET_PeerIdentity) 8280 GNUNET_PeerIdentity)
diff --git a/src/transport/meson.build b/src/transport/meson.build
new file mode 100644
index 000000000..d997aad8a
--- /dev/null
+++ b/src/transport/meson.build
@@ -0,0 +1,320 @@
1libgnunettransport_src = ['transport_api_address_to_string.c',
2 'transport_api_blacklist.c',
3 'transport_api_core.c',
4 'transport_api_hello_get.c',
5 'transport_api_manipulation.c',
6 'transport_api_monitor_peers.c',
7 'transport_api_monitor_plugins.c',
8 'transport_api_offer_hello.c']
9libgnunettransportapplication_src = ['transport_api2_application.c']
10libgnunettransportcore_src = ['transport_api2_core.c']
11libgnunettransportcommunicator_src = ['transport_api2_communication.c']
12libgnunettransportmonitor_src = ['transport_api2_monitor.c']
13
14gnunetservicetransport_src = ['gnunet-service-tng.c']
15gnunetcommunicatortcp_src = ['gnunet-communicator-tcp.c']
16gnunetcommunicatorudp_src = ['gnunet-communicator-udp.c']
17gnunetcommunicatorunix_src = ['gnunet-communicator-unix.c']
18
19configure_file(input : 'transport.conf.in',
20 output : 'transport.conf',
21 configuration : cdata,
22 install: true,
23 install_dir: pkgcfgdir)
24
25configure_file(input : 'gnunet-transport-certificate-creation.in',
26 output : 'gnunet-transport-certificate-creation',
27 configuration : cdata,
28 install: true,
29 install_dir: get_option('bindir'))
30
31configure_file(input : 'communicator-unix.conf',
32 output : 'communicator-unix.conf',
33 configuration : cdata,
34 install: true,
35 install_dir: pkgcfgdir)
36
37if get_option('monolith')
38 foreach p : libgnunettransport_src #+ libgnunettransportapplication_src + libgnunettransportcore_src + libgnunettransportcommunicator_src + libgnunettransportmonitor_src + gnunetservicetransport_src
39 gnunet_src += 'transport/' + p
40 endforeach
41endif
42
43libgnunettransport = library('gnunettransport',
44 libgnunettransport_src,
45 soversion: '2',
46 version: '2.2.0',
47 dependencies: [libgnunetutil_dep, libgnunetats_dep, libgnunethello_dep],
48 include_directories: [incdir, configuration_inc],
49 install: true,
50 install_dir: get_option('libdir'))
51pkg.generate(libgnunettransport, url: 'https://www.gnunet.org',
52 description : 'Provides API for accessing the transport service')
53libgnunettransport_dep = declare_dependency(link_with : libgnunettransport)
54
55libgnunettransporttesting = library('gnunettransporttesting',
56 [
57 'transport-testing.c',
58 'transport-testing-filenames.c',
59 'transport-testing-loggers.c',
60 'transport-testing-main.c',
61 'transport-testing-send.c'
62 ],
63 soversion: '0',
64 version: '0.0.0',
65 dependencies: [libgnunetutil_dep,
66 libgnunettesting_dep,
67 libgnunettransport_dep,
68 libgnunetats_dep,
69 libgnunethello_dep],
70 include_directories: [incdir, configuration_inc],
71 install: true,
72 install_dir: get_option('libdir'))
73
74
75libgnunettransportapplication = library('gnunettransportapplication',
76 libgnunettransportapplication_src,
77 soversion: '0',
78 version: '0.0.0',
79 dependencies: libgnunetutil_dep,
80 include_directories: [incdir, configuration_inc],
81 install: true,
82 install_dir: get_option('libdir'))
83pkg.generate(libgnunettransportapplication, url: 'https://www.gnunet.org',
84 description : 'Provides application APIs for accessing the transport service')
85libgnunettransportapplication_dep = declare_dependency(link_with : libgnunettransportapplication)
86
87libgnunettransportcore = library('gnunettransportcore',
88 libgnunettransportcore_src,
89 soversion: '0',
90 version: '0.0.0',
91 dependencies: libgnunetutil_dep,
92 include_directories: [incdir, configuration_inc],
93 install: true,
94 install_dir: get_option('libdir'))
95pkg.generate(libgnunettransportcore, url: 'https://www.gnunet.org',
96 description : 'Provides core API for accessing the transport service')
97libgnunettransportcore_dep = declare_dependency(link_with : libgnunettransportcore)
98
99libgnunettransportcommunicator = library('gnunettransportcommunicator',
100 libgnunettransportcommunicator_src,
101 soversion: '0',
102 version: '0.0.0',
103 dependencies: libgnunetutil_dep,
104 include_directories: [incdir, configuration_inc],
105 install: true,
106 install_dir: get_option('libdir'))
107pkg.generate(libgnunettransportcommunicator, url: 'https://www.gnunet.org',
108 description : 'Provides communicator API for accessing the transport service')
109libgnunettransportcommunicator_dep = declare_dependency(link_with : libgnunettransportcommunicator)
110
111libgnunettransportmonitor = library('gnunettransportmonitor',
112 libgnunettransportmonitor_src,
113 soversion: '0',
114 version: '0.0.0',
115 dependencies: libgnunetutil_dep,
116 include_directories: [incdir, configuration_inc],
117 install: true,
118 install_dir: get_option('libdir'))
119pkg.generate(libgnunettransportmonitor, url: 'https://www.gnunet.org',
120 description : 'Provides monitor API for accessing the transport service')
121libgnunettransportmonitor_dep = declare_dependency(link_with : libgnunettransportmonitor)
122
123libgnunettransporttesting2 = library('gnunettransporttesting2',
124 [
125 'transport_api_traits.c',
126 'transport_api_cmd_connecting_peers.c',
127 'transport_api_cmd_backchannel_check.c',
128 'transport_api_cmd_start_peer.c',
129 'transport_api_cmd_stop_peer.c',
130 'transport_api_cmd_send_simple.c',
131 'transport_api_cmd_send_simple_performance.c',
132 'transport-testing2.c',
133 'transport-testing-filenames2.c',
134 'transport-testing-loggers2.c',
135 'transport-testing-main2.c',
136 'transport-testing-send2.c',
137 'transport-testing-communicator.c',
138 ],
139 soversion: '0',
140 version: '0.0.0',
141 dependencies: [libgnunetutil_dep,
142 libgnunettransportapplication_dep,
143 libgnunettransport_dep,
144 libgnunetpeerstore_dep,
145 libgnunetats_dep,
146 libgnunettesting_dep,
147 libgnunethello_dep],
148 include_directories: [incdir, configuration_inc],
149 install: true,
150 install_dir: get_option('libdir'))
151libgnunettransporttesting2_dep = declare_dependency(link_with : libgnunettransporttesting2)
152
153executable ('gnunet-service-transport',
154 gnunetservicetransport_src,
155 dependencies: [libgnunettransport_dep, libgnunetutil_dep,
156 libgnunethello_dep,
157 libgnunetpeerstore_dep,
158 m_dep,
159 libgnunetstatistics_dep,
160 gcrypt_dep],
161 include_directories: [incdir, configuration_inc],
162 install: true,
163 install_dir: get_option('libdir') / 'gnunet' / 'libexec')
164
165executable ('gnunet-communicator-unix',
166 gnunetcommunicatorunix_src,
167 dependencies: [libgnunettransportcommunicator_dep,
168 libgnunetpeerstore_dep,
169 libgnunetstatistics_dep,
170 libgnunetnt_dep,
171 libgnunetnat_dep,
172 gcrypt_dep,
173 libgnunetutil_dep],
174 include_directories: [incdir, configuration_inc],
175 install: true,
176 install_dir: get_option('libdir') / 'gnunet' / 'libexec')
177executable ('gnunet-communicator-udp',
178 gnunetcommunicatorudp_src,
179 dependencies: [libgnunettransportcommunicator_dep,
180 libgnunettransportapplication_dep,
181 libgnunetpeerstore_dep,
182 libgnunetstatistics_dep,
183 libgnunetnt_dep,
184 libgnunetnat_dep,
185 gcrypt_dep,
186 libgnunetutil_dep],
187 include_directories: [incdir, configuration_inc],
188 install: true,
189 install_dir: get_option('libdir') / 'gnunet' / 'libexec')
190executable ('gnunet-communicator-tcp',
191 gnunetcommunicatortcp_src,
192 dependencies: [libgnunettransportcommunicator_dep,
193 libgnunetpeerstore_dep,
194 libgnunetstatistics_dep,
195 libgnunetnt_dep,
196 libgnunetnat_dep,
197 gcrypt_dep,
198 libgnunetutil_dep],
199 include_directories: [incdir, configuration_inc],
200 install: true,
201 install_dir: get_option('libdir') / 'gnunet' / 'libexec')
202
203executable ('gnunet-transport',
204 ['gnunet-transport.c'],
205 dependencies: [libgnunettransportcommunicator_dep,
206 libgnunethello_dep,
207 libgnunettransport_dep,
208 libgnunetpeerstore_dep,
209 libgnunetutil_dep],
210 include_directories: [incdir, configuration_inc],
211 install: true,
212 install_dir: get_option('bindir'))
213
214libgnunettesttransport_cmd_simplesend = library('gnunet_test_transport_plugin_cmd_simple_send',
215 ['test_transport_plugin_cmd_simple_send.c'],
216 dependencies: [
217 libgnunetutil_dep,
218 libgnunettransporttesting2_dep,
219 libgnunettransportapplication_dep,
220 libgnunettransportcore_dep,
221 libgnunettesting_dep,
222 libgnunetpeerstore_dep,
223 libgnunetstatistics_dep,
224 libgnunethello_dep,
225 libgnunetarm_dep,
226 libgnunetutil_dep
227 ],
228 include_directories: [incdir, configuration_inc],
229 install: true,
230 install_dir: get_option('libdir')/'gnunet')
231
232libgnunettesttransport_cmd_simplesendbc = library('gnunet_test_transport_plugin_cmd_simple_send_broadcast',
233 ['test_transport_plugin_cmd_simple_send_broadcast.c'],
234 dependencies: [
235 libgnunetutil_dep,
236 libgnunettransporttesting2_dep,
237 libgnunettransportapplication_dep,
238 libgnunettransportcore_dep,
239 libgnunettesting_dep,
240 libgnunetpeerstore_dep,
241 libgnunetstatistics_dep,
242 libgnunethello_dep,
243 libgnunetarm_dep,
244 libgnunetutil_dep
245 ],
246 include_directories: [incdir, configuration_inc],
247 install: true,
248 install_dir: get_option('libdir')/'gnunet')
249
250libgnunettesttransport_cmd_simplesenddv = library('gnunet_test_transport_plugin_cmd_simple_send_dv',
251 ['test_transport_plugin_cmd_simple_send_dv.c'],
252 dependencies: [
253 libgnunetutil_dep,
254 libgnunettransporttesting2_dep,
255 libgnunettransportapplication_dep,
256 libgnunettransportcore_dep,
257 libgnunettesting_dep,
258 libgnunetpeerstore_dep,
259 libgnunetstatistics_dep,
260 libgnunethello_dep,
261 libgnunetarm_dep,
262 libgnunetutil_dep
263 ],
264 include_directories: [incdir, configuration_inc],
265 install: true,
266 install_dir: get_option('libdir')/'gnunet')
267
268libgnunettesttransport_cmd_simplesendperf = library('gnunet_test_transport_plugin_cmd_simple_send_performance',
269 ['test_transport_plugin_cmd_simple_send_performance.c'],
270 dependencies: [
271 libgnunetutil_dep,
272 libgnunettransporttesting2_dep,
273 libgnunettransportapplication_dep,
274 libgnunettransportcore_dep,
275 libgnunettesting_dep,
276 libgnunetpeerstore_dep,
277 libgnunetstatistics_dep,
278 libgnunethello_dep,
279 libgnunetarm_dep,
280 libgnunetutil_dep
281 ],
282 include_directories: [incdir, configuration_inc],
283 install: true,
284 install_dir: get_option('libdir')/'gnunet')
285
286libgnunettesttransport_cmd_udpback = library('gnunet_test_transport_plugin_cmd_udp_backchannel',
287 ['test_transport_plugin_cmd_udp_backchannel.c'],
288 dependencies: [
289 libgnunetutil_dep,
290 libgnunettransporttesting2_dep,
291 libgnunettransportapplication_dep,
292 libgnunettransportcore_dep,
293 libgnunettesting_dep,
294 libgnunetpeerstore_dep,
295 libgnunetstatistics_dep,
296 libgnunethello_dep,
297 libgnunetarm_dep,
298 libgnunetutil_dep
299 ],
300 include_directories: [incdir, configuration_inc],
301 install: true,
302 install_dir: get_option('libdir')/'gnunet')
303
304libgnunettesttransport_cmd_natupnp = library('gnunet_test_transport_plugin_cmd_nat_upnp',
305 ['test_transport_plugin_cmd_nat_upnp.c'],
306 dependencies: [
307 libgnunetutil_dep,
308 libgnunettransporttesting2_dep,
309 libgnunettransportapplication_dep,
310 libgnunettransportcore_dep,
311 libgnunettesting_dep,
312 libgnunetpeerstore_dep,
313 libgnunetstatistics_dep,
314 libgnunethello_dep,
315 libgnunetarm_dep,
316 libgnunetutil_dep
317 ],
318 include_directories: [incdir, configuration_inc],
319 install: true,
320 install_dir: get_option('libdir')/'gnunet')
diff --git a/src/transport/plugin_transport_http_common.c b/src/transport/plugin_transport_http_common.c
index 40353daeb..a033985e1 100644
--- a/src/transport/plugin_transport_http_common.c
+++ b/src/transport/plugin_transport_http_common.c
@@ -604,7 +604,7 @@ http_common_plugin_address_to_string (const char *plugin,
604 if (addr_str[ntohl (address->urlen) - 1] != '\0') 604 if (addr_str[ntohl (address->urlen) - 1] != '\0')
605 return NULL; 605 return NULL;
606 GNUNET_asprintf (&res, "%s.%u.%s", plugin, ntohl (address->options), 606 GNUNET_asprintf (&res, "%s.%u.%s", plugin, ntohl (address->options),
607 (char*)&address[1]); 607 (char*) &address[1]);
608 if (strlen (res) + 1 < 500) 608 if (strlen (res) + 1 < 500)
609 { 609 {
610 GNUNET_memcpy (rbuf, res, strlen (res) + 1); 610 GNUNET_memcpy (rbuf, res, strlen (res) + 1);
diff --git a/src/transport/plugin_transport_wlan.c b/src/transport/plugin_transport_wlan.c
index 138fb5080..3ac106859 100644
--- a/src/transport/plugin_transport_wlan.c
+++ b/src/transport/plugin_transport_wlan.c
@@ -1873,7 +1873,8 @@ handle_helper_message (void *cls,
1873 LOG (GNUNET_ERROR_TYPE_DEBUG, 1873 LOG (GNUNET_ERROR_TYPE_DEBUG,
1874 "Size of packet is too small (%llu bytes < %llu)\n", 1874 "Size of packet is too small (%llu bytes < %llu)\n",
1875 (unsigned long long) msize, 1875 (unsigned long long) msize,
1876 (unsigned long long) sizeof(struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)); 1876 (unsigned long long) sizeof(struct
1877 GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage));
1877 break; 1878 break;
1878 } 1879 }
1879 rxinfo = (const struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) hdr; 1880 rxinfo = (const struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) hdr;
diff --git a/src/transport/test_communicator_basic.c b/src/transport/test_communicator_basic.c
index 14d1a4792..fdbad0957 100644
--- a/src/transport/test_communicator_basic.c
+++ b/src/transport/test_communicator_basic.c
@@ -104,13 +104,13 @@ static unsigned int iterations_left[NUM_PEERS];
104#define TIMEOUT_MULTIPLIER 1 104#define TIMEOUT_MULTIPLIER 1
105 105
106#define DELAY \ 106#define DELAY \
107 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MICROSECONDS,200) 107 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MICROSECONDS,200)
108 108
109#define SHORT_BURST_WINDOW \ 109#define SHORT_BURST_WINDOW \
110 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,2) 110 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,2)
111 111
112#define LONG_BURST_WINDOW \ 112#define LONG_BURST_WINDOW \
113 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,2) 113 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,2)
114 114
115enum TestPhase 115enum TestPhase
116{ 116{
@@ -394,7 +394,8 @@ process_statistics (void *cls,
394 { 394 {
395 ret = 2; 395 ret = 2;
396 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 396 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
397 "Not enough BOX messages!\n"); 397 "Not enough BOX messages! (want: %u, have %llu)\n",
398 9000, value);
398 GNUNET_SCHEDULER_shutdown (); 399 GNUNET_SCHEDULER_shutdown ();
399 } 400 }
400 if ((0 == strcmp ("rekey", test_name)) && 401 if ((0 == strcmp ("rekey", test_name)) &&
@@ -405,7 +406,8 @@ process_statistics (void *cls,
405 { 406 {
406 ret = 2; 407 ret = 2;
407 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 408 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
408 "Not enough BOX messages!\n"); 409 "Not enough BOX messages! (want: %u, have %llu)\n",
410 6000, value);
409 GNUNET_SCHEDULER_shutdown (); 411 GNUNET_SCHEDULER_shutdown ();
410 } 412 }
411 return GNUNET_OK; 413 return GNUNET_OK;
@@ -432,11 +434,13 @@ short_test_cb (void *cls)
432 tc_h); 434 tc_h);
433 payload = make_payload (SHORT_MESSAGE_SIZE); 435 payload = make_payload (SHORT_MESSAGE_SIZE);
434 num_sent_short[peer_nr]++; 436 num_sent_short[peer_nr]++;
437 if (burst_packets_short == num_sent_short[peer_nr])
438 tc_h->cont = NULL;
439 else
440 tc_h->cont = short_test;
441 tc_h->cont_cls = cls;
435 GNUNET_TRANSPORT_TESTING_transport_communicator_send (tc_h, 442 GNUNET_TRANSPORT_TESTING_transport_communicator_send (tc_h,
436 (burst_packets_short == 443 NULL,
437 num_sent_short[peer_nr])
438 ? NULL
439 : &short_test,
440 cls, 444 cls,
441 payload, 445 payload,
442 SHORT_MESSAGE_SIZE); 446 SHORT_MESSAGE_SIZE);
@@ -477,11 +481,13 @@ size_test (void *cls)
477 ack[peer_nr] += 10; 481 ack[peer_nr] += 10;
478 payload = make_payload (ack[peer_nr]); 482 payload = make_payload (ack[peer_nr]);
479 num_sent_size[peer_nr]++; 483 num_sent_size[peer_nr]++;
484 if (ack[peer_nr] >= max_size)
485 tc_h->cont = NULL;
486 else
487 tc_h->cont = size_test;
488 tc_h->cont_cls = cls;
480 GNUNET_TRANSPORT_TESTING_transport_communicator_send (tc_h, 489 GNUNET_TRANSPORT_TESTING_transport_communicator_send (tc_h,
481 (ack[peer_nr] < 490 NULL,
482 max_size)
483 ? &size_test
484 : NULL,
485 cls, 491 cls,
486 payload, 492 payload,
487 ack[peer_nr]); 493 ack[peer_nr]);
@@ -511,11 +517,13 @@ long_test_cb (void *cls)
511 (unsigned int) num_received_long[peer_nr]); 517 (unsigned int) num_received_long[peer_nr]);
512 payload = make_payload (long_message_size); 518 payload = make_payload (long_message_size);
513 num_sent_long[peer_nr]++; 519 num_sent_long[peer_nr]++;
520 if (burst_packets_long == num_sent_long[peer_nr])
521 tc_h->cont = NULL;
522 else
523 tc_h->cont = long_test;
524 tc_h->cont_cls = cls;
514 GNUNET_TRANSPORT_TESTING_transport_communicator_send (tc_h, 525 GNUNET_TRANSPORT_TESTING_transport_communicator_send (tc_h,
515 (burst_packets_long == 526 NULL,
516 num_sent_long[peer_nr])
517 ? NULL
518 : &long_test,
519 cls, 527 cls,
520 payload, 528 payload,
521 long_message_size); 529 long_message_size);
@@ -784,7 +792,7 @@ add_queue_cb (void *cls,
784 return; 792 return;
785 LOG (GNUNET_ERROR_TYPE_DEBUG, 793 LOG (GNUNET_ERROR_TYPE_DEBUG,
786 "Queue established, starting test...\n"); 794 "Queue established, starting test...\n");
787 if (UINT32_MAX != mtu) /* Message header overhead */ 795 if (UINT16_MAX != mtu) /* Message header overhead */
788 long_message_size = mtu - sizeof(struct GNUNET_TRANSPORT_SendMessageTo) 796 long_message_size = mtu - sizeof(struct GNUNET_TRANSPORT_SendMessageTo)
789 - sizeof(struct GNUNET_MessageHeader); 797 - sizeof(struct GNUNET_MessageHeader);
790 else 798 else
@@ -935,7 +943,8 @@ incoming_message_cb (
935 if (long_message_size != payload_len) 943 if (long_message_size != payload_len)
936 { 944 {
937 LOG (GNUNET_ERROR_TYPE_WARNING, 945 LOG (GNUNET_ERROR_TYPE_WARNING,
938 "Ignoring packet with wrong length\n"); 946 "Ignoring packet with wrong length (have: %lu, want: %lu)\n",
947 payload_len, long_message_size);
939 return; // Ignore 948 return; // Ignore
940 } 949 }
941 num_received_long[peer_nr]++; 950 num_received_long[peer_nr]++;
@@ -1086,7 +1095,7 @@ main (int argc,
1086 phase[0] = TP_INIT; 1095 phase[0] = TP_INIT;
1087 phase[1] = TP_INIT; 1096 phase[1] = TP_INIT;
1088 ret = 1; 1097 ret = 1;
1089 test_name = GNUNET_TESTING_get_testname_from_underscore (argv[0]); 1098 test_name = GNUNET_STRINGS_get_suffix_from_binary_name (argv[0]);
1090 communicator_name = strchr (test_name, '-'); 1099 communicator_name = strchr (test_name, '-');
1091 communicator_name[0] = '\0'; 1100 communicator_name[0] = '\0';
1092 communicator_name++; 1101 communicator_name++;
diff --git a/src/transport/test_communicator_quic_basic_peer1.conf b/src/transport/test_communicator_quic_basic_peer1.conf
new file mode 100644
index 000000000..d43752ecc
--- /dev/null
+++ b/src/transport/test_communicator_quic_basic_peer1.conf
@@ -0,0 +1,45 @@
1@INLINE@ test_transport_defaults.conf
2
3[PATHS]
4GNUNET_TEST_HOME = $GNUNET_TMP/test-communicator-unix-1/
5
6[PEER]
7PRIVATE_KEY = $GNUNET_TMP/test-communicator-unix-1/private.key
8
9[transport-tcp]
10PORT = 52400
11
12[transport-udp]
13PORT = 52401
14
15[transport-quic]
16PORT = 52402
17
18[transport]
19#PORT = 60000
20UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-transport_test_1.sock
21
22[nat]
23UNIXPATH = $GNUNET_TMP/test-communicator-unix-1/nat.sock
24ENABLE_IPSCAN = YES
25
26[peerstore]
27UNIXPATH = $GNUNET_TMP/test-communicator-unix-1/peerstore.sock
28
29[statistics]
30PORT = 22461
31UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-statistics_test_1.sock
32
33[resolver]
34PORT = 62089
35UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-resolver_test_1.sock
36
37[communicator-udp]
38# PREFIX = valgrind --leak-check=full --track-origins=yes --log-file=/tmp/vg_com1
39BINDTO = 60002
40DISABLE_V6 = YES
41MAX_QUEUE_LENGTH=5000
42
43[communicator-quic]
44BINDTO = 60002
45DISABLE_V6 = YES
diff --git a/src/transport/test_communicator_quic_basic_peer2.conf b/src/transport/test_communicator_quic_basic_peer2.conf
new file mode 100644
index 000000000..4fabc8a86
--- /dev/null
+++ b/src/transport/test_communicator_quic_basic_peer2.conf
@@ -0,0 +1,45 @@
1@INLINE@ test_transport_defaults.conf
2
3[PATHS]
4GNUNET_TEST_HOME = $GNUNET_TMP/test-gnunetd-plugin-transport/
5
6[PEER]
7PRIVATE_KEY = $GNUNET_TMP/test-communicator-unix-2/private.key
8
9[transport-tcp]
10PORT = 52400
11
12[transport-udp]
13PORT = 52402
14
15[transport-quic]
16PORT = 52403
17
18[transport]
19#PORT = 60001
20UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-transport_test_2.sock
21
22[nat]
23UNIXPATH = $GNUNET_TMP/test-communicator-unix-2/nat.sock
24
25
26[peerstore]
27UNIXPATH = $GNUNET_TMP/test-communicator-unix-2/peerstore.sock
28
29[statistics]
30PORT = 22462
31UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-statistics_test_2.sock
32
33[resolver]
34PORT = 62090
35UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-resolver_test_2.sock
36
37[communicator-udp]
38# PREFIX = valgrind --leak-check=full --track-origins=yes --log-file=/tmp/vg_com2
39BINDTO = 60003
40DISABLE_V6 = YES
41MAX_QUEUE_LENGTH=5000
42
43[communicator-quic]
44BINDTO = 60003
45DISABLE_V6 = YES \ No newline at end of file
diff --git a/src/transport/test_communicator_udp_backchannel_peer1.conf b/src/transport/test_communicator_udp_backchannel_peer1.conf
index 59e6d68e3..65f33bd6b 100644
--- a/src/transport/test_communicator_udp_backchannel_peer1.conf
+++ b/src/transport/test_communicator_udp_backchannel_peer1.conf
@@ -39,7 +39,7 @@ BINDTO = 60002
39DISABLE_V6 = YES 39DISABLE_V6 = YES
40 40
41[communicator-udp] 41[communicator-udp]
42#PREFIX = valgrind --leak-check=full --track-origins=yes 42# PREFIX = valgrind --leak-check=full --track-origins=yes --log-file=/tmp/vg_comm1
43BINDTO = 60002 43BINDTO = 60002
44DISABLE_V6 = YES 44DISABLE_V6 = YES
45MAX_QUEUE_LENGTH=5000 45MAX_QUEUE_LENGTH=5000
diff --git a/src/transport/test_communicator_udp_backchannel_peer2.conf b/src/transport/test_communicator_udp_backchannel_peer2.conf
index 3abf7999b..9875af724 100644
--- a/src/transport/test_communicator_udp_backchannel_peer2.conf
+++ b/src/transport/test_communicator_udp_backchannel_peer2.conf
@@ -39,7 +39,7 @@ BINDTO = 60003
39DISABLE_V6 = YES 39DISABLE_V6 = YES
40 40
41[communicator-udp] 41[communicator-udp]
42#PREFIX = valgrind --leak-check=full --track-origins=yes 42# PREFIX = valgrind --leak-check=full --track-origins=yes --log-file=/tmp/vg_comm2
43BINDTO = 60003 43BINDTO = 60003
44DISABLE_V6 = YES 44DISABLE_V6 = YES
45MAX_QUEUE_LENGTH=5000 45MAX_QUEUE_LENGTH=5000
diff --git a/src/transport/test_communicator_udp_basic_peer1.conf b/src/transport/test_communicator_udp_basic_peer1.conf
index c6ff024ee..6968b3aef 100644
--- a/src/transport/test_communicator_udp_basic_peer1.conf
+++ b/src/transport/test_communicator_udp_basic_peer1.conf
@@ -32,7 +32,8 @@ PORT = 62089
32UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-resolver_test_1.sock 32UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-resolver_test_1.sock
33 33
34[communicator-udp] 34[communicator-udp]
35#PREFIX = valgrind --leak-check=full --track-origins=yes 35# PREFIX = valgrind --leak-check=full --track-origins=yes --log-file=/tmp/vg_com1
36BINDTO = 60002 36BINDTO = 60002
37DISABLE_V6 = YES 37DISABLE_V6 = YES
38MAX_QUEUE_LENGTH=5000 38MAX_QUEUE_LENGTH=5000
39
diff --git a/src/transport/test_communicator_udp_basic_peer2.conf b/src/transport/test_communicator_udp_basic_peer2.conf
index b353b03e9..781bfa7da 100644
--- a/src/transport/test_communicator_udp_basic_peer2.conf
+++ b/src/transport/test_communicator_udp_basic_peer2.conf
@@ -33,7 +33,7 @@ PORT = 62090
33UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-resolver_test_2.sock 33UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-resolver_test_2.sock
34 34
35[communicator-udp] 35[communicator-udp]
36#PREFIX = valgrind --leak-check=full --track-origins=yes 36# PREFIX = valgrind --leak-check=full --track-origins=yes --log-file=/tmp/vg_com2
37BINDTO = 60003 37BINDTO = 60003
38DISABLE_V6 = YES 38DISABLE_V6 = YES
39MAX_QUEUE_LENGTH=5000 39MAX_QUEUE_LENGTH=5000
diff --git a/src/transport/test_communicator_udp_rekey_peer1.conf b/src/transport/test_communicator_udp_rekey_peer1.conf
index 6bfeafe33..9b0fa7497 100644
--- a/src/transport/test_communicator_udp_rekey_peer1.conf
+++ b/src/transport/test_communicator_udp_rekey_peer1.conf
@@ -45,7 +45,8 @@ REKEY_INTERVAL = 100ms
45BINDTO = 60002 45BINDTO = 60002
46DISABLE_V6 = YES 46DISABLE_V6 = YES
47MAX_QUEUE_LENGTH=5000 47MAX_QUEUE_LENGTH=5000
48REKEY_MAX_BYTES=9MiB 48REKEY_INTERVAL = 100ms
49REKEY_MAX_BYTES=9KiB
49 50
50[communicator-test] 51[communicator-test]
51BACKCHANNEL_ENABLED = YES 52BACKCHANNEL_ENABLED = YES
diff --git a/src/transport/test_communicator_udp_rekey_peer2.conf b/src/transport/test_communicator_udp_rekey_peer2.conf
index 474ca0c15..383ab19d2 100644
--- a/src/transport/test_communicator_udp_rekey_peer2.conf
+++ b/src/transport/test_communicator_udp_rekey_peer2.conf
@@ -45,7 +45,8 @@ REKEY_INTERVAL = 100ms
45BINDTO = 60003 45BINDTO = 60003
46DISABLE_V6 = YES 46DISABLE_V6 = YES
47MAX_QUEUE_LENGTH=5000 47MAX_QUEUE_LENGTH=5000
48REKEY_MAX_BYTES=9MiB 48REKEY_INTERVAL = 100ms
49REKEY_MAX_BYTES=9KiB
49 50
50[communicator-test] 51[communicator-test]
51BACKCHANNEL_ENABLED = YES 52BACKCHANNEL_ENABLED = YES
diff --git a/src/transport/test_transport_api2.c b/src/transport/test_transport_api2.c
index e1606e0be..4d423f7c2 100644
--- a/src/transport/test_transport_api2.c
+++ b/src/transport/test_transport_api2.c
@@ -28,7 +28,7 @@
28 * C code apparently. 28 * C code apparently.
29 */ 29 */
30#include "platform.h" 30#include "platform.h"
31//#include "gnunet_transport_service.h" 31// #include "gnunet_transport_service.h"
32#include "transport-testing2.h" 32#include "transport-testing2.h"
33 33
34/** 34/**
diff --git a/src/transport/test_transport_plugin_cmd_nat_upnp.c b/src/transport/test_transport_plugin_cmd_nat_upnp.c
index 5c5e71e85..31206e63f 100644
--- a/src/transport/test_transport_plugin_cmd_nat_upnp.c
+++ b/src/transport/test_transport_plugin_cmd_nat_upnp.c
@@ -90,7 +90,7 @@ handle_test (void *cls,
90struct GNUNET_TESTING_BarrierList* 90struct GNUNET_TESTING_BarrierList*
91get_waiting_for_barriers () 91get_waiting_for_barriers ()
92{ 92{
93 struct GNUNET_TESTING_BarrierList* barriers; 93 struct GNUNET_TESTING_BarrierList*barriers;
94 struct GNUNET_TESTING_BarrierListEntry *ble; 94 struct GNUNET_TESTING_BarrierListEntry *ble;
95 95
96 barriers = GNUNET_new (struct GNUNET_TESTING_BarrierList); 96 barriers = GNUNET_new (struct GNUNET_TESTING_BarrierList);
@@ -209,7 +209,7 @@ all_local_tests_prepared ()
209 * the topology configuration. 209 * the topology configuration.
210 * @param read_file If read_file is GNUNET_YES this string is the filename for the topology configuration, 210 * @param read_file If read_file is GNUNET_YES this string is the filename for the topology configuration,
211 * if read_file is GNUNET_NO the string contains the topology configuration. 211 * if read_file is GNUNET_NO the string contains the topology configuration.
212 * @param finish_cb Callback function which writes a message from the helper process running on a netjail 212 * @param finish_cb Callback function which writes a message from the helper process running on a netjail
213 * node to the master process * signaling that the test case running on the netjail node finished. 213 * node to the master process * signaling that the test case running on the netjail node finished.
214 * @return Returns the struct GNUNET_TESTING_Interpreter of the command loop running on this netjail node. 214 * @return Returns the struct GNUNET_TESTING_Interpreter of the command loop running on this netjail node.
215 */ 215 */
@@ -358,9 +358,9 @@ start_testcase (GNUNET_TESTING_cmd_helper_write_cb write_message,
358 ts->write_message = write_message; 358 ts->write_message = write_message;
359 359
360 is = GNUNET_TESTING_run (commands, 360 is = GNUNET_TESTING_run (commands,
361 TIMEOUT, 361 TIMEOUT,
362 &handle_result, 362 &handle_result,
363 ts); 363 ts);
364 return is; 364 return is;
365} 365}
366 366
diff --git a/src/transport/test_transport_plugin_cmd_simple_send.c b/src/transport/test_transport_plugin_cmd_simple_send.c
index 0c9bfa890..d83c539fa 100644
--- a/src/transport/test_transport_plugin_cmd_simple_send.c
+++ b/src/transport/test_transport_plugin_cmd_simple_send.c
@@ -90,7 +90,7 @@ handle_test (void *cls,
90struct GNUNET_TESTING_BarrierList * 90struct GNUNET_TESTING_BarrierList *
91get_waiting_for_barriers () 91get_waiting_for_barriers ()
92{ 92{
93 //No Barrier 93 // No Barrier
94 return GNUNET_new (struct GNUNET_TESTING_BarrierList); 94 return GNUNET_new (struct GNUNET_TESTING_BarrierList);
95} 95}
96 96
@@ -327,9 +327,9 @@ start_testcase (GNUNET_TESTING_cmd_helper_write_cb write_message,
327 ts->write_message = write_message; 327 ts->write_message = write_message;
328 328
329 is = GNUNET_TESTING_run (commands, 329 is = GNUNET_TESTING_run (commands,
330 TIMEOUT, 330 TIMEOUT,
331 &handle_result, 331 &handle_result,
332 ts); 332 ts);
333 return is; 333 return is;
334} 334}
335 335
diff --git a/src/transport/test_transport_plugin_cmd_simple_send_broadcast.c b/src/transport/test_transport_plugin_cmd_simple_send_broadcast.c
index 7381b1d7e..7000851c4 100644
--- a/src/transport/test_transport_plugin_cmd_simple_send_broadcast.c
+++ b/src/transport/test_transport_plugin_cmd_simple_send_broadcast.c
@@ -90,7 +90,7 @@ handle_test (void *cls,
90struct GNUNET_TESTING_BarrierList * 90struct GNUNET_TESTING_BarrierList *
91get_waiting_for_barriers () 91get_waiting_for_barriers ()
92{ 92{
93 //No Barrier 93 // No Barrier
94 return GNUNET_new (struct GNUNET_TESTING_BarrierList); 94 return GNUNET_new (struct GNUNET_TESTING_BarrierList);
95} 95}
96 96
@@ -147,12 +147,11 @@ static void *
147notify_connect (struct GNUNET_TESTING_Interpreter *is, 147notify_connect (struct GNUNET_TESTING_Interpreter *is,
148 const struct GNUNET_PeerIdentity *peer) 148 const struct GNUNET_PeerIdentity *peer)
149{ 149{
150 const struct GNUNET_TESTING_AsyncContext *ac; 150 struct GNUNET_TESTING_AsyncContext *ac;
151 void *ret = NULL; 151 void *ret = NULL;
152 const struct GNUNET_TESTING_Command *cmd; 152 const struct GNUNET_TESTING_Command *cmd;
153 struct GNUNET_TESTING_BlockState *bs; 153 struct GNUNET_TESTING_BlockState *bs;
154 154
155
156 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 155 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
157 "notify_connect\n"); 156 "notify_connect\n");
158 157
@@ -165,9 +164,9 @@ notify_connect (struct GNUNET_TESTING_Interpreter *is,
165 "notify_connect running\n"); 164 "notify_connect running\n");
166 GNUNET_assert (NULL != ac); 165 GNUNET_assert (NULL != ac);
167 if (NULL == ac->cont) 166 if (NULL == ac->cont)
168 GNUNET_TESTING_async_fail ((struct GNUNET_TESTING_AsyncContext *) ac); 167 GNUNET_TESTING_async_fail (ac);
169 else 168 else
170 GNUNET_TESTING_async_finish ((struct GNUNET_TESTING_AsyncContext *) ac); 169 GNUNET_TESTING_async_finish (ac);
171 } 170 }
172 else 171 else
173 { 172 {
@@ -179,7 +178,7 @@ notify_connect (struct GNUNET_TESTING_Interpreter *is,
179 cmd->label); 178 cmd->label);
180 GNUNET_TESTING_get_trait_block_state ( 179 GNUNET_TESTING_get_trait_block_state (
181 cmd, 180 cmd,
182 (const struct GNUNET_TESTING_BlockState **) &bs); 181 &bs);
183 182
184 LOG (GNUNET_ERROR_TYPE_DEBUG, 183 LOG (GNUNET_ERROR_TYPE_DEBUG,
185 "block state %u\n", 184 "block state %u\n",
@@ -353,9 +352,9 @@ start_testcase (GNUNET_TESTING_cmd_helper_write_cb write_message,
353 ts->write_message = write_message; 352 ts->write_message = write_message;
354 353
355 is = GNUNET_TESTING_run (commands, 354 is = GNUNET_TESTING_run (commands,
356 TIMEOUT, 355 TIMEOUT,
357 &handle_result, 356 &handle_result,
358 ts); 357 ts);
359 return is; 358 return is;
360} 359}
361 360
diff --git a/src/transport/test_transport_plugin_cmd_simple_send_dv.c b/src/transport/test_transport_plugin_cmd_simple_send_dv.c
index ac3e8b24b..c07fd3cf4 100644
--- a/src/transport/test_transport_plugin_cmd_simple_send_dv.c
+++ b/src/transport/test_transport_plugin_cmd_simple_send_dv.c
@@ -113,7 +113,7 @@ handle_test (void *cls,
113 GNUNET_TESTING_get_trait_async_context (&block_receive, 113 GNUNET_TESTING_get_trait_async_context (&block_receive,
114 &ac_block); 114 &ac_block);
115 115
116 if ( connected == number_received) 116 if (connected == number_received)
117 { 117 {
118 if (NULL != ac_block->is) 118 if (NULL != ac_block->is)
119 { 119 {
@@ -142,7 +142,7 @@ handle_test (void *cls,
142struct GNUNET_TESTING_BarrierList * 142struct GNUNET_TESTING_BarrierList *
143get_waiting_for_barriers () 143get_waiting_for_barriers ()
144{ 144{
145 //No Barrier 145 // No Barrier
146 return GNUNET_new (struct GNUNET_TESTING_BarrierList); 146 return GNUNET_new (struct GNUNET_TESTING_BarrierList);
147} 147}
148 148
@@ -201,19 +201,21 @@ notify_connect (struct GNUNET_TESTING_Interpreter *is,
201{ 201{
202 const struct ConnectPeersState *cps; 202 const struct ConnectPeersState *cps;
203 const struct GNUNET_TESTING_Command *cmd; 203 const struct GNUNET_TESTING_Command *cmd;
204 void *ret = NULL;
205 204
206 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 205 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
207 "notify_connect peer %s\n", 206 "notify_connect peer %s\n",
208 GNUNET_i2s (peer)); 207 GNUNET_i2s (peer));
208 // FIXME: modifying future is a bit unclean, not easy to follow logic;
209 // might be better to when reaching the future command to look into
210 // the past...
209 cmd = GNUNET_TESTING_interpreter_lookup_command_all (is, 211 cmd = GNUNET_TESTING_interpreter_lookup_command_all (is,
210 "connect-peers"); 212 "connect-peers");
213 // FIXME: check return value!
211 GNUNET_TRANSPORT_get_trait_connect_peer_state (cmd, 214 GNUNET_TRANSPORT_get_trait_connect_peer_state (cmd,
212 &cps); 215 &cps);
213 cps->notify_connect (is, 216 cps->notify_connect (is,
214 peer); 217 peer);
215 218 return NULL;
216 return ret;
217} 219}
218 220
219 221
@@ -382,9 +384,9 @@ start_testcase (GNUNET_TESTING_cmd_helper_write_cb write_message,
382 ts->write_message = write_message; 384 ts->write_message = write_message;
383 385
384 is = GNUNET_TESTING_run (commands, 386 is = GNUNET_TESTING_run (commands,
385 TIMEOUT, 387 TIMEOUT,
386 &handle_result, 388 &handle_result,
387 ts); 389 ts);
388 return is; 390 return is;
389} 391}
390 392
diff --git a/src/transport/test_transport_plugin_cmd_udp_backchannel.c b/src/transport/test_transport_plugin_cmd_udp_backchannel.c
index 5f411e20e..303790afc 100644
--- a/src/transport/test_transport_plugin_cmd_udp_backchannel.c
+++ b/src/transport/test_transport_plugin_cmd_udp_backchannel.c
@@ -155,6 +155,7 @@ notify_connect (struct GNUNET_TESTING_Interpreter *is,
155 return ret; 155 return ret;
156} 156}
157 157
158
158/** 159/**
159 * Callback to set the flag indicating all peers are prepared to finish. Will be called via the plugin api. 160 * Callback to set the flag indicating all peers are prepared to finish. Will be called via the plugin api.
160 */ 161 */
@@ -173,6 +174,7 @@ all_local_tests_prepared ()
173 GNUNET_TESTING_AsyncContext *) &lfs->ac); 174 GNUNET_TESTING_AsyncContext *) &lfs->ac);
174} 175}
175 176
177
176/** 178/**
177 * Function to start a local test case. 179 * Function to start a local test case.
178 * 180 *
diff --git a/src/transport/test_transport_start_with_config.c b/src/transport/test_transport_start_with_config.c
index a2c692dbc..349cd65a5 100644
--- a/src/transport/test_transport_start_with_config.c
+++ b/src/transport/test_transport_start_with_config.c
@@ -94,13 +94,13 @@ main (int argc,
94 topology_data_script, 94 topology_data_script,
95 &read_file), 95 &read_file),
96 GNUNET_TESTING_cmd_netjail_start_cmds_helper ("netjail-start-testbed", 96 GNUNET_TESTING_cmd_netjail_start_cmds_helper ("netjail-start-testbed",
97 topology, 97 topology,
98 &read_file, 98 &read_file,
99 topology_data_script, 99 topology_data_script,
100 TIMEOUT), 100 TIMEOUT),
101 GNUNET_TESTING_cmd_stop_cmds_helper ("stop-testbed", 101 GNUNET_TESTING_cmd_stop_cmds_helper ("stop-testbed",
102 "netjail-start-testbed", 102 "netjail-start-testbed",
103 topology), 103 topology),
104 GNUNET_TESTING_cmd_netjail_stop ("netjail-stop", 104 GNUNET_TESTING_cmd_netjail_stop ("netjail-stop",
105 topology_data_script, 105 topology_data_script,
106 &read_file), 106 &read_file),
diff --git a/src/transport/transport-testing-communicator.c b/src/transport/transport-testing-communicator.c
index 1bf88bb3d..26895e457 100644
--- a/src/transport/transport-testing-communicator.c
+++ b/src/transport/transport-testing-communicator.c
@@ -676,8 +676,13 @@ handle_send_message_ack (void *cls,
676 const struct GNUNET_TRANSPORT_SendMessageToAck *sma) 676 const struct GNUNET_TRANSPORT_SendMessageToAck *sma)
677{ 677{
678 struct MyClient *client = cls; 678 struct MyClient *client = cls;
679 struct GNUNET_TRANSPORT_TESTING_TransportCommunicatorHandle *tc_h =
680 client->tc;
681 static int mtr = 0;
682 mtr++;
683 if (tc_h->cont != NULL)
684 tc_h->cont (tc_h->cont_cls);
679 GNUNET_SERVICE_client_continue (client->client); 685 GNUNET_SERVICE_client_continue (client->client);
680 // NOP
681} 686}
682 687
683 688
@@ -772,6 +777,7 @@ shutdown_process (struct GNUNET_OS_Process *proc)
772 GNUNET_OS_process_destroy (proc); 777 GNUNET_OS_process_destroy (proc);
773} 778}
774 779
780
775/** 781/**
776 * @brief Task run at shutdown to kill the statistics process 782 * @brief Task run at shutdown to kill the statistics process
777 * 783 *
@@ -784,6 +790,7 @@ shutdown_statistics (void *cls)
784 shutdown_process (proc); 790 shutdown_process (proc);
785} 791}
786 792
793
787/** 794/**
788 * @brief Task run at shutdown to kill the peerstore process 795 * @brief Task run at shutdown to kill the peerstore process
789 * 796 *
@@ -796,6 +803,7 @@ shutdown_peerstore (void *cls)
796 shutdown_process (proc); 803 shutdown_process (proc);
797} 804}
798 805
806
799/** 807/**
800 * @brief Task run at shutdown to kill a communicator process 808 * @brief Task run at shutdown to kill a communicator process
801 * 809 *
@@ -913,6 +921,7 @@ resolver_start (struct
913 921
914} 922}
915 923
924
916/** 925/**
917 * @brief Start Statistics 926 * @brief Start Statistics
918 * 927 *
@@ -942,6 +951,7 @@ statistics_start (
942 GNUNET_free (binary); 951 GNUNET_free (binary);
943} 952}
944 953
954
945/** 955/**
946 * @brief Start Peerstore 956 * @brief Start Peerstore
947 * 957 *
@@ -971,6 +981,7 @@ peerstore_start (
971 GNUNET_free (binary); 981 GNUNET_free (binary);
972} 982}
973 983
984
974/** 985/**
975 * @brief Start NAT 986 * @brief Start NAT
976 * 987 *
@@ -1160,8 +1171,9 @@ GNUNET_TRANSPORT_TESTING_transport_communicator_send
1160 size_t inbox_size; 1171 size_t inbox_size;
1161 struct GNUNET_TRANSPORT_TESTING_TransportCommunicatorQueue *tc_queue; 1172 struct GNUNET_TRANSPORT_TESTING_TransportCommunicatorQueue *tc_queue;
1162 struct GNUNET_TRANSPORT_TESTING_TransportCommunicatorQueue *tc_queue_tmp; 1173 struct GNUNET_TRANSPORT_TESTING_TransportCommunicatorQueue *tc_queue_tmp;
1163 1174 static struct GNUNET_TRANSPORT_TESTING_TransportCommunicatorQueue *last_queue;
1164 tc_queue = NULL; 1175 tc_queue = NULL;
1176
1165 for (tc_queue_tmp = tc_h->queue_head; 1177 for (tc_queue_tmp = tc_h->queue_head;
1166 NULL != tc_queue_tmp; 1178 NULL != tc_queue_tmp;
1167 tc_queue_tmp = tc_queue_tmp->next) 1179 tc_queue_tmp = tc_queue_tmp->next)
@@ -1188,19 +1200,28 @@ GNUNET_TRANSPORT_TESTING_transport_communicator_send
1188 tc_queue = tc_queue_tmp; 1200 tc_queue = tc_queue_tmp;
1189 } 1201 }
1190 } 1202 }
1203 if (last_queue != tc_queue)
1204 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1205 "Selected sending queue changed to %u with length %lu and MTU %u\n",
1206 ntohl (tc_queue->qid), tc_queue->q_len, tc_queue->mtu);
1191 GNUNET_assert (NULL != tc_queue); 1207 GNUNET_assert (NULL != tc_queue);
1208 last_queue = tc_queue;
1192 // Uncomment this for alternativ 1 of backchannel functionality 1209 // Uncomment this for alternativ 1 of backchannel functionality
1193 if (tc_queue->q_len != GNUNET_TRANSPORT_QUEUE_LENGTH_UNLIMITED) 1210 if (tc_queue->q_len != GNUNET_TRANSPORT_QUEUE_LENGTH_UNLIMITED)
1194 tc_queue->q_len--; 1211 tc_queue->q_len--;
1195 // Until here for alternativ 1 1212 // Until here for alternativ 1
1196 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1213 static int msg_count = 0;
1197 "Sending message\n"); 1214 msg_count++;
1215 if (msg_count % 100 == 0)
1216 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1217 "Sending %u-th (%lu-th for queue) message on queue %u\n",
1218 msg_count, tc_queue->mid, ntohl (tc_queue->qid));
1198 inbox_size = sizeof (struct GNUNET_MessageHeader) + payload_size; 1219 inbox_size = sizeof (struct GNUNET_MessageHeader) + payload_size;
1199 env = GNUNET_MQ_msg_extra (msg, 1220 env = GNUNET_MQ_msg_extra (msg,
1200 inbox_size, 1221 inbox_size,
1201 GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_MSG); 1222 GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_MSG);
1202 GNUNET_assert (NULL != env); 1223 GNUNET_assert (NULL != env);
1203 msg->qid = htonl (tc_queue->qid); 1224 msg->qid = tc_queue->qid;
1204 msg->mid = tc_queue->mid++; 1225 msg->mid = tc_queue->mid++;
1205 msg->receiver = tc_queue->peer_id; 1226 msg->receiver = tc_queue->peer_id;
1206 mh = (struct GNUNET_MessageHeader *) &msg[1]; 1227 mh = (struct GNUNET_MessageHeader *) &msg[1];
diff --git a/src/transport/transport-testing-communicator.h b/src/transport/transport-testing-communicator.h
index 1875258b4..122ac3efa 100644
--- a/src/transport/transport-testing-communicator.h
+++ b/src/transport/transport-testing-communicator.h
@@ -282,6 +282,16 @@ struct GNUNET_TRANSPORT_TESTING_TransportCommunicatorHandle
282 void *cb_cls; 282 void *cb_cls;
283 283
284 /** 284 /**
285 * Callback to call when message ack received.
286 */
287 GNUNET_SCHEDULER_TaskCallback cont;
288
289 /**
290 * Closure for cont
291 */
292 void *cont_cls;
293
294 /**
285 * Backchannel supported 295 * Backchannel supported
286 */ 296 */
287 int bc_enabled; 297 int bc_enabled;
diff --git a/src/transport/transport-testing2.c b/src/transport/transport-testing2.c
index 566e0db71..ec27ac8ba 100644
--- a/src/transport/transport-testing2.c
+++ b/src/transport/transport-testing2.c
@@ -329,6 +329,7 @@ notify_disconnect (void *cls,
329 } 329 }
330} 330}
331 331
332
332static void 333static void
333retrieve_hello (void *cls); 334retrieve_hello (void *cls);
334 335
diff --git a/src/transport/transport.conf.in b/src/transport/transport.conf.in
index c6b207ad7..96b87e266 100644
--- a/src/transport/transport.conf.in
+++ b/src/transport/transport.conf.in
@@ -235,3 +235,7 @@ INTERFACE = hci0
235# Real hardware, no testing 235# Real hardware, no testing
236TESTMODE = 0 236TESTMODE = 0
237TESTING_IGNORE_KEYS = ACCEPT_FROM; 237TESTING_IGNORE_KEYS = ACCEPT_FROM;
238
239
240[communicator-quic]
241BINDTO = 127.0.0.1 \ No newline at end of file
diff --git a/src/transport/transport_api_cmd_backchannel_check.c b/src/transport/transport_api_cmd_backchannel_check.c
index d672e3ae8..1bdb8817f 100644
--- a/src/transport/transport_api_cmd_backchannel_check.c
+++ b/src/transport/transport_api_cmd_backchannel_check.c
@@ -330,6 +330,7 @@ will_the_other_node_connect_via_udp (
330 return GNUNET_NO; 330 return GNUNET_NO;
331} 331}
332 332
333
333static void 334static void
334add_search_string (struct CheckState *cs, const struct 335add_search_string (struct CheckState *cs, const struct
335 GNUNET_TESTING_NetjailNode *node) 336 GNUNET_TESTING_NetjailNode *node)
diff --git a/src/transport/transport_api_cmd_connecting_peers.c b/src/transport/transport_api_cmd_connecting_peers.c
index 8ff206a23..33991bc29 100644
--- a/src/transport/transport_api_cmd_connecting_peers.c
+++ b/src/transport/transport_api_cmd_connecting_peers.c
@@ -139,10 +139,10 @@ connect_peers_run (void *cls,
139 char *rest2; 139 char *rest2;
140 char *address; 140 char *address;
141 141
142 prefix = strtok(addr, "_"); 142 prefix = strtok (addr, "_");
143 rest = strtok(NULL, "_"); 143 rest = strtok (NULL, "_");
144 rest2 = strtok(rest, "-"); 144 rest2 = strtok (rest, "-");
145 address = strtok(NULL, "-"); 145 address = strtok (NULL, "-");
146 146
147 GNUNET_asprintf (&addr_and_port, 147 GNUNET_asprintf (&addr_and_port,
148 "%s-%s:0", 148 "%s-%s:0",
@@ -186,20 +186,23 @@ notify_connect (struct GNUNET_TESTING_Interpreter *is,
186 const struct GNUNET_TESTING_Command *cmd; 186 const struct GNUNET_TESTING_Command *cmd;
187 struct ConnectPeersState *cps; 187 struct ConnectPeersState *cps;
188 struct GNUNET_PeerIdentity *peer_connection; 188 struct GNUNET_PeerIdentity *peer_connection;
189 struct GNUNET_TESTING_NodeConnection *pos_connection;
190 unsigned int num; 189 unsigned int num;
191 unsigned int con_num; 190 unsigned int con_num;
192 void *ret = NULL; 191 void *ret = NULL;
193 192
194 cmd = GNUNET_TESTING_interpreter_lookup_command_all (is, 193 cmd = GNUNET_TESTING_interpreter_lookup_command_all (is,
195 "connect-peers"); 194 "connect-peers");
196 cps = cmd->cls; 195 cps = cmd->cls; // WTF? Never go directly into cls of another command! FIXME!
197 con_num = cps->con_num_notified; 196 con_num = cps->con_num_notified;
198 for (pos_connection = cps->node_connections_head; NULL != pos_connection; 197 for (struct GNUNET_TESTING_NodeConnection *pos_connection =
198 cps->node_connections_head;
199 NULL != pos_connection;
199 pos_connection = pos_connection->next) 200 pos_connection = pos_connection->next)
200 { 201 {
201 num = GNUNET_TESTING_calculate_num (pos_connection, cps->topology); 202 num = GNUNET_TESTING_calculate_num (pos_connection,
202 peer_connection = GNUNET_TESTING_get_peer (num, cps->tl_system); 203 cps->topology);
204 peer_connection = GNUNET_TESTING_get_peer (num,
205 cps->tl_system);
203 if (0 == GNUNET_memcmp (peer, 206 if (0 == GNUNET_memcmp (peer,
204 peer_connection)) 207 peer_connection))
205 cps->con_num_notified++; 208 cps->con_num_notified++;
diff --git a/src/transport/transport_api_cmd_start_peer.c b/src/transport/transport_api_cmd_start_peer.c
index c4098e26d..54e204a21 100644
--- a/src/transport/transport_api_cmd_start_peer.c
+++ b/src/transport/transport_api_cmd_start_peer.c
@@ -385,7 +385,7 @@ start_peer_cleanup (void *cls)
385 GNUNET_free (sps->handlers); 385 GNUNET_free (sps->handlers);
386 sps->handlers = NULL; 386 sps->handlers = NULL;
387 } 387 }
388 //TODO Investigate why this caused problems during shutdown. 388 // TODO Investigate why this caused problems during shutdown.
389 /*if (NULL != sps->cfg) 389 /*if (NULL != sps->cfg)
390 { 390 {
391 GNUNET_CONFIGURATION_destroy (sps->cfg); 391 GNUNET_CONFIGURATION_destroy (sps->cfg);