aboutsummaryrefslogtreecommitdiff
path: root/src/cadet
diff options
context:
space:
mode:
Diffstat (limited to 'src/cadet')
-rw-r--r--src/cadet/.gitignore3
-rw-r--r--src/cadet/Makefile.am116
-rw-r--r--src/cadet/TODO36
-rw-r--r--src/cadet/cadet.conf.in32
-rw-r--r--src/cadet/cadet.h2
-rw-r--r--src/cadet/cadet_api.c1794
-rw-r--r--src/cadet/cadet_common.c370
-rw-r--r--src/cadet/cadet_path.c363
-rw-r--r--src/cadet/cadet_path.h226
-rw-r--r--src/cadet/cadet_protocol.h193
-rw-r--r--src/cadet/cadet_test_lib.c133
-rw-r--r--src/cadet/cadet_test_lib.h40
-rw-r--r--src/cadet/desirability_table.c35
-rw-r--r--src/cadet/gnunet-cadet-profiler.c4
-rw-r--r--src/cadet/gnunet-cadet.c630
-rw-r--r--src/cadet/gnunet-service-cadet-new.c1428
-rw-r--r--src/cadet/gnunet-service-cadet-new_channel.c1613
-rw-r--r--src/cadet/gnunet-service-cadet-new_channel.h249
-rw-r--r--src/cadet/gnunet-service-cadet-new_connection.c709
-rw-r--r--src/cadet/gnunet-service-cadet-new_connection.h207
-rw-r--r--src/cadet/gnunet-service-cadet-new_dht.c351
-rw-r--r--src/cadet/gnunet-service-cadet-new_dht.h100
-rw-r--r--src/cadet/gnunet-service-cadet-new_hello.c152
-rw-r--r--src/cadet/gnunet-service-cadet-new_hello.h80
-rw-r--r--src/cadet/gnunet-service-cadet-new_peer.c1282
-rw-r--r--src/cadet/gnunet-service-cadet-new_peer.h380
-rw-r--r--src/cadet/gnunet-service-cadet.c1488
-rw-r--r--src/cadet/gnunet-service-cadet.h (renamed from src/cadet/gnunet-service-cadet-new.h)53
-rw-r--r--src/cadet/gnunet-service-cadet_channel.c3515
-rw-r--r--src/cadet/gnunet-service-cadet_channel.h393
-rw-r--r--src/cadet/gnunet-service-cadet_connection.c4010
-rw-r--r--src/cadet/gnunet-service-cadet_connection.h605
-rw-r--r--src/cadet/gnunet-service-cadet_core.c (renamed from src/cadet/gnunet-service-cadet-new_core.c)606
-rw-r--r--src/cadet/gnunet-service-cadet_core.h (renamed from src/cadet/gnunet-service-cadet-new_core.h)0
-rw-r--r--src/cadet/gnunet-service-cadet_dht.c373
-rw-r--r--src/cadet/gnunet-service-cadet_dht.h49
-rw-r--r--src/cadet/gnunet-service-cadet_hello.c140
-rw-r--r--src/cadet/gnunet-service-cadet_hello.h5
-rw-r--r--src/cadet/gnunet-service-cadet_local.c1553
-rw-r--r--src/cadet/gnunet-service-cadet_local.h234
-rw-r--r--src/cadet/gnunet-service-cadet_paths.c (renamed from src/cadet/gnunet-service-cadet-new_paths.c)119
-rw-r--r--src/cadet/gnunet-service-cadet_paths.h (renamed from src/cadet/gnunet-service-cadet-new_paths.h)2
-rw-r--r--src/cadet/gnunet-service-cadet_peer.c2928
-rw-r--r--src/cadet/gnunet-service-cadet_peer.h516
-rw-r--r--src/cadet/gnunet-service-cadet_tunnel.c3501
-rw-r--r--src/cadet/gnunet-service-cadet_tunnel.h616
-rw-r--r--src/cadet/gnunet-service-cadet_tunnels.c (renamed from src/cadet/gnunet-service-cadet-new_tunnels.c)1712
-rw-r--r--src/cadet/gnunet-service-cadet_tunnels.h (renamed from src/cadet/gnunet-service-cadet-new_tunnels.h)85
-rw-r--r--src/cadet/test_cadet.c819
-rw-r--r--src/cadet/test_cadet_local.c351
-rw-r--r--src/cadet/test_cadet_local_mq.c332
-rw-r--r--src/cadet/test_cadet_single.c354
52 files changed, 9515 insertions, 25372 deletions
diff --git a/src/cadet/.gitignore b/src/cadet/.gitignore
index 096ee06eb..44382fde9 100644
--- a/src/cadet/.gitignore
+++ b/src/cadet/.gitignore
@@ -19,3 +19,6 @@ test_cadet_5_speed_reliable
19test_cadet_5_speed_reliable_backwards 19test_cadet_5_speed_reliable_backwards
20test_cadet_local 20test_cadet_local
21test_cadet_single 21test_cadet_single
22gnunet-service-cadet-new
23test_cadet_local_mq
24test_cadet_*_new \ No newline at end of file
diff --git a/src/cadet/Makefile.am b/src/cadet/Makefile.am
index 53d17dd9c..ce30ebe46 100644
--- a/src/cadet/Makefile.am
+++ b/src/cadet/Makefile.am
@@ -23,24 +23,24 @@ AM_CLFAGS = -g
23 23
24libexec_PROGRAMS = \ 24libexec_PROGRAMS = \
25 gnunet-service-cadet \ 25 gnunet-service-cadet \
26 gnunet-service-cadet-new \
27 $(EXP_LIBEXEC) 26 $(EXP_LIBEXEC)
28 27
29bin_PROGRAMS = \ 28bin_PROGRAMS = \
30 gnunet-cadet 29 gnunet-cadet
31 30
32lib_LTLIBRARIES = \ 31lib_LTLIBRARIES = \
33 libgnunetcadet.la $(EXP_LIB) 32 libgnunetcadet.la \
33 $(EXP_LIB)
34 34
35libgnunetcadet_la_SOURCES = \ 35libgnunetcadet_la_SOURCES = \
36 cadet_api.c cadet_common.c 36 cadet_api.c
37libgnunetcadet_la_LIBADD = \ 37libgnunetcadet_la_LIBADD = \
38 $(top_builddir)/src/util/libgnunetutil.la \ 38 $(top_builddir)/src/util/libgnunetutil.la \
39 $(XLIB) \ 39 $(XLIB) \
40 $(LTLIBINTL) 40 $(LTLIBINTL)
41libgnunetcadet_la_LDFLAGS = \ 41libgnunetcadet_la_LDFLAGS = \
42 $(GN_LIB_LDFLAGS) $(WINFLAGS) \ 42 $(GN_LIB_LDFLAGS) $(WINFLAGS) \
43 -version-info 5:0:0 43 -version-info 7:0:0
44 44
45gnunet_cadet_SOURCES = \ 45gnunet_cadet_SOURCES = \
46 gnunet-cadet.c 46 gnunet-cadet.c
@@ -48,46 +48,23 @@ gnunet_cadet_LDADD = \
48 libgnunetcadet.la \ 48 libgnunetcadet.la \
49 $(top_builddir)/src/util/libgnunetutil.la 49 $(top_builddir)/src/util/libgnunetutil.la
50 50
51gnunet_service_cadet_new_SOURCES = \
52 gnunet-service-cadet-new.c gnunet-service-cadet-new.h \
53 gnunet-service-cadet-new_channel.c gnunet-service-cadet-new_channel.h \
54 gnunet-service-cadet-new_connection.c gnunet-service-cadet-new_connection.h \
55 gnunet-service-cadet-new_core.c gnunet-service-cadet-new_core.h \
56 gnunet-service-cadet-new_dht.c gnunet-service-cadet-new_dht.h \
57 gnunet-service-cadet-new_hello.c gnunet-service-cadet-new_hello.h \
58 gnunet-service-cadet-new_tunnels.c gnunet-service-cadet-new_tunnels.h \
59 gnunet-service-cadet-new_paths.c gnunet-service-cadet-new_paths.h \
60 gnunet-service-cadet-new_peer.c gnunet-service-cadet-new_peer.h
61gnunet_service_cadet_new_LDADD = \
62 $(top_builddir)/src/util/libgnunetutil.la \
63 $(top_builddir)/src/ats/libgnunetats.la \
64 $(top_builddir)/src/core/libgnunetcore.la \
65 $(top_builddir)/src/dht/libgnunetdht.la \
66 $(top_builddir)/src/statistics/libgnunetstatistics.la \
67 $(top_builddir)/src/transport/libgnunettransport.la \
68 $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \
69 $(top_builddir)/src/hello/libgnunethello.la \
70 $(top_builddir)/src/block/libgnunetblock.la
71
72gnunet_service_cadet_SOURCES = \ 51gnunet_service_cadet_SOURCES = \
73 gnunet-service-cadet_tunnel.c gnunet-service-cadet_tunnel.h \ 52 gnunet-service-cadet.c gnunet-service-cadet.h \
74 gnunet-service-cadet_connection.c gnunet-service-cadet_connection.h \
75 gnunet-service-cadet_channel.c gnunet-service-cadet_channel.h \ 53 gnunet-service-cadet_channel.c gnunet-service-cadet_channel.h \
76 gnunet-service-cadet_local.c gnunet-service-cadet_local.h \ 54 gnunet-service-cadet_connection.c gnunet-service-cadet_connection.h \
77 gnunet-service-cadet_peer.c gnunet-service-cadet_peer.h \ 55 gnunet-service-cadet_core.c gnunet-service-cadet_core.h \
78 gnunet-service-cadet_dht.c gnunet-service-cadet_dht.h \ 56 gnunet-service-cadet_dht.c gnunet-service-cadet_dht.h \
79 gnunet-service-cadet_hello.c gnunet-service-cadet_hello.h \ 57 gnunet-service-cadet_hello.c gnunet-service-cadet_hello.h \
80 cadet_path.c cadet_path.h \ 58 gnunet-service-cadet_tunnels.c gnunet-service-cadet_tunnels.h \
81 cadet_common.c \ 59 gnunet-service-cadet_paths.c gnunet-service-cadet_paths.h \
82 gnunet-service-cadet.c 60 gnunet-service-cadet_peer.c gnunet-service-cadet_peer.h
83gnunet_service_cadet_CFLAGS = $(AM_CFLAGS)
84gnunet_service_cadet_LDADD = \ 61gnunet_service_cadet_LDADD = \
85 $(top_builddir)/src/util/libgnunetutil.la \ 62 $(top_builddir)/src/util/libgnunetutil.la \
86 $(top_builddir)/src/transport/libgnunettransport.la \
87 $(top_builddir)/src/core/libgnunetcore.la \
88 $(top_builddir)/src/ats/libgnunetats.la \ 63 $(top_builddir)/src/ats/libgnunetats.la \
64 $(top_builddir)/src/core/libgnunetcore.la \
89 $(top_builddir)/src/dht/libgnunetdht.la \ 65 $(top_builddir)/src/dht/libgnunetdht.la \
90 $(top_builddir)/src/statistics/libgnunetstatistics.la \ 66 $(top_builddir)/src/statistics/libgnunetstatistics.la \
67 $(top_builddir)/src/transport/libgnunettransport.la \
91 $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ 68 $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \
92 $(top_builddir)/src/hello/libgnunethello.la \ 69 $(top_builddir)/src/hello/libgnunethello.la \
93 $(top_builddir)/src/block/libgnunetblock.la 70 $(top_builddir)/src/block/libgnunetblock.la
@@ -97,26 +74,14 @@ endif
97 74
98 75
99if HAVE_TESTING 76if HAVE_TESTING
100 noinst_LIBRARIES = libgnunetcadettest.a $(noinst_LIB_EXP) 77 noinst_LTLIBRARIES = libgnunetcadettest.la $(noinst_LIB_EXP)
101 noinst_PROGRAMS = gnunet-cadet-profiler 78# noinst_PROGRAMS = gnunet-cadet-profiler
102endif 79endif
103 80
104libgnunetcadettest_a_SOURCES = \
105 cadet_test_lib.c cadet_test_lib.h
106libgnunetcadettest_a_LIBADD = \
107 $(top_builddir)/src/util/libgnunetutil.la \
108 $(top_builddir)/src/testbed/libgnunettestbed.la \
109 libgnunetcadet.la
110
111if HAVE_TESTING 81if HAVE_TESTING
112check_PROGRAMS = \ 82check_PROGRAMS = \
113 test_cadet_2_speed_reliable_backwards \ 83 test_cadet_local_mq \
114 test_cadet_5_speed \ 84 test_cadet_2_forward \
115 test_cadet_5_speed_ack \
116 test_cadet_5_speed_reliable \
117 test_cadet_5_speed_reliable_backwards \
118 test_cadet_single \
119 test_cadet_local \
120 test_cadet_2_forward \ 85 test_cadet_2_forward \
121 test_cadet_2_signal \ 86 test_cadet_2_signal \
122 test_cadet_2_keepalive \ 87 test_cadet_2_keepalive \
@@ -124,40 +89,50 @@ check_PROGRAMS = \
124 test_cadet_2_speed_ack \ 89 test_cadet_2_speed_ack \
125 test_cadet_2_speed_backwards \ 90 test_cadet_2_speed_backwards \
126 test_cadet_2_speed_reliable \ 91 test_cadet_2_speed_reliable \
92 test_cadet_2_speed_reliable_backwards \
127 test_cadet_5_forward \ 93 test_cadet_5_forward \
128 test_cadet_5_signal \ 94 test_cadet_5_signal \
129 test_cadet_5_keepalive \ 95 test_cadet_5_keepalive \
96 test_cadet_5_speed \
97 test_cadet_5_speed_ack \
98 test_cadet_5_speed_reliable \
99 test_cadet_5_speed_reliable_backwards \
130 test_cadet_5_speed_backwards 100 test_cadet_5_speed_backwards
131endif 101endif
132 102
103
104#gnunet_cadet_profiler_SOURCES = \
105# gnunet-cadet-profiler.c
106#gnunet_cadet_profiler_LDADD = $(ld_cadet_test_lib)
107
108
109test_cadet_local_mq_SOURCES = \
110 test_cadet_local_mq.c
111test_cadet_local_mq_LDADD = \
112 libgnunetcadet.la \
113 $(top_builddir)/src/testing/libgnunettesting.la \
114 $(top_builddir)/src/util/libgnunetutil.la
115
116
117libgnunetcadettest_la_SOURCES = \
118 cadet_test_lib.c cadet_test_lib.h
119libgnunetcadettest_la_LIBADD = \
120 $(top_builddir)/src/util/libgnunetutil.la \
121 $(top_builddir)/src/testbed/libgnunettestbed.la \
122 libgnunetcadet.la
123
133ld_cadet_test_lib = \ 124ld_cadet_test_lib = \
134 $(top_builddir)/src/util/libgnunetutil.la \ 125 $(top_builddir)/src/util/libgnunetutil.la \
135 $(top_builddir)/src/testing/libgnunettesting.la \ 126 $(top_builddir)/src/testing/libgnunettesting.la \
136 libgnunetcadettest.a \
137 libgnunetcadet.la \ 127 libgnunetcadet.la \
128 libgnunetcadettest.la \
138 $(top_builddir)/src/testbed/libgnunettestbed.la \ 129 $(top_builddir)/src/testbed/libgnunettestbed.la \
139 $(top_builddir)/src/statistics/libgnunetstatistics.la 130 $(top_builddir)/src/statistics/libgnunetstatistics.la
140
141dep_cadet_test_lib = \ 131dep_cadet_test_lib = \
142 libgnunetcadet.la \ 132 libgnunetcadet.la \
143 libgnunetcadettest.a \ 133 libgnunetcadettest.la \
144 $(top_builddir)/src/statistics/libgnunetstatistics.la 134 $(top_builddir)/src/statistics/libgnunetstatistics.la
145 135
146
147gnunet_cadet_profiler_SOURCES = \
148 gnunet-cadet-profiler.c
149gnunet_cadet_profiler_LDADD = $(ld_cadet_test_lib)
150
151
152test_cadet_single_SOURCES = \
153 test_cadet_single.c
154test_cadet_single_LDADD = $(ld_cadet_test_lib)
155
156test_cadet_local_SOURCES = \
157 test_cadet_local.c
158test_cadet_local_LDADD = $(ld_cadet_test_lib)
159
160
161test_cadet_2_forward_SOURCES = \ 136test_cadet_2_forward_SOURCES = \
162 test_cadet.c 137 test_cadet.c
163test_cadet_2_forward_LDADD = $(ld_cadet_test_lib) 138test_cadet_2_forward_LDADD = $(ld_cadet_test_lib)
@@ -190,7 +165,6 @@ test_cadet_2_speed_reliable_backwards_SOURCES = \
190 test_cadet.c 165 test_cadet.c
191test_cadet_2_speed_reliable_backwards_LDADD = $(ld_cadet_test_lib) 166test_cadet_2_speed_reliable_backwards_LDADD = $(ld_cadet_test_lib)
192 167
193
194test_cadet_5_forward_SOURCES = \ 168test_cadet_5_forward_SOURCES = \
195 test_cadet.c 169 test_cadet.c
196test_cadet_5_forward_LDADD = $(ld_cadet_test_lib) 170test_cadet_5_forward_LDADD = $(ld_cadet_test_lib)
@@ -225,7 +199,7 @@ test_cadet_5_speed_reliable_backwards_LDADD = $(ld_cadet_test_lib)
225 199
226 200
227if ENABLE_TEST_RUN 201if ENABLE_TEST_RUN
228AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH; 202AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME;
229TESTS = \ 203TESTS = \
230 $(check_PROGRAMS) 204 $(check_PROGRAMS)
231endif 205endif
diff --git a/src/cadet/TODO b/src/cadet/TODO
new file mode 100644
index 000000000..06567b0ad
--- /dev/null
+++ b/src/cadet/TODO
@@ -0,0 +1,36 @@
1- URGENT:
2 + if 'client-not-ready', we do not ACK at all, and sender keeps
3 retransmitting again and again; would be good to do flow-control notification instead
4 of not ACKing that we got the data but are simply not ready for more!
5 + Congestion/flow control (CHANNEL):
6 estimate max bandwidth using bursts and use to for CONGESTION CONTROL!
7 (and figure out how/where to use this!)
8
9- HIGH: revisit handling of 'unbuffered' traffic! (CHANNEL/TUNNEL)
10 (need to push down through tunnel into connection selection);
11 At Tunnel-level, try to create connections that match channel
12 preferences (buffered/unbuffered) and select connections for
13 channel traffic that match channel preferences.
14 BUT: not sure this is ideal, discloses traffic type to
15 routers. We don't want that! (Maybe revise decision to do this?)
16
17- HIGH: revisit handling of 'buffered' traffic: 4 is a rather small buffer; (CHANNEL)
18 maybe reserve more bits in 'options' to allow for buffer size control?
19 Or: maybe even better, calculated required buffer size based on latency
20 and throughput (and available memory)
21
22- HIGH: if we receive BROKEN messages, cut down corresponding PATH (up to the
23 point of breakage) as well as connection/route (CORE)
24
25- OPTIMIZATION: proper connection evaluation during connection management:
26 + TUNNELS:
27 * consider quality of current connection set when deciding
28 how often to do maintenance
29 * interact with PEER to drive DHT GET/PUT operations based
30 on how much we like our connections
31
32
33- OPTIMIZATION: optimize stopping/restarting DHT search to situations
34 where we actually need it (i.e. not if we have a direct connection,
35 or if we already have plenty of good short ones, or maybe even
36 to take a break if we have some connections and have searched a lot (?)) (PEER)
diff --git a/src/cadet/cadet.conf.in b/src/cadet/cadet.conf.in
index 48fd03329..d50e168f0 100644
--- a/src/cadet/cadet.conf.in
+++ b/src/cadet/cadet.conf.in
@@ -11,13 +11,43 @@ UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-cadet.sock
11UNIX_MATCH_UID = YES 11UNIX_MATCH_UID = YES
12UNIX_MATCH_GID = YES 12UNIX_MATCH_GID = YES
13 13
14
15# How often do we send KEEPALIVE messages on connections to keep them
16# from timing out?
14REFRESH_CONNECTION_TIME = 5 min 17REFRESH_CONNECTION_TIME = 5 min
18
19# Percentage of packets CADET is artificially dropping. Used for testing only!
20# DROP_PERCENT =
21
22# How frequently do we usually anounce our presence in the DHT?
15ID_ANNOUNCE_TIME = 1 h 23ID_ANNOUNCE_TIME = 1 h
24
25# FIXME: document
16CONNECT_TIMEOUT = 30 s 26CONNECT_TIMEOUT = 30 s
27
28# What is the replication level we give to the DHT when announcing our
29# existence? Usually there is no need to change this.
17DHT_REPLICATION_LEVEL = 3 30DHT_REPLICATION_LEVEL = 3
18MAX_TUNNELS = 1000 31
32# FIXME: not implemented
33# MAX_TUNNELS = 1000
34
35# FIXME: not implemented, replaced by MAX_ROUTES in NEW CADET!
19MAX_CONNECTIONS = 1000 36MAX_CONNECTIONS = 1000
37
38# How many routes do we participate in at most? Should be smaller
39# than MAX_MSGS_QUEUE
40MAX_ROUTES = 5000
41
42# FIXME: not implemented
20MAX_MSGS_QUEUE = 10000 43MAX_MSGS_QUEUE = 10000
44
45# FIXME: not implemented
21MAX_PEERS = 1000 46MAX_PEERS = 1000
47
48# How often do we advance the ratchet even if there is not
49# any traffic?
22RATCHET_TIME = 1 h 50RATCHET_TIME = 1 h
51
52# How often do we advance the ratched if there is traffic?
23RATCHET_MESSAGES = 64 53RATCHET_MESSAGES = 64
diff --git a/src/cadet/cadet.h b/src/cadet/cadet.h
index 451d1f354..99f9f2653 100644
--- a/src/cadet/cadet.h
+++ b/src/cadet/cadet.h
@@ -59,7 +59,7 @@ extern "C"
59#include "gnunet_core_service.h" 59#include "gnunet_core_service.h"
60#include "gnunet_cadet_service.h" 60#include "gnunet_cadet_service.h"
61#include "gnunet_protocols.h" 61#include "gnunet_protocols.h"
62#include <gnunet_cadet_service.h> 62#include "gnunet_cadet_service.h"
63 63
64/******************************************************************************/ 64/******************************************************************************/
65/************************** CONSTANTS ******************************/ 65/************************** CONSTANTS ******************************/
diff --git a/src/cadet/cadet_api.c b/src/cadet/cadet_api.c
index 72b7b692d..decf473a9 100644
--- a/src/cadet/cadet_api.c
+++ b/src/cadet/cadet_api.c
@@ -21,8 +21,8 @@
21 * @file cadet/cadet_api.c 21 * @file cadet/cadet_api.c
22 * @brief cadet api: client implementation of cadet service 22 * @brief cadet api: client implementation of cadet service
23 * @author Bartlomiej Polot 23 * @author Bartlomiej Polot
24 * @author Christian Grothoff
24 */ 25 */
25
26#include "platform.h" 26#include "platform.h"
27#include "gnunet_util_lib.h" 27#include "gnunet_util_lib.h"
28#include "gnunet_constants.h" 28#include "gnunet_constants.h"
@@ -32,55 +32,9 @@
32 32
33#define LOG(kind,...) GNUNET_log_from (kind, "cadet-api",__VA_ARGS__) 33#define LOG(kind,...) GNUNET_log_from (kind, "cadet-api",__VA_ARGS__)
34 34
35/******************************************************************************/
36/************************ DATA STRUCTURES ****************************/
37/******************************************************************************/
38
39/** 35/**
40 * Transmission queue to the service 36 * Ugly legacy hack.
41 */ 37 */
42struct GNUNET_CADET_TransmitHandle
43{
44 /**
45 * Double Linked list
46 */
47 struct GNUNET_CADET_TransmitHandle *next;
48
49 /**
50 * Double Linked list
51 */
52 struct GNUNET_CADET_TransmitHandle *prev;
53
54 /**
55 * Channel this message is sent on / for (may be NULL for control messages).
56 */
57 struct GNUNET_CADET_Channel *channel;
58
59 /**
60 * Request data task.
61 */
62 struct GNUNET_SCHEDULER_Task *request_data_task;
63
64 /**
65 * Callback to obtain the message to transmit, or NULL if we
66 * got the message in 'data'. Notice that messages built
67 * by 'notify' need to be encapsulated with information about
68 * the 'target'.
69 */
70 GNUNET_CONNECTION_TransmitReadyNotify notify;
71
72 /**
73 * Closure for 'notify'
74 */
75 void *notify_cls;
76
77 /**
78 * Size of the payload.
79 */
80 size_t size;
81};
82
83
84union CadetInfoCB 38union CadetInfoCB
85{ 39{
86 40
@@ -117,54 +71,19 @@ union CadetInfoCB
117struct GNUNET_CADET_Handle 71struct GNUNET_CADET_Handle
118{ 72{
119 /** 73 /**
120 * Message queue (if available). 74 * Message queue.
121 */ 75 */
122 struct GNUNET_MQ_Handle *mq; 76 struct GNUNET_MQ_Handle *mq;
123 77
124 /** 78 /**
125 * Set of handlers used for processing incoming messages in the channels
126 */
127 const struct GNUNET_CADET_MessageHandler *message_handlers;
128
129 /**
130 * Number of handlers in the handlers array.
131 */
132 unsigned int n_handlers;
133
134 /**
135 * Ports open. 79 * Ports open.
136 */ 80 */
137 struct GNUNET_CONTAINER_MultiHashMap *ports; 81 struct GNUNET_CONTAINER_MultiHashMap *ports;
138 82
139 /** 83 /**
140 * Double linked list of the channels this client is connected to, head. 84 * Channels open.
141 */
142 struct GNUNET_CADET_Channel *channels_head;
143
144 /**
145 * Double linked list of the channels this client is connected to, tail.
146 */ 85 */
147 struct GNUNET_CADET_Channel *channels_tail; 86 struct GNUNET_CONTAINER_MultiHashMap32 *channels;
148
149 /**
150 * Callback for inbound channel disconnection
151 */
152 GNUNET_CADET_ChannelEndHandler *cleaner;
153
154 /**
155 * Closure for all the handlers given by the client
156 */
157 void *cls;
158
159 /**
160 * Messages to send to the service, head.
161 */
162 struct GNUNET_CADET_TransmitHandle *th_head;
163
164 /**
165 * Messages to send to the service, tail.
166 */
167 struct GNUNET_CADET_TransmitHandle *th_tail;
168 87
169 /** 88 /**
170 * child of the next channel to create (to avoid reusing IDs often) 89 * child of the next channel to create (to avoid reusing IDs often)
@@ -177,14 +96,9 @@ struct GNUNET_CADET_Handle
177 const struct GNUNET_CONFIGURATION_Handle *cfg; 96 const struct GNUNET_CONFIGURATION_Handle *cfg;
178 97
179 /** 98 /**
180 * Time to the next reconnect in case one reconnect fails
181 */
182 struct GNUNET_TIME_Relative reconnect_time;
183
184 /**
185 * Task for trying to reconnect. 99 * Task for trying to reconnect.
186 */ 100 */
187 struct GNUNET_SCHEDULER_Task * reconnect_task; 101 struct GNUNET_SCHEDULER_Task *reconnect_task;
188 102
189 /** 103 /**
190 * Callback for an info task (only one active at a time). 104 * Callback for an info task (only one active at a time).
@@ -195,65 +109,73 @@ struct GNUNET_CADET_Handle
195 * Info callback closure for @c info_cb. 109 * Info callback closure for @c info_cb.
196 */ 110 */
197 void *info_cls; 111 void *info_cls;
112
113 /**
114 * Time to the next reconnect in case one reconnect fails
115 */
116 struct GNUNET_TIME_Relative reconnect_time;
117
198}; 118};
199 119
200 120
201/** 121/**
202 * Description of a peer 122 * Opaque handle to a channel.
203 */ 123 */
204struct GNUNET_CADET_Peer 124struct GNUNET_CADET_Channel
205{ 125{
126
206 /** 127 /**
207 * ID of the peer in short form 128 * Other end of the channel.
208 */ 129 */
209 GNUNET_PEER_Id id; 130 struct GNUNET_PeerIdentity peer;
210 131
211 /** 132 /**
212 * Channel this peer belongs to 133 * Handle to the cadet this channel belongs to
213 */ 134 */
214 struct GNUNET_CADET_Channel *t; 135 struct GNUNET_CADET_Handle *cadet;
215};
216 136
137 /**
138 * Channel's port, if incoming.
139 */
140 struct GNUNET_CADET_Port *incoming_port;
217 141
218/**
219 * Opaque handle to a channel.
220 */
221struct GNUNET_CADET_Channel
222{
223 /** 142 /**
224 * DLL next 143 * Any data the caller wants to put in here, used for the
144 * various callbacks (@e disconnects, @e window_changes, handlers).
225 */ 145 */
226 struct GNUNET_CADET_Channel *next; 146 void *ctx;
227 147
228 /** 148 /**
229 * DLL prev 149 * Message Queue for the channel (which we are implementing).
230 */ 150 */
231 struct GNUNET_CADET_Channel *prev; 151 struct GNUNET_MQ_Handle *mq;
232 152
233 /** 153 /**
234 * Handle to the cadet this channel belongs to 154 * Task to allow mq to send more traffic.
235 */ 155 */
236 struct GNUNET_CADET_Handle *cadet; 156 struct GNUNET_SCHEDULER_Task *mq_cont;
237 157
238 /** 158 /**
239 * Local ID of the channel 159 * Pending envelope with a message to be transmitted to the
160 * service as soon as we are allowed to. Should only be
161 * non-NULL if @e allow_send is 0.
240 */ 162 */
241 struct GNUNET_CADET_ClientChannelNumber ccn; 163 struct GNUNET_MQ_Envelope *pending_env;
242 164
243 /** 165 /**
244 * Channel's port, if any. 166 * Window change handler.
245 */ 167 */
246 struct GNUNET_CADET_Port *port; 168 GNUNET_CADET_WindowSizeEventHandler window_changes;
247 169
248 /** 170 /**
249 * Other end of the channel. 171 * Disconnect handler.
250 */ 172 */
251 GNUNET_PEER_Id peer; 173 GNUNET_CADET_DisconnectEventHandler disconnects;
252 174
253 /** 175 /**
254 * Any data the caller wants to put in here 176 * Local ID of the channel, #GNUNET_CADET_LOCAL_CHANNEL_ID_CLI bit is set if outbound.
255 */ 177 */
256 void *ctx; 178 struct GNUNET_CADET_ClientChannelNumber ccn;
257 179
258 /** 180 /**
259 * Channel options: reliability, etc. 181 * Channel options: reliability, etc.
@@ -261,7 +183,7 @@ struct GNUNET_CADET_Channel
261 enum GNUNET_CADET_ChannelOption options; 183 enum GNUNET_CADET_ChannelOption options;
262 184
263 /** 185 /**
264 * Are we allowed to send to the service? 186 * How many messages are we allowed to send to the service right now?
265 */ 187 */
266 unsigned int allow_send; 188 unsigned int allow_send;
267 189
@@ -273,82 +195,62 @@ struct GNUNET_CADET_Channel
273 */ 195 */
274struct GNUNET_CADET_Port 196struct GNUNET_CADET_Port
275{ 197{
198
199 /**
200 * Port "number"
201 */
202 struct GNUNET_HashCode id;
203
276 /** 204 /**
277 * Handle to the CADET session this port belongs to. 205 * Handle to the CADET session this port belongs to.
278 */ 206 */
279 struct GNUNET_CADET_Handle *cadet; 207 struct GNUNET_CADET_Handle *cadet;
280 208
281 /** 209 /**
282 * Port ID. 210 * Closure for @a handler.
283 */ 211 */
284 struct GNUNET_HashCode *hash; 212 void *cls;
285 213
286 /** 214 /**
287 * Callback handler for incoming channels on this port. 215 * Handler for incoming channels on this port
288 */ 216 */
289 GNUNET_CADET_InboundChannelNotificationHandler *handler; 217 GNUNET_CADET_ConnectEventHandler connects;
290 218
291 /** 219 /**
292 * Closure for @a handler. 220 * Closure for @ref connects
293 */ 221 */
294 void *cls; 222 void *connects_cls;
295};
296 223
224 /**
225 * Window size change handler.
226 */
227 GNUNET_CADET_WindowSizeEventHandler window_changes;
297 228
298/**
299 * Implementation state for cadet's message queue.
300 */
301struct CadetMQState
302{
303 /** 229 /**
304 * The current transmit handle, or NULL 230 * Handler called when an incoming channel is destroyed.
305 * if no transmit is active.
306 */ 231 */
307 struct GNUNET_CADET_TransmitHandle *th; 232 GNUNET_CADET_DisconnectEventHandler disconnects;
308 233
309 /** 234 /**
310 * Channel to send the data over. 235 * Payload handlers for incoming channels.
311 */ 236 */
312 struct GNUNET_CADET_Channel *channel; 237 struct GNUNET_MQ_MessageHandler *handlers;
313}; 238};
314 239
315 240
316/******************************************************************************/
317/*********************** AUXILIARY FUNCTIONS *************************/
318/******************************************************************************/
319
320/**
321 * Check if transmission is a payload packet.
322 *
323 * @param th Transmission handle.
324 *
325 * @return #GNUNET_YES if it is a payload packet,
326 * #GNUNET_NO if it is a cadet management packet.
327 */
328static int
329th_is_payload (struct GNUNET_CADET_TransmitHandle *th)
330{
331 return (th->notify != NULL) ? GNUNET_YES : GNUNET_NO;
332}
333
334
335/** 241/**
336 * Find the Port struct for a hash. 242 * Find the Port struct for a hash.
337 * 243 *
338 * @param h CADET handle. 244 * @param h CADET handle.
339 * @param hash HashCode for the port number. 245 * @param hash HashCode for the port number.
340 *
341 * @return The port handle if known, NULL otherwise. 246 * @return The port handle if known, NULL otherwise.
342 */ 247 */
343static struct GNUNET_CADET_Port * 248static struct GNUNET_CADET_Port *
344find_port (const struct GNUNET_CADET_Handle *h, 249find_port (const struct GNUNET_CADET_Handle *h,
345 const struct GNUNET_HashCode *hash) 250 const struct GNUNET_HashCode *hash)
346{ 251{
347 struct GNUNET_CADET_Port *p; 252 return GNUNET_CONTAINER_multihashmap_get (h->ports,
348 253 hash);
349 p = GNUNET_CONTAINER_multihashmap_get (h->ports, hash);
350
351 return p;
352} 254}
353 255
354 256
@@ -360,15 +262,11 @@ find_port (const struct GNUNET_CADET_Handle *h,
360 * @return handle to the required channel or NULL if not found 262 * @return handle to the required channel or NULL if not found
361 */ 263 */
362static struct GNUNET_CADET_Channel * 264static struct GNUNET_CADET_Channel *
363retrieve_channel (struct GNUNET_CADET_Handle *h, 265find_channel (struct GNUNET_CADET_Handle *h,
364 struct GNUNET_CADET_ClientChannelNumber ccn) 266 struct GNUNET_CADET_ClientChannelNumber ccn)
365{ 267{
366 struct GNUNET_CADET_Channel *ch; 268 return GNUNET_CONTAINER_multihashmap32_get (h->channels,
367 269 ntohl (ccn.channel_of_client));
368 for (ch = h->channels_head; NULL != ch; ch = ch->next)
369 if (ch->ccn.channel_of_client == ccn.channel_of_client)
370 return ch;
371 return NULL;
372} 270}
373 271
374 272
@@ -376,38 +274,37 @@ retrieve_channel (struct GNUNET_CADET_Handle *h,
376 * Create a new channel and insert it in the channel list of the cadet handle 274 * Create a new channel and insert it in the channel list of the cadet handle
377 * 275 *
378 * @param h Cadet handle 276 * @param h Cadet handle
379 * @param ccn Desired ccn of the channel, 0 to assign one automatically. 277 * @param ccnp pointer to desired ccn of the channel, NULL to assign one automatically.
380 *
381 * @return Handle to the created channel. 278 * @return Handle to the created channel.
382 */ 279 */
383static struct GNUNET_CADET_Channel * 280static struct GNUNET_CADET_Channel *
384create_channel (struct GNUNET_CADET_Handle *h, 281create_channel (struct GNUNET_CADET_Handle *h,
385 struct GNUNET_CADET_ClientChannelNumber ccn) 282 const struct GNUNET_CADET_ClientChannelNumber *ccnp)
386{ 283{
387 struct GNUNET_CADET_Channel *ch; 284 struct GNUNET_CADET_Channel *ch;
285 struct GNUNET_CADET_ClientChannelNumber ccn;
388 286
389 ch = GNUNET_new (struct GNUNET_CADET_Channel); 287 ch = GNUNET_new (struct GNUNET_CADET_Channel);
390 GNUNET_CONTAINER_DLL_insert (h->channels_head,
391 h->channels_tail,
392 ch);
393 ch->cadet = h; 288 ch->cadet = h;
394 if (0 == ccn.channel_of_client) 289 if (NULL == ccnp)
395 { 290 {
396 ch->ccn = h->next_ccn; 291 while (NULL !=
397 while (NULL != retrieve_channel (h, 292 find_channel (h,
398 h->next_ccn)) 293 h->next_ccn))
399 {
400 h->next_ccn.channel_of_client 294 h->next_ccn.channel_of_client
401 = htonl (1 + ntohl (h->next_ccn.channel_of_client)); 295 = htonl (GNUNET_CADET_LOCAL_CHANNEL_ID_CLI | (1 + ntohl (h->next_ccn.channel_of_client)));
402 if (0 == ntohl (h->next_ccn.channel_of_client)) 296 ccn = h->next_ccn;
403 h->next_ccn.channel_of_client
404 = htonl (GNUNET_CADET_LOCAL_CHANNEL_ID_CLI);
405 }
406 } 297 }
407 else 298 else
408 { 299 {
409 ch->ccn = ccn; 300 ccn = *ccnp;
410 } 301 }
302 ch->ccn = ccn;
303 GNUNET_assert (GNUNET_OK ==
304 GNUNET_CONTAINER_multihashmap32_put (h->channels,
305 ntohl (ch->ccn.channel_of_client),
306 ch,
307 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
411 return ch; 308 return ch;
412} 309}
413 310
@@ -421,145 +318,273 @@ create_channel (struct GNUNET_CADET_Handle *h,
421 * 318 *
422 * @param ch Pointer to the channel. 319 * @param ch Pointer to the channel.
423 * @param call_cleaner Whether to call the cleaner handler. 320 * @param call_cleaner Whether to call the cleaner handler.
321 */
322static void
323destroy_channel (struct GNUNET_CADET_Channel *ch)
324{
325 struct GNUNET_CADET_Handle *h = ch->cadet;
326
327 LOG (GNUNET_ERROR_TYPE_DEBUG,
328 "Destroying channel %X of %p\n",
329 ch->ccn,
330 h);
331 GNUNET_assert (GNUNET_YES ==
332 GNUNET_CONTAINER_multihashmap32_remove (h->channels,
333 ntohl (ch->ccn.channel_of_client),
334 ch));
335 if (NULL != ch->mq_cont)
336 {
337 GNUNET_SCHEDULER_cancel (ch->mq_cont);
338 ch->mq_cont = NULL;
339 }
340 /* signal channel destruction */
341 if (NULL != ch->disconnects)
342 ch->disconnects (ch->ctx,
343 ch);
344 if (NULL != ch->pending_env)
345 GNUNET_MQ_discard (ch->pending_env);
346 GNUNET_MQ_destroy (ch->mq);
347 GNUNET_free (ch);
348}
349
350
351/**
352 * Reconnect to the service, retransmit all infomation to try to restore the
353 * original state.
424 * 354 *
425 * @return Handle to the required channel or NULL if not found. 355 * @param h handle to the cadet
426 */ 356 */
427// FIXME: simplify: call_cleaner is always #GNUNET_YES!!!
428static void 357static void
429destroy_channel (struct GNUNET_CADET_Channel *ch, 358reconnect (struct GNUNET_CADET_Handle *h);
430 int call_cleaner) 359
360
361/**
362 * Reconnect callback: tries to reconnect again after a failer previous
363 * reconnecttion
364 *
365 * @param cls closure (cadet handle)
366 */
367static void
368reconnect_cbk (void *cls)
431{ 369{
432 struct GNUNET_CADET_Handle *h; 370 struct GNUNET_CADET_Handle *h = cls;
433 struct GNUNET_CADET_TransmitHandle *th;
434 struct GNUNET_CADET_TransmitHandle *next;
435 371
436 if (NULL == ch) 372 h->reconnect_task = NULL;
373 reconnect (h);
374}
375
376
377/**
378 * Function called during #reconnect() to destroy
379 * all channels that are still open.
380 *
381 * @param cls the `struct GNUNET_CADET_Handle`
382 * @param cid chanenl ID
383 * @param value a `struct GNUNET_CADET_Channel` to destroy
384 * @return #GNUNET_OK (continue to iterate)
385 */
386static int
387destroy_channel_on_reconnect_cb (void *cls,
388 uint32_t cid,
389 void *value)
390{
391 /* struct GNUNET_CADET_Handle *handle = cls; */
392 struct GNUNET_CADET_Channel *ch = value;
393
394 destroy_channel (ch);
395 return GNUNET_OK;
396}
397
398
399/**
400 * Reconnect to the service, retransmit all infomation to try to restore the
401 * original state.
402 *
403 * @param h handle to the cadet
404 *
405 * @return #GNUNET_YES in case of sucess, #GNUNET_NO otherwise (service down...)
406 */
407static void
408schedule_reconnect (struct GNUNET_CADET_Handle *h)
409{
410 if (NULL != h->reconnect_task)
411 return;
412 GNUNET_CONTAINER_multihashmap32_iterate (h->channels,
413 &destroy_channel_on_reconnect_cb,
414 h);
415 h->reconnect_task
416 = GNUNET_SCHEDULER_add_delayed (h->reconnect_time,
417 &reconnect_cbk,
418 h);
419 h->reconnect_time
420 = GNUNET_TIME_STD_BACKOFF (h->reconnect_time);
421}
422
423
424/**
425 * Notify the application about a change in the window size (if needed).
426 *
427 * @param ch Channel to notify about.
428 */
429static void
430notify_window_size (struct GNUNET_CADET_Channel *ch)
431{
432 if (NULL != ch->window_changes)
433 ch->window_changes (ch->ctx,
434 ch, /* FIXME: remove 'ch'? */
435 ch->allow_send);
436}
437
438
439/**
440 * Transmit the next message from our queue.
441 *
442 * @param cls Closure (channel whose mq to activate).
443 */
444static void
445cadet_mq_send_now (void *cls)
446{
447 struct GNUNET_CADET_Channel *ch = cls;
448 struct GNUNET_MQ_Envelope *env = ch->pending_env;
449
450 ch->mq_cont = NULL;
451 if (0 == ch->allow_send)
437 { 452 {
453 /* how did we get here? */
438 GNUNET_break (0); 454 GNUNET_break (0);
439 return; 455 return;
440 } 456 }
441 h = ch->cadet; 457 if (NULL == env)
442 LOG (GNUNET_ERROR_TYPE_DEBUG, 458 {
443 " destroy_channel %X of %p\n", 459 /* how did we get here? */
444 ch->ccn, 460 GNUNET_break (0);
445 h); 461 return;
462 }
463 ch->allow_send--;
464 ch->pending_env = NULL;
465 GNUNET_MQ_send (ch->cadet->mq,
466 env);
467 GNUNET_MQ_impl_send_continue (ch->mq);
468}
446 469
447 GNUNET_CONTAINER_DLL_remove (h->channels_head,
448 h->channels_tail,
449 ch);
450 470
451 /* signal channel destruction */ 471/**
452 if ( (NULL != h->cleaner) && 472 * Implement sending functionality of a message queue for
453 (0 != ch->peer) && 473 * us sending messages to a peer.
454 (GNUNET_YES == call_cleaner) ) 474 *
475 * Encapsulates the payload message in a #GNUNET_CADET_LocalData message
476 * in order to label the message with the channel ID and send the
477 * encapsulated message to the service.
478 *
479 * @param mq the message queue
480 * @param msg the message to send
481 * @param impl_state state of the implementation
482 */
483static void
484cadet_mq_send_impl (struct GNUNET_MQ_Handle *mq,
485 const struct GNUNET_MessageHeader *msg,
486 void *impl_state)
487{
488 struct GNUNET_CADET_Channel *ch = impl_state;
489 struct GNUNET_CADET_Handle *h = ch->cadet;
490 uint16_t msize;
491 struct GNUNET_MQ_Envelope *env;
492 struct GNUNET_CADET_LocalData *cadet_msg;
493
494 if (NULL == h->mq)
455 { 495 {
456 LOG (GNUNET_ERROR_TYPE_DEBUG, 496 /* We're currently reconnecting, pretend this worked */
457 " calling cleaner\n"); 497 GNUNET_MQ_impl_send_continue (mq);
458 h->cleaner (h->cls, ch, ch->ctx); 498 return;
459 } 499 }
460 500
461 /* check that clients did not leave messages behind in the queue */ 501 /* check message size for sanity */
462 for (th = h->th_head; NULL != th; th = next) 502 msize = ntohs (msg->size);
503 if (msize > GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE)
463 { 504 {
464 next = th->next; 505 GNUNET_break (0);
465 if (th->channel != ch) 506 GNUNET_MQ_impl_send_continue (mq);
466 continue; 507 return;
467 /* Clients should have aborted their requests already.
468 * Management traffic should be ok, as clients can't cancel that.
469 * If the service crashed and we are reconnecting, it's ok.
470 */
471 GNUNET_break (GNUNET_NO == th_is_payload (th));
472 GNUNET_CADET_notify_transmit_ready_cancel (th);
473 } 508 }
474 509 env = GNUNET_MQ_msg_nested_mh (cadet_msg,
475 if (0 != ch->peer) 510 GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA,
476 GNUNET_PEER_change_rc (ch->peer, -1); 511 msg);
477 GNUNET_free (ch); 512 cadet_msg->ccn = ch->ccn;
513 GNUNET_assert (NULL == ch->pending_env);
514 ch->pending_env = env;
515 if (0 < ch->allow_send)
516 ch->mq_cont
517 = GNUNET_SCHEDULER_add_now (&cadet_mq_send_now,
518 ch);
478} 519}
479 520
480 521
481/** 522/**
482 * Add a transmit handle to the transmission queue and set the 523 * Handle destruction of a message queue. Implementations must not
483 * timeout if needed. 524 * free @a mq, but should take care of @a impl_state.
484 * 525 *
485 * @param h cadet handle with the queue head and tail 526 * @param mq the message queue to destroy
486 * @param th handle to the packet to be transmitted 527 * @param impl_state state of the implementation
487 */ 528 */
488static void 529static void
489add_to_queue (struct GNUNET_CADET_Handle *h, 530cadet_mq_destroy_impl (struct GNUNET_MQ_Handle *mq,
490 struct GNUNET_CADET_TransmitHandle *th) 531 void *impl_state)
491{ 532{
492 GNUNET_CONTAINER_DLL_insert_tail (h->th_head, 533 struct GNUNET_CADET_Channel *ch = impl_state;
493 h->th_tail, 534
494 th); 535 GNUNET_assert (mq == ch->mq);
536 ch->mq = NULL;
495} 537}
496 538
497 539
498/** 540/**
499 * Remove a transmit handle from the transmission queue, if present. 541 * We had an error processing a message we forwarded from a peer to
500 * 542 * the CADET service. We should just complain about it but otherwise
501 * Safe to call even if not queued. 543 * continue processing.
502 * 544 *
503 * @param th handle to the packet to be unqueued. 545 * @param cls closure with our `struct GNUNET_CADET_Channel`
546 * @param error error code
504 */ 547 */
505static void 548static void
506remove_from_queue (struct GNUNET_CADET_TransmitHandle *th) 549cadet_mq_error_handler (void *cls,
550 enum GNUNET_MQ_Error error)
507{ 551{
508 struct GNUNET_CADET_Handle *h = th->channel->cadet; 552 struct GNUNET_CADET_Channel *ch = cls;
509 553
510 /* It might or might not have been queued (rarely not), but check anyway. */ 554 GNUNET_break (0);
511 if (NULL != th->next || h->th_tail == th) 555 if (GNUNET_MQ_ERROR_NO_MATCH == error)
556 {
557 /* Got a message we did not understand, still try to continue! */
558 GNUNET_CADET_receive_done (ch);
559 }
560 else
512 { 561 {
513 GNUNET_CONTAINER_DLL_remove (h->th_head, h->th_tail, th); 562 schedule_reconnect (ch->cadet);
514 } 563 }
515} 564}
516 565
517 566
518
519/******************************************************************************/
520/*********************** RECEIVE HANDLERS ****************************/
521/******************************************************************************/
522
523
524/** 567/**
525 * Call the @a notify callback given to #GNUNET_CADET_notify_transmit_ready to 568 * Implementation function that cancels the currently sent message.
526 * request the data to send over MQ. Since MQ manages the queue, this function 569 * Should basically undo whatever #mq_send_impl() did.
527 * is scheduled immediatly after a transmit ready notification.
528 * 570 *
529 * @param cls Closure (transmit handle). 571 * @param mq message queue
572 * @param impl_state state specific to the implementation
530 */ 573 */
531static void 574static void
532request_data (void *cls) 575cadet_mq_cancel_impl (struct GNUNET_MQ_Handle *mq,
576 void *impl_state)
533{ 577{
534 struct GNUNET_CADET_TransmitHandle *th = cls; 578 struct GNUNET_CADET_Channel *ch = impl_state;
535 struct GNUNET_CADET_LocalData *msg;
536 struct GNUNET_MQ_Envelope *env;
537 size_t osize;
538 579
539 LOG (GNUNET_ERROR_TYPE_DEBUG, 580 GNUNET_assert (NULL != ch->pending_env);
540 "Requesting Data: %u bytes (allow send is %u)\n", 581 GNUNET_MQ_discard (ch->pending_env);
541 th->size, 582 ch->pending_env = NULL;
542 th->channel->allow_send); 583 if (NULL != ch->mq_cont)
543 584 {
544 GNUNET_assert (0 < th->channel->allow_send); 585 GNUNET_SCHEDULER_cancel (ch->mq_cont);
545 th->channel->allow_send--; 586 ch->mq_cont = NULL;
546 /* NOTE: we may be allowed to send another packet immediately, 587 }
547 albeit the current logic waits for the ACK. */
548 th->request_data_task = NULL;
549 remove_from_queue (th);
550
551 env = GNUNET_MQ_msg_extra (msg,
552 th->size,
553 GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA);
554 msg->ccn = th->channel->ccn;
555 osize = th->notify (th->notify_cls,
556 th->size,
557 &msg[1]);
558 GNUNET_assert (osize == th->size);
559
560 GNUNET_MQ_send (th->channel->cadet->mq,
561 env);
562 GNUNET_free (th);
563} 588}
564 589
565 590
@@ -586,18 +611,20 @@ handle_channel_created (void *cls,
586 GNUNET_break (0); 611 GNUNET_break (0);
587 return; 612 return;
588 } 613 }
589 port = find_port (h, port_number); 614 port = find_port (h,
615 port_number);
590 if (NULL == port) 616 if (NULL == port)
591 { 617 {
618 /* We could have closed the port but the service didn't know about it yet
619 * This is not an error.
620 */
592 struct GNUNET_CADET_LocalChannelDestroyMessage *d_msg; 621 struct GNUNET_CADET_LocalChannelDestroyMessage *d_msg;
593 struct GNUNET_MQ_Envelope *env; 622 struct GNUNET_MQ_Envelope *env;
594 623
595 GNUNET_break (0);
596 LOG (GNUNET_ERROR_TYPE_DEBUG, 624 LOG (GNUNET_ERROR_TYPE_DEBUG,
597 "No handler for incoming channel %X [%s]\n", 625 "No handler for incoming channel %X (on port %s, recently closed?)\n",
598 ntohl (ccn.channel_of_client), 626 ntohl (ccn.channel_of_client),
599 GNUNET_h2s (port_number)); 627 GNUNET_h2s (port_number));
600 /* FIXME: should disconnect instead, this is a serious error! */
601 env = GNUNET_MQ_msg (d_msg, 628 env = GNUNET_MQ_msg (d_msg,
602 GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY); 629 GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY);
603 d_msg->ccn = msg->ccn; 630 d_msg->ccn = msg->ccn;
@@ -607,23 +634,32 @@ handle_channel_created (void *cls,
607 } 634 }
608 635
609 ch = create_channel (h, 636 ch = create_channel (h,
610 ccn); 637 &ccn);
611 ch->peer = GNUNET_PEER_intern (&msg->peer); 638 ch->peer = msg->peer;
612 ch->cadet = h; 639 ch->cadet = h;
613 ch->ccn = ccn; 640 ch->incoming_port = port;
614 ch->port = port;
615 ch->options = ntohl (msg->opt); 641 ch->options = ntohl (msg->opt);
616
617 LOG (GNUNET_ERROR_TYPE_DEBUG, 642 LOG (GNUNET_ERROR_TYPE_DEBUG,
618 "Creating incoming channel %X [%s] %p\n", 643 "Creating incoming channel %X [%s] %p\n",
619 ntohl (ccn.channel_of_client), 644 ntohl (ccn.channel_of_client),
620 GNUNET_h2s (port_number), 645 GNUNET_h2s (port_number),
621 ch); 646 ch);
622 ch->ctx = port->handler (port->cls, 647
623 ch, 648 GNUNET_assert (NULL != port->connects);
624 &msg->peer, 649 ch->window_changes = port->window_changes;
625 port->hash, 650 ch->disconnects = port->disconnects;
626 ch->options); 651 ch->mq = GNUNET_MQ_queue_for_callbacks (&cadet_mq_send_impl,
652 &cadet_mq_destroy_impl,
653 &cadet_mq_cancel_impl,
654 ch,
655 port->handlers,
656 &cadet_mq_error_handler,
657 ch);
658 ch->ctx = port->connects (port->cls,
659 ch,
660 &msg->peer);
661 GNUNET_MQ_set_handlers_closure (ch->mq,
662 ch->ctx);
627} 663}
628 664
629 665
@@ -639,24 +675,20 @@ handle_channel_destroy (void *cls,
639{ 675{
640 struct GNUNET_CADET_Handle *h = cls; 676 struct GNUNET_CADET_Handle *h = cls;
641 struct GNUNET_CADET_Channel *ch; 677 struct GNUNET_CADET_Channel *ch;
642 struct GNUNET_CADET_ClientChannelNumber ccn;
643
644 ccn = msg->ccn;
645 LOG (GNUNET_ERROR_TYPE_DEBUG,
646 "Channel %X Destroy from service\n",
647 ntohl (ccn.channel_of_client));
648 ch = retrieve_channel (h,
649 ccn);
650 678
679 ch = find_channel (h,
680 msg->ccn);
651 if (NULL == ch) 681 if (NULL == ch)
652 { 682 {
653 LOG (GNUNET_ERROR_TYPE_DEBUG, 683 LOG (GNUNET_ERROR_TYPE_DEBUG,
654 "channel %X unknown\n", 684 "Received channel destroy for unknown channel %X from CADET service (recently close?)\n",
655 ntohl (ccn.channel_of_client)); 685 ntohl (msg->ccn.channel_of_client));
656 return; 686 return;
657 } 687 }
658 destroy_channel (ch, 688 LOG (GNUNET_ERROR_TYPE_DEBUG,
659 GNUNET_YES); 689 "Received channel destroy for channel %X from CADET service\n",
690 ntohl (msg->ccn.channel_of_client));
691 destroy_channel (ch);
660} 692}
661 693
662 694
@@ -672,25 +704,14 @@ static int
672check_local_data (void *cls, 704check_local_data (void *cls,
673 const struct GNUNET_CADET_LocalData *message) 705 const struct GNUNET_CADET_LocalData *message)
674{ 706{
675 struct GNUNET_CADET_Handle *h = cls;
676 struct GNUNET_CADET_Channel *ch;
677 uint16_t size; 707 uint16_t size;
678 708
679 size = ntohs (message->header.size); 709 size = ntohs (message->header.size);
680 if (sizeof (*message) + sizeof (struct GNUNET_MessageHeader) > size) 710 if (sizeof (*message) + sizeof (struct GNUNET_MessageHeader) > size)
681 { 711 {
682 GNUNET_break_op (0); 712 GNUNET_break (0);
683 return GNUNET_SYSERR;
684 }
685
686 ch = retrieve_channel (h,
687 message->ccn);
688 if (NULL == ch)
689 {
690 GNUNET_break_op (0);
691 return GNUNET_SYSERR; 713 return GNUNET_SYSERR;
692 } 714 }
693
694 return GNUNET_OK; 715 return GNUNET_OK;
695} 716}
696 717
@@ -707,46 +728,31 @@ handle_local_data (void *cls,
707{ 728{
708 struct GNUNET_CADET_Handle *h = cls; 729 struct GNUNET_CADET_Handle *h = cls;
709 const struct GNUNET_MessageHeader *payload; 730 const struct GNUNET_MessageHeader *payload;
710 const struct GNUNET_CADET_MessageHandler *handler;
711 struct GNUNET_CADET_Channel *ch; 731 struct GNUNET_CADET_Channel *ch;
712 uint16_t type; 732 uint16_t type;
733 int fwd;
713 734
714 ch = retrieve_channel (h, 735 ch = find_channel (h,
715 message->ccn); 736 message->ccn);
716 GNUNET_assert (NULL != ch); 737 if (NULL == ch)
738 {
739 LOG (GNUNET_ERROR_TYPE_DEBUG,
740 "Unknown channel %X for incoming data (recently closed?)\n",
741 ntohl (message->ccn.channel_of_client));
742 return;
743 }
717 744
718 payload = (struct GNUNET_MessageHeader *) &message[1]; 745 payload = (const struct GNUNET_MessageHeader *) &message[1];
719 type = ntohs (payload->type); 746 type = ntohs (payload->type);
747 fwd = ntohl (ch->ccn.channel_of_client) <= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI;
720 LOG (GNUNET_ERROR_TYPE_DEBUG, 748 LOG (GNUNET_ERROR_TYPE_DEBUG,
721 "Got a %s data on channel %s [%X] of type %s (%u)\n", 749 "Got a %s data on channel %s [%X] of type %u\n",
722 GC_f2s (ntohl (ch->ccn.channel_of_client) >= 750 fwd ? "FWD" : "BWD",
723 GNUNET_CADET_LOCAL_CHANNEL_ID_CLI), 751 GNUNET_i2s (&ch->peer),
724 GNUNET_i2s (GNUNET_PEER_resolve2 (ch->peer)),
725 ntohl (message->ccn.channel_of_client), 752 ntohl (message->ccn.channel_of_client),
726 GC_m2s (type),
727 type); 753 type);
728 for (unsigned i=0;i<h->n_handlers;i++) 754 GNUNET_MQ_inject_message (ch->mq,
729 { 755 payload);
730 handler = &h->message_handlers[i];
731 if (handler->type == type)
732 {
733 if (GNUNET_OK !=
734 handler->callback (h->cls,
735 ch,
736 &ch->ctx,
737 payload))
738 {
739 LOG (GNUNET_ERROR_TYPE_DEBUG,
740 "callback caused disconnection\n");
741 GNUNET_CADET_channel_destroy (ch);
742 return;
743 }
744 return;
745 }
746 }
747 /* Other peer sent message we do not comprehend. */
748 GNUNET_break_op (0);
749 GNUNET_CADET_receive_done (ch);
750} 756}
751 757
752 758
@@ -763,57 +769,36 @@ handle_local_ack (void *cls,
763{ 769{
764 struct GNUNET_CADET_Handle *h = cls; 770 struct GNUNET_CADET_Handle *h = cls;
765 struct GNUNET_CADET_Channel *ch; 771 struct GNUNET_CADET_Channel *ch;
766 struct GNUNET_CADET_ClientChannelNumber ccn;
767 struct GNUNET_CADET_TransmitHandle *th;
768 772
769 ccn = message->ccn; 773 ch = find_channel (h,
770 ch = retrieve_channel (h, ccn); 774 message->ccn);
771 if (NULL == ch) 775 if (NULL == ch)
772 { 776 {
773 LOG (GNUNET_ERROR_TYPE_DEBUG, 777 LOG (GNUNET_ERROR_TYPE_DEBUG,
774 "ACK on unknown channel %X\n", 778 "ACK on unknown channel %X\n",
775 ntohl (ccn.channel_of_client)); 779 ntohl (message->ccn.channel_of_client));
776 return; 780 return;
777 } 781 }
778 ch->allow_send++; 782 ch->allow_send++;
779 LOG (GNUNET_ERROR_TYPE_DEBUG, 783 if (NULL == ch->pending_env)
780 "Got an ACK on channel %X, allow send now %u!\n",
781 ntohl (ch->ccn.channel_of_client),
782 ch->allow_send);
783 for (th = h->th_head; NULL != th; th = th->next)
784 { 784 {
785 if ( (th->channel == ch) && 785 LOG (GNUNET_ERROR_TYPE_DEBUG,
786 (NULL == th->request_data_task) ) 786 "Got an ACK on mq channel %X, allow send now %u!\n",
787 { 787 ntohl (ch->ccn.channel_of_client),
788 th->request_data_task 788 ch->allow_send);
789 = GNUNET_SCHEDULER_add_now (&request_data, 789 notify_window_size (ch);
790 th); 790 return;
791 break;
792 }
793 } 791 }
792 if (NULL != ch->mq_cont)
793 return; /* already working on it! */
794 LOG (GNUNET_ERROR_TYPE_DEBUG,
795 "Got an ACK on mq channel %X, sending pending message!\n",
796 ntohl (ch->ccn.channel_of_client));
797 ch->mq_cont
798 = GNUNET_SCHEDULER_add_now (&cadet_mq_send_now,
799 ch);
794} 800}
795 801
796/**
797 * Reconnect to the service, retransmit all infomation to try to restore the
798 * original state.
799 *
800 * @param h handle to the cadet
801 *
802 * @return #GNUNET_YES in case of sucess, #GNUNET_NO otherwise (service down...)
803 */
804static void
805reconnect (struct GNUNET_CADET_Handle *h);
806
807
808/**
809 * Reconnect callback: tries to reconnect again after a failer previous
810 * reconnection.
811 *
812 * @param cls closure (cadet handle)
813 */
814static void
815reconnect_cbk (void *cls);
816
817 802
818/** 803/**
819 * Generic error handler, called with the appropriate error code and 804 * Generic error handler, called with the appropriate error code and
@@ -829,134 +814,15 @@ handle_mq_error (void *cls,
829{ 814{
830 struct GNUNET_CADET_Handle *h = cls; 815 struct GNUNET_CADET_Handle *h = cls;
831 816
832 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MQ ERROR: %u\n", error); 817 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
818 "MQ ERROR: %u\n",
819 error);
833 GNUNET_MQ_destroy (h->mq); 820 GNUNET_MQ_destroy (h->mq);
834 h->mq = NULL; 821 h->mq = NULL;
835 reconnect (h); 822 reconnect (h);
836} 823}
837 824
838 825
839/*
840 * Process a local reply about info on all channels, pass info to the user.
841 *
842 * @param h Cadet handle.
843 * @param message Message itself.
844 */
845// static void
846// process_get_channels (struct GNUNET_CADET_Handle *h,
847// const struct GNUNET_MessageHeader *message)
848// {
849// struct GNUNET_CADET_LocalInfo *msg;
850//
851// GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Get Channels messasge received\n");
852//
853// if (NULL == h->channels_cb)
854// {
855// GNUNET_log (GNUNET_ERROR_TYPE_ERROR, " ignored\n");
856// return;
857// }
858//
859// msg = (struct GNUNET_CADET_LocalInfo *) message;
860// if (ntohs (message->size) !=
861// (sizeof (struct GNUNET_CADET_LocalInfo) +
862// sizeof (struct GNUNET_PeerIdentity)))
863// {
864// GNUNET_break_op (0);
865// GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
866// "Get channels message: size %hu - expected %u\n",
867// ntohs (message->size),
868// sizeof (struct GNUNET_CADET_LocalInfo));
869// return;
870// }
871// h->channels_cb (h->channels_cls,
872// ntohl (msg->channel_id),
873// &msg->owner,
874// &msg->destination);
875// }
876
877
878
879/*
880 * Process a local monitor_channel reply, pass info to the user.
881 *
882 * @param h Cadet handle.
883 * @param message Message itself.
884 */
885// static void
886// process_show_channel (struct GNUNET_CADET_Handle *h,
887// const struct GNUNET_MessageHeader *message)
888// {
889// struct GNUNET_CADET_LocalInfo *msg;
890// size_t esize;
891//
892// GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Show Channel messasge received\n");
893//
894// if (NULL == h->channel_cb)
895// {
896// GNUNET_log (GNUNET_ERROR_TYPE_ERROR, " ignored\n");
897// return;
898// }
899//
900// /* Verify message sanity */
901// msg = (struct GNUNET_CADET_LocalInfo *) message;
902// esize = sizeof (struct GNUNET_CADET_LocalInfo);
903// if (ntohs (message->size) != esize)
904// {
905// GNUNET_break_op (0);
906// GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
907// "Show channel message: size %hu - expected %u\n",
908// ntohs (message->size),
909// esize);
910//
911// h->channel_cb (h->channel_cls, NULL, NULL);
912// h->channel_cb = NULL;
913// h->channel_cls = NULL;
914//
915// return;
916// }
917//
918// h->channel_cb (h->channel_cls,
919// &msg->destination,
920// &msg->owner);
921// }
922
923
924
925/**
926 * Check that message received from CADET service is well-formed.
927 *
928 * @param cls the `struct GNUNET_CADET_Handle`
929 * @param message the message we got
930 * @return #GNUNET_OK if the message is well-formed,
931 * #GNUNET_SYSERR otherwise
932 */
933static int
934check_get_peers (void *cls,
935 const struct GNUNET_CADET_LocalInfoPeer *message)
936{
937 struct GNUNET_CADET_Handle *h = cls;
938 uint16_t size;
939
940 if (NULL == h->info_cb.peers_cb)
941 {
942 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
943 " no handler for peesr monitor message!\n");
944 return GNUNET_SYSERR;
945 }
946
947 size = ntohs (message->header.size);
948 if (sizeof (struct GNUNET_CADET_LocalInfoPeer) > size)
949 {
950 h->info_cb.peers_cb (h->info_cls, NULL, -1, 0, 0);
951 h->info_cb.peers_cb = NULL;
952 h->info_cls = NULL;
953 return GNUNET_SYSERR;
954 }
955
956 return GNUNET_OK;
957}
958
959
960/** 826/**
961 * Process a local reply about info on all tunnels, pass info to the user. 827 * Process a local reply about info on all tunnels, pass info to the user.
962 * 828 *
@@ -968,9 +834,13 @@ handle_get_peers (void *cls,
968 const struct GNUNET_CADET_LocalInfoPeer *msg) 834 const struct GNUNET_CADET_LocalInfoPeer *msg)
969{ 835{
970 struct GNUNET_CADET_Handle *h = cls; 836 struct GNUNET_CADET_Handle *h = cls;
971 h->info_cb.peers_cb (h->info_cls, &msg->destination, 837
838 if (NULL == h->info_cb.peers_cb)
839 return;
840 h->info_cb.peers_cb (h->info_cls,
841 &msg->destination,
972 (int) ntohs (msg->tunnel), 842 (int) ntohs (msg->tunnel),
973 (unsigned int ) ntohs (msg->paths), 843 (unsigned int) ntohs (msg->paths),
974 0); 844 0);
975} 845}
976 846
@@ -987,62 +857,39 @@ static int
987check_get_peer (void *cls, 857check_get_peer (void *cls,
988 const struct GNUNET_CADET_LocalInfoPeer *message) 858 const struct GNUNET_CADET_LocalInfoPeer *message)
989{ 859{
990 struct GNUNET_CADET_Handle *h = cls; 860 size_t msize = sizeof (struct GNUNET_CADET_LocalInfoPeer);
991 const size_t msize = sizeof (struct GNUNET_CADET_LocalInfoPeer); 861 const struct GNUNET_PeerIdentity *paths_array;
992 struct GNUNET_PeerIdentity *paths_array;
993 size_t esize; 862 size_t esize;
994 unsigned int epaths; 863 unsigned int epaths;
995 unsigned int paths; 864 unsigned int paths;
996 unsigned int peers; 865 unsigned int peers;
997 866
998 if (NULL == h->info_cb.peer_cb)
999 {
1000 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1001 " no handler for peer monitor message!\n");
1002 goto clean_cls;
1003 }
1004
1005 /* Verify message sanity */
1006 esize = ntohs (message->header.size); 867 esize = ntohs (message->header.size);
1007 if (esize < msize) 868 if (esize < msize)
1008 { 869 {
1009 GNUNET_break_op (0); 870 GNUNET_break (0);
1010 h->info_cb.peer_cb (h->info_cls, NULL, 0, 0, 0, NULL); 871 return GNUNET_SYSERR;
1011 goto clean_cls;
1012 } 872 }
1013 if (0 != ((esize - msize) % sizeof (struct GNUNET_PeerIdentity))) 873 if (0 != ((esize - msize) % sizeof (struct GNUNET_PeerIdentity)))
1014 { 874 {
1015 GNUNET_break_op (0); 875 GNUNET_break (0);
1016 h->info_cb.peer_cb (h->info_cls, NULL, 0, 0, 0, NULL); 876 return GNUNET_SYSERR;
1017 goto clean_cls;
1018
1019 } 877 }
1020 peers = (esize - msize) / sizeof (struct GNUNET_PeerIdentity); 878 peers = (esize - msize) / sizeof (struct GNUNET_PeerIdentity);
1021 epaths = (unsigned int) ntohs (message->paths); 879 epaths = ntohs (message->paths);
1022 paths_array = (struct GNUNET_PeerIdentity *) &message[1]; 880 paths_array = (const struct GNUNET_PeerIdentity *) &message[1];
1023 paths = 0; 881 paths = 0;
1024 for (int i = 0; i < peers; i++) 882 for (unsigned int i = 0; i < peers; i++)
1025 { 883 if (0 == memcmp (&paths_array[i],
1026 if (0 == memcmp (&paths_array[i], &message->destination, 884 &message->destination,
1027 sizeof (struct GNUNET_PeerIdentity))) 885 sizeof (struct GNUNET_PeerIdentity)))
1028 {
1029 paths++; 886 paths++;
1030 }
1031 }
1032 if (paths != epaths) 887 if (paths != epaths)
1033 { 888 {
1034 GNUNET_break_op (0); 889 GNUNET_break (0);
1035 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "p:%u, e: %u\n", paths, epaths); 890 return GNUNET_SYSERR;
1036 h->info_cb.peer_cb (h->info_cls, NULL, 0, 0, 0, NULL);
1037 goto clean_cls;
1038 } 891 }
1039
1040 return GNUNET_OK; 892 return GNUNET_OK;
1041
1042clean_cls:
1043 h->info_cb.peer_cb = NULL;
1044 h->info_cls = NULL;
1045 return GNUNET_SYSERR;
1046} 893}
1047 894
1048 895
@@ -1057,22 +904,26 @@ handle_get_peer (void *cls,
1057 const struct GNUNET_CADET_LocalInfoPeer *message) 904 const struct GNUNET_CADET_LocalInfoPeer *message)
1058{ 905{
1059 struct GNUNET_CADET_Handle *h = cls; 906 struct GNUNET_CADET_Handle *h = cls;
1060 struct GNUNET_PeerIdentity *paths_array; 907 const struct GNUNET_PeerIdentity *paths_array;
1061 unsigned int paths; 908 unsigned int paths;
1062 unsigned int path_length; 909 unsigned int path_length;
1063 int neighbor; 910 int neighbor;
1064 unsigned int peers; 911 unsigned int peers;
1065 912
1066 paths = (unsigned int) ntohs (message->paths); 913 if (NULL == h->info_cb.peer_cb)
1067 paths_array = (struct GNUNET_PeerIdentity *) &message[1]; 914 return;
915 paths = ntohs (message->paths);
916 paths_array = (const struct GNUNET_PeerIdentity *) &message[1];
1068 peers = (ntohs (message->header.size) - sizeof (*message)) 917 peers = (ntohs (message->header.size) - sizeof (*message))
1069 / sizeof (struct GNUNET_PeerIdentity); 918 / sizeof (struct GNUNET_PeerIdentity);
1070 path_length = 0; 919 path_length = 0;
1071 neighbor = GNUNET_NO; 920 neighbor = GNUNET_NO;
1072 921
1073 for (int i = 0; i < peers; i++) 922 for (unsigned int i = 0; i < peers; i++)
1074 { 923 {
1075 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " %s\n", GNUNET_i2s (&paths_array[i])); 924 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
925 " %s\n",
926 GNUNET_i2s (&paths_array[i]));
1076 path_length++; 927 path_length++;
1077 if (0 == memcmp (&paths_array[i], &message->destination, 928 if (0 == memcmp (&paths_array[i], &message->destination,
1078 sizeof (struct GNUNET_PeerIdentity))) 929 sizeof (struct GNUNET_PeerIdentity)))
@@ -1084,7 +935,7 @@ handle_get_peer (void *cls,
1084 } 935 }
1085 936
1086 /* Call Callback with tunnel info. */ 937 /* Call Callback with tunnel info. */
1087 paths_array = (struct GNUNET_PeerIdentity *) &message[1]; 938 paths_array = (const struct GNUNET_PeerIdentity *) &message[1];
1088 h->info_cb.peer_cb (h->info_cls, 939 h->info_cb.peer_cb (h->info_cls,
1089 &message->destination, 940 &message->destination,
1090 (int) ntohs (message->tunnel), 941 (int) ntohs (message->tunnel),
@@ -1095,40 +946,6 @@ handle_get_peer (void *cls,
1095 946
1096 947
1097/** 948/**
1098 * Check that message received from CADET service is well-formed.
1099 *
1100 * @param cls the `struct GNUNET_CADET_Handle`
1101 * @param msg the message we got
1102 * @return #GNUNET_OK if the message is well-formed,
1103 * #GNUNET_SYSERR otherwise
1104 */
1105static int
1106check_get_tunnels (void *cls,
1107 const struct GNUNET_CADET_LocalInfoTunnel *msg)
1108{
1109 struct GNUNET_CADET_Handle *h = cls;
1110 uint16_t size;
1111
1112 if (NULL == h->info_cb.tunnels_cb)
1113 {
1114 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1115 " no handler for tunnels monitor message!\n");
1116 return GNUNET_SYSERR;
1117 }
1118
1119 size = ntohs (msg->header.size);
1120 if (sizeof (struct GNUNET_CADET_LocalInfoTunnel) > size)
1121 {
1122 h->info_cb.tunnels_cb (h->info_cls, NULL, 0, 0, 0, 0);
1123 h->info_cb.tunnels_cb = NULL;
1124 h->info_cls = NULL;
1125 return GNUNET_SYSERR;
1126 }
1127 return GNUNET_OK;
1128}
1129
1130
1131/**
1132 * Process a local reply about info on all tunnels, pass info to the user. 949 * Process a local reply about info on all tunnels, pass info to the user.
1133 * 950 *
1134 * @param cls Closure (Cadet handle). 951 * @param cls Closure (Cadet handle).
@@ -1140,6 +957,8 @@ handle_get_tunnels (void *cls,
1140{ 957{
1141 struct GNUNET_CADET_Handle *h = cls; 958 struct GNUNET_CADET_Handle *h = cls;
1142 959
960 if (NULL == h->info_cb.tunnels_cb)
961 return;
1143 h->info_cb.tunnels_cb (h->info_cls, 962 h->info_cb.tunnels_cb (h->info_cls,
1144 &msg->destination, 963 &msg->destination,
1145 ntohl (msg->channels), 964 ntohl (msg->channels),
@@ -1162,28 +981,18 @@ static int
1162check_get_tunnel (void *cls, 981check_get_tunnel (void *cls,
1163 const struct GNUNET_CADET_LocalInfoTunnel *msg) 982 const struct GNUNET_CADET_LocalInfoTunnel *msg)
1164{ 983{
1165 struct GNUNET_CADET_Handle *h = cls;
1166 unsigned int ch_n; 984 unsigned int ch_n;
1167 unsigned int c_n; 985 unsigned int c_n;
1168 size_t esize; 986 size_t esize;
1169 size_t msize; 987 size_t msize;
1170 988
1171 if (NULL == h->info_cb.tunnel_cb)
1172 {
1173 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1174 " no handler for tunnel monitor message!\n");
1175 goto clean_cls;
1176 }
1177
1178 /* Verify message sanity */ 989 /* Verify message sanity */
1179 msize = ntohs (msg->header.size); 990 msize = ntohs (msg->header.size);
1180 esize = sizeof (struct GNUNET_CADET_LocalInfoTunnel); 991 esize = sizeof (struct GNUNET_CADET_LocalInfoTunnel);
1181 if (esize > msize) 992 if (esize > msize)
1182 { 993 {
1183 GNUNET_break_op (0); 994 GNUNET_break (0);
1184 h->info_cb.tunnel_cb (h->info_cls, 995 return GNUNET_SYSERR;
1185 NULL, 0, 0, NULL, NULL, 0, 0);
1186 goto clean_cls;
1187 } 996 }
1188 ch_n = ntohl (msg->channels); 997 ch_n = ntohl (msg->channels);
1189 c_n = ntohl (msg->connections); 998 c_n = ntohl (msg->connections);
@@ -1198,17 +1007,9 @@ check_get_tunnel (void *cls,
1198 (unsigned int) esize, 1007 (unsigned int) esize,
1199 ch_n, 1008 ch_n,
1200 c_n); 1009 c_n);
1201 h->info_cb.tunnel_cb (h->info_cls, 1010 return GNUNET_SYSERR;
1202 NULL, 0, 0, NULL, NULL, 0, 0);
1203 goto clean_cls;
1204 } 1011 }
1205
1206 return GNUNET_OK; 1012 return GNUNET_OK;
1207
1208clean_cls:
1209 h->info_cb.tunnel_cb = NULL;
1210 h->info_cls = NULL;
1211 return GNUNET_SYSERR;
1212} 1013}
1213 1014
1214 1015
@@ -1228,6 +1029,9 @@ handle_get_tunnel (void *cls,
1228 const struct GNUNET_CADET_ConnectionTunnelIdentifier *conns; 1029 const struct GNUNET_CADET_ConnectionTunnelIdentifier *conns;
1229 const struct GNUNET_CADET_ChannelTunnelNumber *chns; 1030 const struct GNUNET_CADET_ChannelTunnelNumber *chns;
1230 1031
1032 if (NULL == h->info_cb.tunnel_cb)
1033 return;
1034
1231 ch_n = ntohl (msg->channels); 1035 ch_n = ntohl (msg->channels);
1232 c_n = ntohl (msg->connections); 1036 c_n = ntohl (msg->connections);
1233 1037
@@ -1245,16 +1049,14 @@ handle_get_tunnel (void *cls,
1245} 1049}
1246 1050
1247 1051
1248
1249/** 1052/**
1250 * Reconnect to the service, retransmit all infomation to try to restore the 1053 * Reconnect to the service, retransmit all infomation to try to restore the
1251 * original state. 1054 * original state.
1252 * 1055 *
1253 * @param h handle to the cadet 1056 * @param h handle to the cadet
1254 * @return #GNUNET_YES in case of success, #GNUNET_NO otherwise (service down...)
1255 */ 1057 */
1256static int 1058static void
1257do_reconnect (struct GNUNET_CADET_Handle *h) 1059reconnect (struct GNUNET_CADET_Handle *h)
1258{ 1060{
1259 struct GNUNET_MQ_MessageHandler handlers[] = { 1061 struct GNUNET_MQ_MessageHandler handlers[] = {
1260 GNUNET_MQ_hd_fixed_size (channel_created, 1062 GNUNET_MQ_hd_fixed_size (channel_created,
@@ -1273,32 +1075,25 @@ do_reconnect (struct GNUNET_CADET_Handle *h)
1273 GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK, 1075 GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK,
1274 struct GNUNET_CADET_LocalAck, 1076 struct GNUNET_CADET_LocalAck,
1275 h), 1077 h),
1276 GNUNET_MQ_hd_var_size (get_peers, 1078 GNUNET_MQ_hd_fixed_size (get_peers,
1277 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS, 1079 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS,
1278 struct GNUNET_CADET_LocalInfoPeer, 1080 struct GNUNET_CADET_LocalInfoPeer,
1279 h), 1081 h),
1280 GNUNET_MQ_hd_var_size (get_peer, 1082 GNUNET_MQ_hd_var_size (get_peer,
1281 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER, 1083 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER,
1282 struct GNUNET_CADET_LocalInfoPeer, 1084 struct GNUNET_CADET_LocalInfoPeer,
1283 h), 1085 h),
1284 GNUNET_MQ_hd_var_size (get_tunnels, 1086 GNUNET_MQ_hd_fixed_size (get_tunnels,
1285 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS, 1087 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS,
1286 struct GNUNET_CADET_LocalInfoTunnel, 1088 struct GNUNET_CADET_LocalInfoTunnel,
1287 h), 1089 h),
1288 GNUNET_MQ_hd_var_size (get_tunnel, 1090 GNUNET_MQ_hd_var_size (get_tunnel,
1289 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL, 1091 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL,
1290 struct GNUNET_CADET_LocalInfoTunnel, 1092 struct GNUNET_CADET_LocalInfoTunnel,
1291 h), 1093 h),
1292 // FIXME
1293// GNUNET_MQ_hd_fixed_Y size (channel_destroyed,
1294// GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_NACK_DEPRECATED,
1295// struct GNUNET_CADET_ChannelDestroyMessage);
1296 GNUNET_MQ_handler_end () 1094 GNUNET_MQ_handler_end ()
1297 }; 1095 };
1298 1096
1299 LOG (GNUNET_ERROR_TYPE_DEBUG, "Connecting to CADET\n");
1300
1301 GNUNET_assert (NULL == h->mq);
1302 h->mq = GNUNET_CLIENT_connect (h->cfg, 1097 h->mq = GNUNET_CLIENT_connect (h->cfg,
1303 "cadet", 1098 "cadet",
1304 handlers, 1099 handlers,
@@ -1306,92 +1101,63 @@ do_reconnect (struct GNUNET_CADET_Handle *h)
1306 h); 1101 h);
1307 if (NULL == h->mq) 1102 if (NULL == h->mq)
1308 { 1103 {
1309 reconnect (h); 1104 schedule_reconnect (h);
1310 return GNUNET_NO; 1105 return;
1311 }
1312 else
1313 {
1314 h->reconnect_time = GNUNET_TIME_UNIT_MILLISECONDS;
1315 } 1106 }
1316 return GNUNET_YES; 1107 h->reconnect_time = GNUNET_TIME_UNIT_MILLISECONDS;
1317} 1108}
1318 1109
1110
1319/** 1111/**
1320 * Reconnect callback: tries to reconnect again after a failer previous 1112 * Function called during #GNUNET_CADET_disconnect() to destroy
1321 * reconnecttion 1113 * all channels that are still open.
1322 * 1114 *
1323 * @param cls closure (cadet handle) 1115 * @param cls the `struct GNUNET_CADET_Handle`
1116 * @param cid chanenl ID
1117 * @param value a `struct GNUNET_CADET_Channel` to destroy
1118 * @return #GNUNET_OK (continue to iterate)
1324 */ 1119 */
1325static void 1120static int
1326reconnect_cbk (void *cls) 1121destroy_channel_cb (void *cls,
1122 uint32_t cid,
1123 void *value)
1327{ 1124{
1328 struct GNUNET_CADET_Handle *h = cls; 1125 /* struct GNUNET_CADET_Handle *handle = cls; */
1126 struct GNUNET_CADET_Channel *ch = value;
1329 1127
1330 h->reconnect_task = NULL; 1128 if (ntohl (ch->ccn.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
1331 do_reconnect (h); 1129 {
1130 GNUNET_break (0);
1131 LOG (GNUNET_ERROR_TYPE_DEBUG,
1132 "channel %X not destroyed\n",
1133 ntohl (ch->ccn.channel_of_client));
1134 }
1135 destroy_channel (ch);
1136 return GNUNET_OK;
1332} 1137}
1333 1138
1334 1139
1335/** 1140/**
1336 * Reconnect to the service, retransmit all infomation to try to restore the 1141 * Function called during #GNUNET_CADET_disconnect() to destroy
1337 * original state. 1142 * all ports that are still open.
1338 *
1339 * @param h handle to the cadet
1340 * 1143 *
1341 * @return #GNUNET_YES in case of sucess, #GNUNET_NO otherwise (service down...) 1144 * @param cls the `struct GNUNET_CADET_Handle`
1145 * @param id port ID
1146 * @param value a `struct GNUNET_CADET_Channel` to destroy
1147 * @return #GNUNET_OK (continue to iterate)
1342 */ 1148 */
1343static void 1149static int
1344reconnect (struct GNUNET_CADET_Handle *h) 1150destroy_port_cb (void *cls,
1345{ 1151 const struct GNUNET_HashCode *id,
1346 struct GNUNET_CADET_Channel *ch; 1152 void *value)
1347
1348 LOG (GNUNET_ERROR_TYPE_DEBUG,
1349 "Requested RECONNECT, destroying all channels\n");
1350 while (NULL != (ch = h->channels_head))
1351 destroy_channel (ch, GNUNET_YES);
1352 if (NULL == h->reconnect_task)
1353 h->reconnect_task = GNUNET_SCHEDULER_add_delayed (h->reconnect_time,
1354 &reconnect_cbk, h);
1355}
1356
1357
1358/******************************************************************************/
1359/********************** API CALL DEFINITIONS *************************/
1360/******************************************************************************/
1361
1362struct GNUNET_CADET_Handle *
1363GNUNET_CADET_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
1364 void *cls,
1365 GNUNET_CADET_ChannelEndHandler cleaner,
1366 const struct GNUNET_CADET_MessageHandler *handlers)
1367{ 1153{
1368 struct GNUNET_CADET_Handle *h; 1154 /* struct GNUNET_CADET_Handle *handle = cls; */
1369 1155 struct GNUNET_CADET_Port *port = value;
1370 h = GNUNET_new (struct GNUNET_CADET_Handle);
1371 LOG (GNUNET_ERROR_TYPE_DEBUG,
1372 "GNUNET_CADET_connect() %p\n",
1373 h);
1374 h->cfg = cfg;
1375 h->cleaner = cleaner;
1376 h->ports = GNUNET_CONTAINER_multihashmap_create (4, GNUNET_YES);
1377 do_reconnect (h);
1378 if (h->mq == NULL)
1379 {
1380 GNUNET_break (0);
1381 GNUNET_CADET_disconnect (h);
1382 return NULL;
1383 }
1384 h->cls = cls;
1385 h->message_handlers = handlers;
1386 h->next_ccn.channel_of_client = htonl (GNUNET_CADET_LOCAL_CHANNEL_ID_CLI);
1387 h->reconnect_time = GNUNET_TIME_UNIT_MILLISECONDS;
1388 h->reconnect_task = NULL;
1389 1156
1390 /* count handlers */ 1157 /* This is a warning, the app should have cleanly closed all open ports */
1391 for (h->n_handlers = 0; 1158 GNUNET_break (0);
1392 handlers && handlers[h->n_handlers].type; 1159 GNUNET_CADET_close_port (port);
1393 h->n_handlers++) ; 1160 return GNUNET_OK;
1394 return h;
1395} 1161}
1396 1162
1397 1163
@@ -1406,58 +1172,16 @@ GNUNET_CADET_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
1406void 1172void
1407GNUNET_CADET_disconnect (struct GNUNET_CADET_Handle *handle) 1173GNUNET_CADET_disconnect (struct GNUNET_CADET_Handle *handle)
1408{ 1174{
1409 struct GNUNET_CADET_Channel *ch; 1175 GNUNET_CONTAINER_multihashmap_iterate (handle->ports,
1410 struct GNUNET_CADET_Channel *aux; 1176 &destroy_port_cb,
1411 struct GNUNET_CADET_TransmitHandle *th; 1177 handle);
1412 1178 GNUNET_CONTAINER_multihashmap_destroy (handle->ports);
1413 LOG (GNUNET_ERROR_TYPE_DEBUG, 1179 handle->ports = NULL;
1414 "CADET DISCONNECT\n"); 1180 GNUNET_CONTAINER_multihashmap32_iterate (handle->channels,
1415 ch = handle->channels_head; 1181 &destroy_channel_cb,
1416 while (NULL != ch) 1182 handle);
1417 { 1183 GNUNET_CONTAINER_multihashmap32_destroy (handle->channels);
1418 aux = ch->next; 1184 handle->channels = NULL;
1419 if (ntohl (ch->ccn.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
1420 {
1421 GNUNET_break (0);
1422 LOG (GNUNET_ERROR_TYPE_DEBUG,
1423 "channel %X not destroyed\n",
1424 ntohl (ch->ccn.channel_of_client));
1425 }
1426 destroy_channel (ch,
1427 GNUNET_YES);
1428 ch = aux;
1429 }
1430 while (NULL != (th = handle->th_head))
1431 {
1432 struct GNUNET_MessageHeader *msg;
1433
1434 /* Make sure it is an allowed packet (everything else should have been
1435 * already canceled).
1436 */
1437 GNUNET_break (GNUNET_NO == th_is_payload (th));
1438 msg = (struct GNUNET_MessageHeader *) &th[1];
1439 switch (ntohs(msg->type))
1440 {
1441 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN:
1442 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY:
1443 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_OPEN:
1444 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE:
1445 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CHANNELS:
1446 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CHANNEL:
1447 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER:
1448 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS:
1449 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL:
1450 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS:
1451 break;
1452 default:
1453 GNUNET_break (0);
1454 LOG (GNUNET_ERROR_TYPE_ERROR, "unexpected unsent msg %s\n",
1455 GC_m2s (ntohs(msg->type)));
1456 }
1457
1458 GNUNET_CADET_notify_transmit_ready_cancel (th);
1459 }
1460
1461 if (NULL != handle->mq) 1185 if (NULL != handle->mq)
1462 { 1186 {
1463 GNUNET_MQ_destroy (handle->mq); 1187 GNUNET_MQ_destroy (handle->mq);
@@ -1465,58 +1189,15 @@ GNUNET_CADET_disconnect (struct GNUNET_CADET_Handle *handle)
1465 } 1189 }
1466 if (NULL != handle->reconnect_task) 1190 if (NULL != handle->reconnect_task)
1467 { 1191 {
1468 GNUNET_SCHEDULER_cancel(handle->reconnect_task); 1192 GNUNET_SCHEDULER_cancel (handle->reconnect_task);
1469 handle->reconnect_task = NULL; 1193 handle->reconnect_task = NULL;
1470 } 1194 }
1471
1472 GNUNET_CONTAINER_multihashmap_destroy (handle->ports);
1473 handle->ports = NULL;
1474 GNUNET_free (handle); 1195 GNUNET_free (handle);
1475} 1196}
1476 1197
1477 1198
1478/** 1199/**
1479 * Open a port to receive incomming channels. 1200 * Close a port opened with @a GNUNET_CADET_open_port().
1480 *
1481 * @param h CADET handle.
1482 * @param port Hash representing the port number.
1483 * @param new_channel Function called when an channel is received.
1484 * @param new_channel_cls Closure for @a new_channel.
1485 * @return Port handle.
1486 */
1487struct GNUNET_CADET_Port *
1488GNUNET_CADET_open_port (struct GNUNET_CADET_Handle *h,
1489 const struct GNUNET_HashCode *port,
1490 GNUNET_CADET_InboundChannelNotificationHandler
1491 new_channel,
1492 void *new_channel_cls)
1493{
1494 struct GNUNET_CADET_PortMessage *msg;
1495 struct GNUNET_MQ_Envelope *env;
1496 struct GNUNET_CADET_Port *p;
1497
1498 GNUNET_assert (NULL != new_channel);
1499 p = GNUNET_new (struct GNUNET_CADET_Port);
1500 p->cadet = h;
1501 p->hash = GNUNET_new (struct GNUNET_HashCode);
1502 *p->hash = *port;
1503 p->handler = new_channel;
1504 p->cls = new_channel_cls;
1505 GNUNET_assert (GNUNET_OK ==
1506 GNUNET_CONTAINER_multihashmap_put (h->ports,
1507 p->hash,
1508 p,
1509 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1510
1511 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_OPEN);
1512 msg->port = *p->hash;
1513 GNUNET_MQ_send (h->mq, env);
1514
1515 return p;
1516}
1517
1518/**
1519 * Close a port opened with @a GNUNET_CADET_open_port.
1520 * The @a new_channel callback will no longer be called. 1201 * The @a new_channel callback will no longer be called.
1521 * 1202 *
1522 * @param p Port handle. 1203 * @param p Port handle.
@@ -1527,110 +1208,45 @@ GNUNET_CADET_close_port (struct GNUNET_CADET_Port *p)
1527 struct GNUNET_CADET_PortMessage *msg; 1208 struct GNUNET_CADET_PortMessage *msg;
1528 struct GNUNET_MQ_Envelope *env; 1209 struct GNUNET_MQ_Envelope *env;
1529 1210
1530 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE); 1211 env = GNUNET_MQ_msg (msg,
1531 1212 GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE);
1532 msg->port = *p->hash; 1213 msg->port = p->id;
1533 GNUNET_MQ_send (p->cadet->mq, env); 1214 GNUNET_MQ_send (p->cadet->mq,
1534 GNUNET_CONTAINER_multihashmap_remove (p->cadet->ports, p->hash, p); 1215 env);
1535 GNUNET_free (p->hash); 1216 GNUNET_assert (GNUNET_YES ==
1217 GNUNET_CONTAINER_multihashmap_remove (p->cadet->ports,
1218 &p->id,
1219 p));
1220 GNUNET_free_non_null (p->handlers);
1536 GNUNET_free (p); 1221 GNUNET_free (p);
1537} 1222}
1538 1223
1539 1224
1540/** 1225/**
1541 * Create a new channel towards a remote peer. 1226 * Destroy an existing channel.
1542 * 1227 *
1543 * If the destination port is not open by any peer or the destination peer 1228 * The existing end callback for the channel will be called immediately.
1544 * does not accept the channel, #GNUNET_CADET_ChannelEndHandler will be called 1229 * Any pending outgoing messages will be sent but no incoming messages will be
1545 * for this channel. 1230 * accepted and no data callbacks will be called.
1546 * 1231 *
1547 * @param h cadet handle 1232 * @param channel Channel handle, becomes invalid after this call.
1548 * @param channel_ctx client's channel context to associate with the channel
1549 * @param peer peer identity the channel should go to
1550 * @param port Port hash (port number).
1551 * @param options CadetOption flag field, with all desired option bits set to 1.
1552 * @return handle to the channel
1553 */ 1233 */
1554struct GNUNET_CADET_Channel *
1555GNUNET_CADET_channel_create (struct GNUNET_CADET_Handle *h,
1556 void *channel_ctx,
1557 const struct GNUNET_PeerIdentity *peer,
1558 const struct GNUNET_HashCode *port,
1559 enum GNUNET_CADET_ChannelOption options)
1560{
1561 struct GNUNET_CADET_LocalChannelCreateMessage *msg;
1562 struct GNUNET_MQ_Envelope *env;
1563 struct GNUNET_CADET_Channel *ch;
1564 struct GNUNET_CADET_ClientChannelNumber ccn;
1565
1566 ccn.channel_of_client = htonl (0);
1567 ch = create_channel (h, ccn);
1568 ch->ctx = channel_ctx;
1569 ch->peer = GNUNET_PEER_intern (peer);
1570
1571 LOG (GNUNET_ERROR_TYPE_DEBUG,
1572 "Creating new channel to %s:%u at %p number %X\n",
1573 GNUNET_i2s (peer),
1574 port,
1575 ch,
1576 ntohl (ch->ccn.channel_of_client));
1577 env = GNUNET_MQ_msg (msg,
1578 GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE);
1579 msg->ccn = ch->ccn;
1580 msg->port = *port;
1581 msg->peer = *peer;
1582 msg->opt = htonl (options);
1583 GNUNET_MQ_send (h->mq,
1584 env);
1585 return ch;
1586}
1587
1588
1589void 1234void
1590GNUNET_CADET_channel_destroy (struct GNUNET_CADET_Channel *channel) 1235GNUNET_CADET_channel_destroy (struct GNUNET_CADET_Channel *channel)
1591{ 1236{
1592 struct GNUNET_CADET_Handle *h; 1237 struct GNUNET_CADET_Handle *h = channel->cadet;
1593 struct GNUNET_CADET_LocalChannelDestroyMessage *msg; 1238 struct GNUNET_CADET_LocalChannelDestroyMessage *msg;
1594 struct GNUNET_MQ_Envelope *env; 1239 struct GNUNET_MQ_Envelope *env;
1595 struct GNUNET_CADET_TransmitHandle *th;
1596 struct GNUNET_CADET_TransmitHandle *next;
1597 1240
1598 LOG (GNUNET_ERROR_TYPE_DEBUG, 1241 if (NULL != h->mq)
1599 "Destroying channel\n");
1600 h = channel->cadet;
1601 for (th = h->th_head; th != NULL; th = next)
1602 { 1242 {
1603 next = th->next; 1243 env = GNUNET_MQ_msg (msg,
1604 if (th->channel == channel) 1244 GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY);
1605 { 1245 msg->ccn = channel->ccn;
1606 GNUNET_break (0); 1246 GNUNET_MQ_send (h->mq,
1607 if (GNUNET_YES == th_is_payload (th)) 1247 env);
1608 {
1609 /* applications should cancel before destroying channel */
1610 LOG (GNUNET_ERROR_TYPE_WARNING,
1611 "Channel destroyed without cancelling transmission requests\n");
1612 th->notify (th->notify_cls, 0, NULL);
1613 }
1614 else
1615 {
1616 LOG (GNUNET_ERROR_TYPE_WARNING,
1617 "no meta-traffic should be queued\n");
1618 }
1619 GNUNET_CONTAINER_DLL_remove (h->th_head,
1620 h->th_tail,
1621 th);
1622 GNUNET_CADET_notify_transmit_ready_cancel (th);
1623 }
1624 } 1248 }
1625 1249 destroy_channel (channel);
1626 env = GNUNET_MQ_msg (msg,
1627 GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY);
1628 msg->ccn = channel->ccn;
1629 GNUNET_MQ_send (h->mq,
1630 env);
1631
1632 destroy_channel (channel,
1633 GNUNET_YES);
1634} 1250}
1635 1251
1636 1252
@@ -1645,10 +1261,10 @@ GNUNET_CADET_channel_destroy (struct GNUNET_CADET_Channel *channel)
1645 */ 1261 */
1646const union GNUNET_CADET_ChannelInfo * 1262const union GNUNET_CADET_ChannelInfo *
1647GNUNET_CADET_channel_get_info (struct GNUNET_CADET_Channel *channel, 1263GNUNET_CADET_channel_get_info (struct GNUNET_CADET_Channel *channel,
1648 enum GNUNET_CADET_ChannelOption option, ...) 1264 enum GNUNET_CADET_ChannelOption option,
1265 ...)
1649{ 1266{
1650 static int bool_flag; 1267 static int bool_flag;
1651 const union GNUNET_CADET_ChannelInfo *ret;
1652 1268
1653 switch (option) 1269 switch (option)
1654 { 1270 {
@@ -1659,74 +1275,15 @@ GNUNET_CADET_channel_get_info (struct GNUNET_CADET_Channel *channel,
1659 bool_flag = GNUNET_YES; 1275 bool_flag = GNUNET_YES;
1660 else 1276 else
1661 bool_flag = GNUNET_NO; 1277 bool_flag = GNUNET_NO;
1662 ret = (const union GNUNET_CADET_ChannelInfo *) &bool_flag; 1278 return (const union GNUNET_CADET_ChannelInfo *) &bool_flag;
1663 break; 1279 break;
1664 case GNUNET_CADET_OPTION_PEER: 1280 case GNUNET_CADET_OPTION_PEER:
1665 ret = (const union GNUNET_CADET_ChannelInfo *) GNUNET_PEER_resolve2 (channel->peer); 1281 return (const union GNUNET_CADET_ChannelInfo *) &channel->peer;
1666 break; 1282 break;
1667 default: 1283 default:
1668 GNUNET_break (0); 1284 GNUNET_break (0);
1669 return NULL; 1285 return NULL;
1670 } 1286 }
1671
1672 return ret;
1673}
1674
1675
1676struct GNUNET_CADET_TransmitHandle *
1677GNUNET_CADET_notify_transmit_ready (struct GNUNET_CADET_Channel *channel,
1678 int cork,
1679 struct GNUNET_TIME_Relative maxdelay,
1680 size_t notify_size,
1681 GNUNET_CONNECTION_TransmitReadyNotify notify,
1682 void *notify_cls)
1683{
1684 struct GNUNET_CADET_TransmitHandle *th;
1685
1686 GNUNET_assert (NULL != channel);
1687 GNUNET_assert (NULL != notify);
1688 GNUNET_assert (GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE >= notify_size);
1689 LOG (GNUNET_ERROR_TYPE_DEBUG,
1690 "CADET NOTIFY TRANSMIT READY on channel %X allow_send is %u to %s with %u bytes\n",
1691 channel->ccn,
1692 channel->allow_send,
1693 (ntohl (channel->ccn.channel_of_client) >=
1694 GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
1695 ? "origin"
1696 : "destination",
1697 (unsigned int) notify_size);
1698 if (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us != maxdelay.rel_value_us)
1699 {
1700 LOG (GNUNET_ERROR_TYPE_WARNING,
1701 "CADET transmit ready timeout is deprected (has no effect)\n");
1702 }
1703
1704 th = GNUNET_new (struct GNUNET_CADET_TransmitHandle);
1705 th->channel = channel;
1706 th->size = notify_size;
1707 th->notify = notify;
1708 th->notify_cls = notify_cls;
1709 if (0 != channel->allow_send)
1710 th->request_data_task
1711 = GNUNET_SCHEDULER_add_now (&request_data,
1712 th);
1713 else
1714 add_to_queue (channel->cadet,
1715 th);
1716 return th;
1717}
1718
1719
1720void
1721GNUNET_CADET_notify_transmit_ready_cancel (struct GNUNET_CADET_TransmitHandle *th)
1722{
1723 if (NULL != th->request_data_task)
1724 {
1725 GNUNET_SCHEDULER_cancel (th->request_data_task);
1726 th->request_data_task = NULL;
1727 }
1728 remove_from_queue (th);
1729 GNUNET_free (th);
1730} 1287}
1731 1288
1732 1289
@@ -1745,25 +1302,30 @@ GNUNET_CADET_receive_done (struct GNUNET_CADET_Channel *channel)
1745 GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK); 1302 GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK);
1746 LOG (GNUNET_ERROR_TYPE_DEBUG, 1303 LOG (GNUNET_ERROR_TYPE_DEBUG,
1747 "Sending ACK on channel %X\n", 1304 "Sending ACK on channel %X\n",
1748 channel->ccn.channel_of_client); 1305 ntohl (channel->ccn.channel_of_client));
1749 msg->ccn = channel->ccn; 1306 msg->ccn = channel->ccn;
1750 GNUNET_MQ_send (channel->cadet->mq, 1307 GNUNET_MQ_send (channel->cadet->mq,
1751 env); 1308 env);
1752} 1309}
1753 1310
1754 1311
1312/**
1313 * Send message of @a type to CADET service of @a h
1314 *
1315 * @param h handle to CADET service
1316 * @param type message type of trivial information request to send
1317 */
1755static void 1318static void
1756send_info_request (struct GNUNET_CADET_Handle *h, uint16_t type) 1319send_info_request (struct GNUNET_CADET_Handle *h,
1320 uint16_t type)
1757{ 1321{
1758 struct GNUNET_MessageHeader *msg; 1322 struct GNUNET_MessageHeader *msg;
1759 struct GNUNET_MQ_Envelope *env; 1323 struct GNUNET_MQ_Envelope *env;
1760 1324
1761 LOG (GNUNET_ERROR_TYPE_DEBUG, 1325 env = GNUNET_MQ_msg (msg,
1762 " Sending %s monitor message to service\n", 1326 type);
1763 GC_m2s(type)); 1327 GNUNET_MQ_send (h->mq,
1764 1328 env);
1765 env = GNUNET_MQ_msg (msg, type);
1766 GNUNET_MQ_send (h->mq, env);
1767} 1329}
1768 1330
1769 1331
@@ -1777,8 +1339,8 @@ send_info_request (struct GNUNET_CADET_Handle *h, uint16_t type)
1777void 1339void
1778GNUNET_CADET_request_dump (struct GNUNET_CADET_Handle *h) 1340GNUNET_CADET_request_dump (struct GNUNET_CADET_Handle *h)
1779{ 1341{
1780 LOG (GNUNET_ERROR_TYPE_DEBUG, "requesting dump\n"); 1342 send_info_request (h,
1781 send_info_request (h, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_DUMP); 1343 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_DUMP);
1782} 1344}
1783 1345
1784 1346
@@ -1787,13 +1349,11 @@ GNUNET_CADET_request_dump (struct GNUNET_CADET_Handle *h)
1787 * The callback will be called for every peer known to the service. 1349 * The callback will be called for every peer known to the service.
1788 * Only one info request (of any kind) can be active at once. 1350 * Only one info request (of any kind) can be active at once.
1789 * 1351 *
1790 *
1791 * WARNING: unstable API, likely to change in the future! 1352 * WARNING: unstable API, likely to change in the future!
1792 * 1353 *
1793 * @param h Handle to the cadet peer. 1354 * @param h Handle to the cadet peer.
1794 * @param callback Function to call with the requested data. 1355 * @param callback Function to call with the requested data.
1795 * @param callback_cls Closure for @c callback. 1356 * @param callback_cls Closure for @c callback.
1796 *
1797 * @return #GNUNET_OK / #GNUNET_SYSERR 1357 * @return #GNUNET_OK / #GNUNET_SYSERR
1798 */ 1358 */
1799int 1359int
@@ -1806,7 +1366,8 @@ GNUNET_CADET_get_peers (struct GNUNET_CADET_Handle *h,
1806 GNUNET_break (0); 1366 GNUNET_break (0);
1807 return GNUNET_SYSERR; 1367 return GNUNET_SYSERR;
1808 } 1368 }
1809 send_info_request (h, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS); 1369 send_info_request (h,
1370 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS);
1810 h->info_cb.peers_cb = callback; 1371 h->info_cb.peers_cb = callback;
1811 h->info_cls = callback_cls; 1372 h->info_cls = callback_cls;
1812 return GNUNET_OK; 1373 return GNUNET_OK;
@@ -1819,15 +1380,13 @@ GNUNET_CADET_get_peers (struct GNUNET_CADET_Handle *h,
1819 * WARNING: unstable API, likely to change in the future! 1380 * WARNING: unstable API, likely to change in the future!
1820 * 1381 *
1821 * @param h Cadet handle. 1382 * @param h Cadet handle.
1822 * 1383 * @return Closure given to GNUNET_CADET_get_peers().
1823 * @return Closure given to GNUNET_CADET_get_peers.
1824 */ 1384 */
1825void * 1385void *
1826GNUNET_CADET_get_peers_cancel (struct GNUNET_CADET_Handle *h) 1386GNUNET_CADET_get_peers_cancel (struct GNUNET_CADET_Handle *h)
1827{ 1387{
1828 void *cls; 1388 void *cls = h->info_cls;
1829 1389
1830 cls = h->info_cls;
1831 h->info_cb.peers_cb = NULL; 1390 h->info_cb.peers_cb = NULL;
1832 h->info_cls = NULL; 1391 h->info_cls = NULL;
1833 return cls; 1392 return cls;
@@ -1845,7 +1404,6 @@ GNUNET_CADET_get_peers_cancel (struct GNUNET_CADET_Handle *h)
1845 * @param id Peer whose tunnel to examine. 1404 * @param id Peer whose tunnel to examine.
1846 * @param callback Function to call with the requested data. 1405 * @param callback Function to call with the requested data.
1847 * @param callback_cls Closure for @c callback. 1406 * @param callback_cls Closure for @c callback.
1848 *
1849 * @return #GNUNET_OK / #GNUNET_SYSERR 1407 * @return #GNUNET_OK / #GNUNET_SYSERR
1850 */ 1408 */
1851int 1409int
@@ -1862,11 +1420,11 @@ GNUNET_CADET_get_peer (struct GNUNET_CADET_Handle *h,
1862 GNUNET_break (0); 1420 GNUNET_break (0);
1863 return GNUNET_SYSERR; 1421 return GNUNET_SYSERR;
1864 } 1422 }
1865 1423 env = GNUNET_MQ_msg (msg,
1866 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER); 1424 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER);
1867 msg->peer = *id; 1425 msg->peer = *id;
1868 GNUNET_MQ_send (h->mq, env); 1426 GNUNET_MQ_send (h->mq,
1869 1427 env);
1870 h->info_cb.peer_cb = callback; 1428 h->info_cb.peer_cb = callback;
1871 h->info_cls = callback_cls; 1429 h->info_cls = callback_cls;
1872 return GNUNET_OK; 1430 return GNUNET_OK;
@@ -1883,7 +1441,6 @@ GNUNET_CADET_get_peer (struct GNUNET_CADET_Handle *h,
1883 * @param h Handle to the cadet peer. 1441 * @param h Handle to the cadet peer.
1884 * @param callback Function to call with the requested data. 1442 * @param callback Function to call with the requested data.
1885 * @param callback_cls Closure for @c callback. 1443 * @param callback_cls Closure for @c callback.
1886 *
1887 * @return #GNUNET_OK / #GNUNET_SYSERR 1444 * @return #GNUNET_OK / #GNUNET_SYSERR
1888 */ 1445 */
1889int 1446int
@@ -1896,7 +1453,8 @@ GNUNET_CADET_get_tunnels (struct GNUNET_CADET_Handle *h,
1896 GNUNET_break (0); 1453 GNUNET_break (0);
1897 return GNUNET_SYSERR; 1454 return GNUNET_SYSERR;
1898 } 1455 }
1899 send_info_request (h, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS); 1456 send_info_request (h,
1457 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS);
1900 h->info_cb.tunnels_cb = callback; 1458 h->info_cb.tunnels_cb = callback;
1901 h->info_cls = callback_cls; 1459 h->info_cls = callback_cls;
1902 return GNUNET_OK; 1460 return GNUNET_OK;
@@ -1907,23 +1465,19 @@ GNUNET_CADET_get_tunnels (struct GNUNET_CADET_Handle *h,
1907 * Cancel a monitor request. The monitor callback will not be called. 1465 * Cancel a monitor request. The monitor callback will not be called.
1908 * 1466 *
1909 * @param h Cadet handle. 1467 * @param h Cadet handle.
1910 * 1468 * @return Closure given to GNUNET_CADET_get_tunnels().
1911 * @return Closure given to GNUNET_CADET_get_tunnels.
1912 */ 1469 */
1913void * 1470void *
1914GNUNET_CADET_get_tunnels_cancel (struct GNUNET_CADET_Handle *h) 1471GNUNET_CADET_get_tunnels_cancel (struct GNUNET_CADET_Handle *h)
1915{ 1472{
1916 void *cls; 1473 void *cls = h->info_cls;
1917 1474
1918 h->info_cb.tunnels_cb = NULL; 1475 h->info_cb.tunnels_cb = NULL;
1919 cls = h->info_cls;
1920 h->info_cls = NULL; 1476 h->info_cls = NULL;
1921
1922 return cls; 1477 return cls;
1923} 1478}
1924 1479
1925 1480
1926
1927/** 1481/**
1928 * Request information about a tunnel of the running cadet peer. 1482 * Request information about a tunnel of the running cadet peer.
1929 * The callback will be called for the tunnel once. 1483 * The callback will be called for the tunnel once.
@@ -1935,7 +1489,6 @@ GNUNET_CADET_get_tunnels_cancel (struct GNUNET_CADET_Handle *h)
1935 * @param id Peer whose tunnel to examine. 1489 * @param id Peer whose tunnel to examine.
1936 * @param callback Function to call with the requested data. 1490 * @param callback Function to call with the requested data.
1937 * @param callback_cls Closure for @c callback. 1491 * @param callback_cls Closure for @c callback.
1938 *
1939 * @return #GNUNET_OK / #GNUNET_SYSERR 1492 * @return #GNUNET_OK / #GNUNET_SYSERR
1940 */ 1493 */
1941int 1494int
@@ -1952,11 +1505,11 @@ GNUNET_CADET_get_tunnel (struct GNUNET_CADET_Handle *h,
1952 GNUNET_break (0); 1505 GNUNET_break (0);
1953 return GNUNET_SYSERR; 1506 return GNUNET_SYSERR;
1954 } 1507 }
1955 1508 env = GNUNET_MQ_msg (msg,
1956 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL); 1509 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL);
1957 msg->peer = *id; 1510 msg->peer = *id;
1958 GNUNET_MQ_send (h->mq, env); 1511 GNUNET_MQ_send (h->mq,
1959 1512 env);
1960 h->info_cb.tunnel_cb = callback; 1513 h->info_cb.tunnel_cb = callback;
1961 h->info_cls = callback_cls; 1514 h->info_cls = callback_cls;
1962 return GNUNET_OK; 1515 return GNUNET_OK;
@@ -1964,175 +1517,190 @@ GNUNET_CADET_get_tunnel (struct GNUNET_CADET_Handle *h,
1964 1517
1965 1518
1966/** 1519/**
1967 * Request information about a specific channel of the running cadet peer. 1520 * Transitional function to convert an unsigned int port to a hash value.
1968 * 1521 * WARNING: local static value returned, NOT reentrant!
1969 * WARNING: unstable API, likely to change in the future! 1522 * WARNING: do not use this function for new code!
1970 * FIXME Add destination option.
1971 * 1523 *
1972 * @param h Handle to the cadet peer. 1524 * @param port Numerical port (unsigned int format).
1973 * @param initiator ID of the owner of the channel.
1974 * @param channel_number Channel number.
1975 * @param callback Function to call with the requested data.
1976 * @param callback_cls Closure for @c callback.
1977 * 1525 *
1978 * @return #GNUNET_OK / #GNUNET_SYSERR 1526 * @return A GNUNET_HashCode usable for the new CADET API.
1979 */ 1527 */
1980int 1528const struct GNUNET_HashCode *
1981GNUNET_CADET_show_channel (struct GNUNET_CADET_Handle *h, 1529GC_u2h (uint32_t port)
1982 struct GNUNET_PeerIdentity *initiator,
1983 unsigned int channel_number,
1984 GNUNET_CADET_ChannelCB callback,
1985 void *callback_cls)
1986{ 1530{
1987 struct GNUNET_CADET_LocalInfo *msg; 1531 static struct GNUNET_HashCode hash;
1988 struct GNUNET_MQ_Envelope *env;
1989
1990 if (NULL != h->info_cb.channel_cb)
1991 {
1992 GNUNET_break (0);
1993 return GNUNET_SYSERR;
1994 }
1995
1996 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CHANNEL);
1997 msg->peer = *initiator;
1998 msg->ccn.channel_of_client = htonl (channel_number);
1999 GNUNET_MQ_send (h->mq, env);
2000 1532
2001 h->info_cb.channel_cb = callback; 1533 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2002 h->info_cls = callback_cls; 1534 "This is a transitional function, use proper crypto hashes as CADET ports\n");
2003 return GNUNET_OK; 1535 GNUNET_CRYPTO_hash (&port,
1536 sizeof (port),
1537 &hash);
1538 return &hash;
2004} 1539}
2005 1540
2006 1541
2007/** 1542/**
2008 * Function called to notify a client about the connection 1543 * Connect to the MQ-based cadet service.
2009 * begin ready to queue more data. "buf" will be
2010 * NULL and "size" zero if the connection was closed for
2011 * writing in the meantime.
2012 * 1544 *
2013 * @param cls closure 1545 * @param cfg Configuration to use.
2014 * @param size number of bytes available in buf 1546 *
2015 * @param buf where the callee should write the message 1547 * @return Handle to the cadet service NULL on error.
2016 * @return number of bytes written to buf
2017 */ 1548 */
2018static size_t 1549struct GNUNET_CADET_Handle *
2019cadet_mq_ntr (void *cls, size_t size, 1550GNUNET_CADET_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
2020 void *buf)
2021{ 1551{
2022 struct GNUNET_MQ_Handle *mq = cls; 1552 struct GNUNET_CADET_Handle *h;
2023 struct CadetMQState *state = GNUNET_MQ_impl_state (mq);
2024 const struct GNUNET_MessageHeader *msg = GNUNET_MQ_impl_current (mq);
2025 uint16_t msize;
2026 1553
2027 state->th = NULL; 1554 LOG (GNUNET_ERROR_TYPE_DEBUG,
2028 if (NULL == buf) 1555 "GNUNET_CADET_connect()\n");
1556 h = GNUNET_new (struct GNUNET_CADET_Handle);
1557 h->cfg = cfg;
1558 h->ports = GNUNET_CONTAINER_multihashmap_create (4,
1559 GNUNET_YES);
1560 h->channels = GNUNET_CONTAINER_multihashmap32_create (4);
1561 reconnect (h);
1562 if (NULL == h->mq)
2029 { 1563 {
2030 GNUNET_MQ_inject_error (mq, GNUNET_MQ_ERROR_WRITE); 1564 GNUNET_break (0);
2031 return 0; 1565 GNUNET_CADET_disconnect (h);
1566 return NULL;
2032 } 1567 }
2033 msize = ntohs (msg->size); 1568 h->next_ccn.channel_of_client = htonl (GNUNET_CADET_LOCAL_CHANNEL_ID_CLI);
2034 GNUNET_assert (msize <= size); 1569 h->reconnect_time = GNUNET_TIME_UNIT_MILLISECONDS;
2035 GNUNET_memcpy (buf, msg, msize); 1570 h->reconnect_task = NULL;
2036 GNUNET_MQ_impl_send_continue (mq); 1571
2037 return msize; 1572 return h;
2038} 1573}
2039 1574
2040 1575
2041/** 1576/**
2042 * Signature of functions implementing the 1577 * Open a port to receive incomming MQ-based channels.
2043 * sending functionality of a message queue.
2044 * 1578 *
2045 * @param mq the message queue 1579 * @param h CADET handle.
2046 * @param msg the message to send 1580 * @param port Hash identifying the port.
2047 * @param impl_state state of the implementation 1581 * @param connects Function called when an incoming channel is connected.
1582 * @param connects_cls Closure for the @a connects handler.
1583 * @param window_changes Function called when the transmit window size changes.
1584 * @param disconnects Function called when a channel is disconnected.
1585 * @param handlers Callbacks for messages we care about, NULL-terminated.
1586 * @return Port handle.
2048 */ 1587 */
2049static void 1588struct GNUNET_CADET_Port *
2050cadet_mq_send_impl (struct GNUNET_MQ_Handle *mq, 1589GNUNET_CADET_open_port (struct GNUNET_CADET_Handle *h,
2051 const struct GNUNET_MessageHeader *msg, 1590 const struct GNUNET_HashCode *port,
2052 void *impl_state) 1591 GNUNET_CADET_ConnectEventHandler connects,
1592 void * connects_cls,
1593 GNUNET_CADET_WindowSizeEventHandler window_changes,
1594 GNUNET_CADET_DisconnectEventHandler disconnects,
1595 const struct GNUNET_MQ_MessageHandler *handlers)
2053{ 1596{
2054 struct CadetMQState *state = impl_state; 1597 struct GNUNET_CADET_PortMessage *msg;
2055 1598 struct GNUNET_MQ_Envelope *env;
2056 GNUNET_assert (NULL == state->th); 1599 struct GNUNET_CADET_Port *p;
2057 state->th =
2058 GNUNET_CADET_notify_transmit_ready (state->channel,
2059 /* FIXME: add option for corking */
2060 GNUNET_NO,
2061 GNUNET_TIME_UNIT_FOREVER_REL,
2062 ntohs (msg->size),
2063 &cadet_mq_ntr, mq);
2064
2065}
2066 1600
1601 GNUNET_assert (NULL != connects);
1602 GNUNET_assert (NULL != disconnects);
2067 1603
2068/** 1604 p = GNUNET_new (struct GNUNET_CADET_Port);
2069 * Signature of functions implementing the 1605 p->cadet = h;
2070 * destruction of a message queue. 1606 p->id = *port;
2071 * Implementations must not free 'mq', but should 1607 p->connects = connects;
2072 * take care of 'impl_state'. 1608 p->cls = connects_cls;
2073 * 1609 p->window_changes = window_changes;
2074 * @param mq the message queue to destroy 1610 p->disconnects = disconnects;
2075 * @param impl_state state of the implementation 1611 p->handlers = GNUNET_MQ_copy_handlers (handlers);
2076 */
2077static void
2078cadet_mq_destroy_impl (struct GNUNET_MQ_Handle *mq,
2079 void *impl_state)
2080{
2081 struct CadetMQState *state = impl_state;
2082 1612
2083 if (NULL != state->th) 1613 GNUNET_assert (GNUNET_OK ==
2084 GNUNET_CADET_notify_transmit_ready_cancel (state->th); 1614 GNUNET_CONTAINER_multihashmap_put (h->ports,
1615 &p->id,
1616 p,
1617 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
2085 1618
2086 GNUNET_free (state); 1619 env = GNUNET_MQ_msg (msg,
1620 GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_OPEN);
1621 msg->port = p->id;
1622 GNUNET_MQ_send (h->mq,
1623 env);
1624 return p;
2087} 1625}
2088 1626
2089 1627
2090/** 1628/**
2091 * Create a message queue for a cadet channel. 1629 * Create a new channel towards a remote peer.
2092 * The message queue can only be used to transmit messages,
2093 * not to receive them.
2094 * 1630 *
2095 * @param channel the channel to create the message qeue for 1631 * If the destination port is not open by any peer or the destination peer
2096 * @return a message queue to messages over the channel 1632 * does not accept the channel, #GNUNET_CADET_ChannelEndHandler will be called
1633 * for this channel.
1634 *
1635 * @param h CADET handle.
1636 * @param channel_cls Closure for the channel. It's given to:
1637 * - The disconnect handler @a disconnects
1638 * - Each message type callback in @a handlers
1639 * @param destination Peer identity the channel should go to.
1640 * @param port Identification of the destination port.
1641 * @param options CadetOption flag field, with all desired option bits set to 1.
1642 * @param window_changes Function called when the transmit window size changes.
1643 * @param disconnects Function called when the channel is disconnected.
1644 * @param handlers Callbacks for messages we care about, NULL-terminated.
1645 * @return Handle to the channel.
2097 */ 1646 */
2098struct GNUNET_MQ_Handle * 1647struct GNUNET_CADET_Channel *
2099GNUNET_CADET_mq_create (struct GNUNET_CADET_Channel *channel) 1648GNUNET_CADET_channel_create (struct GNUNET_CADET_Handle *h,
1649 void *channel_cls,
1650 const struct GNUNET_PeerIdentity *destination,
1651 const struct GNUNET_HashCode *port,
1652 enum GNUNET_CADET_ChannelOption options,
1653 GNUNET_CADET_WindowSizeEventHandler window_changes,
1654 GNUNET_CADET_DisconnectEventHandler disconnects,
1655 const struct GNUNET_MQ_MessageHandler *handlers)
2100{ 1656{
2101 struct GNUNET_MQ_Handle *mq; 1657 struct GNUNET_CADET_Channel *ch;
2102 struct CadetMQState *state; 1658 struct GNUNET_CADET_LocalChannelCreateMessage *msg;
2103 1659 struct GNUNET_MQ_Envelope *env;
2104 state = GNUNET_new (struct CadetMQState); 1660
2105 state->channel = channel; 1661 GNUNET_assert (NULL != disconnects);
2106 1662 ch = create_channel (h,
2107 mq = GNUNET_MQ_queue_for_callbacks (&cadet_mq_send_impl, 1663 NULL);
2108 &cadet_mq_destroy_impl, 1664 ch->ctx = channel_cls;
2109 NULL, /* FIXME: cancel impl. */ 1665 ch->peer = *destination;
2110 state, 1666 ch->options = options;
2111 NULL, /* no msg handlers */ 1667 ch->window_changes = window_changes;
2112 NULL, /* no err handlers */ 1668 ch->disconnects = disconnects;
2113 NULL); /* no handler cls */ 1669
2114 return mq; 1670 /* Create MQ for channel */
1671 ch->mq = GNUNET_MQ_queue_for_callbacks (&cadet_mq_send_impl,
1672 &cadet_mq_destroy_impl,
1673 &cadet_mq_cancel_impl,
1674 ch,
1675 handlers,
1676 &cadet_mq_error_handler,
1677 ch);
1678 GNUNET_MQ_set_handlers_closure (ch->mq, channel_cls);
1679
1680 /* Request channel creation to service */
1681 env = GNUNET_MQ_msg (msg,
1682 GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE);
1683 msg->ccn = ch->ccn;
1684 msg->port = *port;
1685 msg->peer = *destination;
1686 msg->opt = htonl (options);
1687 GNUNET_MQ_send (h->mq,
1688 env);
1689 return ch;
2115} 1690}
2116 1691
2117 1692
2118/** 1693/**
2119 * Transitional function to convert an unsigned int port to a hash value. 1694 * Obtain the message queue for a connected peer.
2120 * WARNING: local static value returned, NOT reentrant!
2121 * WARNING: do not use this function for new code!
2122 * 1695 *
2123 * @param port Numerical port (unsigned int format). 1696 * @param channel The channel handle from which to get the MQ.
2124 * 1697 *
2125 * @return A GNUNET_HashCode usable for the new CADET API. 1698 * @return NULL if @a channel is not yet connected.
2126 */ 1699 */
2127const struct GNUNET_HashCode * 1700struct GNUNET_MQ_Handle *
2128GC_u2h (uint32_t port) 1701GNUNET_CADET_get_mq (const struct GNUNET_CADET_Channel *channel)
2129{ 1702{
2130 static struct GNUNET_HashCode hash; 1703 return channel->mq;
2131
2132 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2133 "This is a transitional function, "
2134 "use proper crypto hashes as CADET ports\n");
2135 GNUNET_CRYPTO_hash (&port, sizeof (port), &hash);
2136
2137 return &hash;
2138} 1704}
1705
1706/* end of cadet_api.c */
diff --git a/src/cadet/cadet_common.c b/src/cadet/cadet_common.c
deleted file mode 100644
index 95a3144e4..000000000
--- a/src/cadet/cadet_common.c
+++ /dev/null
@@ -1,370 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2012 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 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 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file cadet/cadet_common.c
23 * @brief CADET helper functions
24 * @author Bartlomiej Polot
25 */
26
27#include "cadet.h"
28
29/**
30 * @brief Translate a fwd variable into a string representation, for logging.
31 *
32 * @param fwd Is FWD? (#GNUNET_YES or #GNUNET_NO)
33 *
34 * @return String representing FWD or BCK.
35 */
36char *
37GC_f2s (int fwd)
38{
39 if (GNUNET_YES == fwd)
40 {
41 return "FWD";
42 }
43 else if (GNUNET_NO == fwd)
44 {
45 return "BCK";
46 }
47 else
48 {
49 /* Not an error, can happen with CONNECTION_BROKEN messages. */
50 return "\???";
51 }
52}
53
54
55/**
56 * Test if @a bigger is larger than @a smaller.
57 * Considers the case that @a bigger just overflowed
58 * and is thus tiny while @a smaller is still below
59 * `UINT32_MAX`.
60 */
61int
62GC_is_pid_bigger (uint32_t bigger,
63 uint32_t smaller)
64{
65 return (PID_OVERFLOW (smaller, bigger) ||
66 ( (bigger > smaller) &&
67 (! PID_OVERFLOW (bigger, smaller))) );
68}
69
70
71uint32_t
72GC_max_pid (uint32_t a, uint32_t b)
73{
74 if (GC_is_pid_bigger(a, b))
75 return a;
76 return b;
77}
78
79
80uint32_t
81GC_min_pid (uint32_t a, uint32_t b)
82{
83 if (GC_is_pid_bigger(a, b))
84 return b;
85 return a;
86}
87
88
89/**
90 * Allocate a string with a hexdump of any binary data.
91 *
92 * @param bin Arbitrary binary data.
93 * @param len Length of @a bin in bytes.
94 * @param output Where to write the output (if *output be NULL it's allocated).
95 *
96 * @return The size of the output.
97 */
98size_t
99GC_bin2s (void *bin, unsigned int len, char **output)
100{
101 char *data = bin;
102 char *buf;
103 unsigned int s_len;
104 unsigned int i;
105
106 s_len = 2 * len + 1;
107 if (NULL == *output)
108 *output = GNUNET_malloc (s_len);
109 buf = *output;
110
111 for (i = 0; i < len; i++)
112 {
113 SPRINTF (&buf[2 * i], "%2X", data[i]);
114 }
115 buf[s_len - 1] = '\0';
116
117 return s_len;
118}
119
120
121#if !defined(GNUNET_CULL_LOGGING)
122const char *
123GC_m2s (uint16_t m)
124{
125 static char buf[2][16];
126 static int idx;
127 const char *s;
128
129 idx = (idx + 1) % 2;
130 switch (m)
131 {
132 /**
133 * Used to mark the "payload" of a non-payload message.
134 */
135 case 0:
136 s = "retransmit";
137 break;
138
139 /**
140 * Request the creation of a path
141 */
142 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE:
143 s = "CONN_CREAT";
144 break;
145
146 /**
147 * Request the modification of an existing path
148 */
149 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK:
150 s = "CONN_ACK";
151 break;
152
153 /**
154 * Notify that a connection of a path is no longer valid
155 */
156 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN:
157 s = "CONN_BRKN";
158 break;
159
160 /**
161 * At some point, the route will spontaneously change
162 */
163 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_PATH_CHANGED_UNIMPLEMENTED:
164 s = "PATH_CHNGD";
165 break;
166
167 /**
168 * Transport payload data.
169 */
170 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA:
171 s = "DATA";
172 break;
173
174 /**
175 * Confirm receipt of payload data.
176 */
177 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK:
178 s = "DATA_ACK";
179 break;
180
181 /**
182 * Key exchange message.
183 */
184 case GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX:
185 s = "KX";
186 break;
187
188 /**
189 * Encrypted.
190 */
191 case GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED:
192 s = "ENCRYPTED";
193 break;
194
195 /**
196 * Request the destuction of a path
197 */
198 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY:
199 s = "CONN_DSTRY";
200 break;
201
202 /**
203 * ACK for a data packet.
204 */
205 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_HOP_BY_HOP_ENCRYPTED_ACK:
206 s = "ACK";
207 break;
208
209 /**
210 * POLL for ACK.
211 */
212 case GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED_POLL:
213 s = "POLL";
214 break;
215
216 /**
217 * Announce origin is still alive.
218 */
219 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE:
220 s = "KEEPALIVE";
221 break;
222
223 /**
224 * Open port
225 */
226 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_OPEN:
227 s = "OPEN_PORT";
228 break;
229
230 /**
231 * Close port
232 */
233 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE:
234 s = "CLOSE_PORT";
235 break;
236
237 /**
238 * Ask the cadet service to create a new tunnel
239 */
240 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN:
241 s = "CHAN_CREAT";
242 break;
243
244 /**
245 * Ask the cadet service to destroy a tunnel
246 */
247 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY:
248 s = "CHAN_DSTRY";
249 break;
250
251 /**
252 * Confirm the creation of a channel.
253 */
254 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK:
255 s = "CHAN_ACK";
256 break;
257
258 /**
259 * Confirm the creation of a channel.
260 */
261 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_NACK_DEPRECATED:
262 s = "CHAN_NACK";
263 break;
264
265 /**
266 * Local payload traffic
267 */
268 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA:
269 s = "LOC_DATA";
270 break;
271
272 /**
273 * Local ACK for data.
274 */
275 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK:
276 s = "LOC_ACK";
277 break;
278
279 /**
280 * Local monitoring of channels.
281 */
282 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CHANNELS:
283 s = "INFO_CHANS";
284 break;
285
286 /**
287 * Local monitoring of a channel.
288 */
289 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CHANNEL:
290 s = "INFO_CHAN";
291 break;
292
293 /**
294 * Local monitoring of service.
295 */
296 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS:
297 s = "INFO_TUNS";
298 break;
299
300 /**
301 * Local monitoring of service.
302 */
303 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL:
304 s = "INFO_TUN";
305 break;
306
307 /**
308 * Local information about all connections of service.
309 */
310 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CONNECTIONS:
311 s = "INFO_CONNS";
312 break;
313
314 /**
315 * Local information of service about a specific connection.
316 */
317 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CONNECTION:
318 s = "INFO_CONN";
319 break;
320
321 /**
322 * Local information about all peers known to the service.
323 */
324 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS:
325 s = "INFO_PEERS";
326 break;
327
328 /**
329 * Local information of service about a specific peer.
330 */
331 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER:
332 s = "INFO_PEER";
333 break;
334
335 /**
336 * Traffic (net-cat style) used by the Command Line Interface.
337 */
338 case GNUNET_MESSAGE_TYPE_CADET_CLI:
339 s = "CLI";
340 break;
341
342 /**
343 * Debug request.
344 */
345 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_DUMP:
346 s = "INFO_DUMP";
347 break;
348
349 /**
350 * Used to mark the "payload" of a non-payload message.
351 */
352 case UINT16_MAX:
353 s = " N/A";
354 break;
355
356
357 default:
358 SPRINTF (buf[idx], "{UNK: %5u}", m);
359 return buf[idx];
360 }
361 SPRINTF (buf[idx], "{%10s}", s);
362 return buf[idx];
363}
364#else
365const char *
366GC_m2s (uint16_t m)
367{
368 return "";
369}
370#endif
diff --git a/src/cadet/cadet_path.c b/src/cadet/cadet_path.c
deleted file mode 100644
index 79a498805..000000000
--- a/src/cadet/cadet_path.c
+++ /dev/null
@@ -1,363 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2001 - 2013 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 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 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file cadet/cadet_path.c
23 * @brief Path handling functions
24 * @author Bartlomiej Polot
25 */
26
27#include "cadet.h"
28#include "cadet_path.h"
29#include "gnunet-service-cadet_peer.h"
30
31#define LOG(level, ...) GNUNET_log_from (level,"cadet-pth",__VA_ARGS__)
32
33
34/**
35 * @brief Destroy a path after some time has past.
36 * Removes the path from the peer (must not be used for direct paths).
37 *
38 * @param cls Closure (path to destroy).
39 */
40static void
41path_destroy_delayed (void *cls)
42{
43 struct CadetPeerPath *path = cls;
44 struct CadetPeer *peer;
45
46 path->path_delete = NULL;
47 LOG (GNUNET_ERROR_TYPE_DEBUG,
48 "Destroy delayed %p (%u)\n",
49 path,
50 path->length);
51 GNUNET_assert (2 < path->length);
52 peer = GCP_get_short (path->peers[path->length - 1],
53 GNUNET_NO);
54 GNUNET_assert (NULL != peer);
55 GCP_remove_path (peer, path);
56}
57
58
59/**
60 * Create a new path
61 *
62 * @param length How many hops will the path have.
63 * @return A newly allocated path with a peer array of the specified length.
64 */
65struct CadetPeerPath *
66path_new (unsigned int length)
67{
68 struct CadetPeerPath *p;
69
70 p = GNUNET_new (struct CadetPeerPath);
71 if (length > 0)
72 {
73 p->length = length;
74 p->peers = GNUNET_malloc (length * sizeof (GNUNET_PEER_Id));
75 }
76 LOG (GNUNET_ERROR_TYPE_DEBUG, "New path %p (%u)\n", p, p->length);
77 return p;
78}
79
80
81/**
82 * Invert the path
83 *
84 * @param path the path to invert
85 */
86void
87path_invert (struct CadetPeerPath *path)
88{
89 GNUNET_PEER_Id aux;
90 unsigned int i;
91
92 for (i = 0; i < path->length / 2; i++)
93 {
94 aux = path->peers[i];
95 path->peers[i] = path->peers[path->length - i - 1];
96 path->peers[path->length - i - 1] = aux;
97 }
98}
99
100
101/**
102 * Duplicate a path, incrementing short peer's rc.
103 *
104 * @param path The path to duplicate.
105 */
106struct CadetPeerPath *
107path_duplicate (const struct CadetPeerPath *path)
108{
109 struct CadetPeerPath *aux;
110 unsigned int i;
111
112 aux = path_new (path->length);
113 GNUNET_memcpy (aux->peers,
114 path->peers,
115 path->length * sizeof (GNUNET_PEER_Id));
116 for (i = 0; i < aux->length; i++)
117 GNUNET_PEER_change_rc (aux->peers[i], 1);
118 return aux;
119}
120
121
122/**
123 * Get the length of a path.
124 *
125 * @param path The path to measure, with the local peer at any point of it.
126 *
127 * @return Number of hops to reach destination.
128 * UINT_MAX in case the peer is not in the path.
129 */
130unsigned int
131path_get_length (struct CadetPeerPath *path)
132{
133 if (NULL == path)
134 return UINT_MAX;
135 return path->length;
136}
137
138
139
140/**
141 * Mark path as invalid: keep it aroud for a while to avoid trying it in a loop.
142 *
143 * Never invalidates a two-hop (direct) path, only a core handler can do that.
144 *
145 * Rationale: DHT_get sometimes returns bad cached results, for instance,
146 * on a locally cached result where the PUT followed a path that is no longer
147 * current. The path must remain "known and marked as invalid" for a while.
148 *
149 * @param p Path to invalidate.
150 */
151void
152path_invalidate (struct CadetPeerPath *p)
153{
154 if (NULL != p->path_delete)
155 return;
156
157 LOG (GNUNET_ERROR_TYPE_DEBUG,
158 "Invalidating path %p (%u)\n",
159 p,
160 p->length);
161 p->path_delete
162 = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
163 &path_destroy_delayed, p);
164}
165
166
167/**
168 * Builds a path from a PeerIdentity array.
169 *
170 * @param peers PeerIdentity array.
171 * @param size Size of the @c peers array.
172 * @param myid ID of local peer, to find @c own_pos.
173 * @param own_pos Output parameter: own position in the path.
174 *
175 * @return Fixed and shortened path.
176 */
177struct CadetPeerPath *
178path_build_from_peer_ids (struct GNUNET_PeerIdentity *peers,
179 unsigned int size,
180 GNUNET_PEER_Id myid,
181 unsigned int *own_pos)
182{
183 struct CadetPeerPath *path;
184 GNUNET_PEER_Id shortid;
185 unsigned int i;
186 unsigned int j;
187 unsigned int offset;
188
189 /* Create path */
190 LOG (GNUNET_ERROR_TYPE_DEBUG, " Creating path...\n");
191 path = path_new (size);
192 *own_pos = 0;
193 offset = 0;
194 for (i = 0; i < size; i++)
195 {
196 LOG (GNUNET_ERROR_TYPE_DEBUG, " - %u: taking %s\n",
197 i, GNUNET_i2s (&peers[i]));
198 shortid = GNUNET_PEER_intern (&peers[i]);
199
200 /* Check for loops / duplicates */
201 for (j = 0; j < i - offset; j++)
202 {
203 if (path->peers[j] == shortid)
204 {
205 LOG (GNUNET_ERROR_TYPE_DEBUG, " already exists at pos %u\n", j);
206 offset = i - j;
207 LOG (GNUNET_ERROR_TYPE_DEBUG, " offset now %u\n", offset);
208 GNUNET_PEER_change_rc (shortid, -1);
209 }
210 }
211 LOG (GNUNET_ERROR_TYPE_DEBUG, " storing at %u\n", i - offset);
212 path->peers[i - offset] = shortid;
213 if (path->peers[i - offset] == myid)
214 *own_pos = i - offset;
215 }
216 path->length -= offset;
217
218 if (path->peers[*own_pos] != myid)
219 {
220 /* create path: self not found in path through self */
221 GNUNET_break_op (0);
222 path_destroy (path);
223 return NULL;
224 }
225
226 return path;
227}
228
229
230/**
231 * Test if two paths are equivalent (equal or revese of each other).
232 *
233 * @param p1 First path
234 * @param p2 Second path
235 *
236 * @return #GNUNET_YES if both paths are equivalent
237 * #GNUNET_NO otherwise
238 */
239int
240path_equivalent (const struct CadetPeerPath *p1,
241 const struct CadetPeerPath *p2)
242{
243 unsigned int i;
244 unsigned int l;
245 unsigned int half;
246
247 if (NULL == p1 || NULL == p2)
248 return GNUNET_NO;
249
250 if (p1->length != p2->length)
251 return GNUNET_NO;
252
253 l = p1->length;
254 if (0 == memcmp (p1->peers, p2->peers, sizeof (p1->peers[0]) * l))
255 return GNUNET_YES;
256
257 half = l / 2;
258 l = l - 1;
259 for (i = 0; i <= half; i++)
260 if (p1->peers[i] != p2->peers[l - i])
261 return GNUNET_NO;
262
263 return GNUNET_YES;
264}
265
266
267/**
268 * Test if a path is valid (or at least not known to be invalid).
269 *
270 * @param path Path to test.
271 *
272 * @return #GNUNET_YES If the path is valid or unknown,
273 * #GNUNET_NO If the path is known to be invalid.
274 */
275int
276path_is_valid (const struct CadetPeerPath *path)
277{
278 return (NULL == path->path_delete);
279}
280
281
282/**
283 * Destroy the path and free any allocated resources linked to it
284 *
285 * @param p the path to destroy
286 *
287 * @return #GNUNET_OK on success
288 */
289int
290path_destroy (struct CadetPeerPath *p)
291{
292 if (NULL == p)
293 return GNUNET_OK;
294
295 LOG (GNUNET_ERROR_TYPE_DEBUG,
296 "destroying path %p (%u)\n",
297 p,
298 p->length);
299 GNUNET_PEER_decrement_rcs (p->peers, p->length);
300 GNUNET_free_non_null (p->peers);
301 if (NULL != p->path_delete)
302 GNUNET_SCHEDULER_cancel (p->path_delete);
303 GNUNET_free (p);
304 return GNUNET_OK;
305}
306
307
308/**
309 * Compare two paths.
310 *
311 * @param p1 First path.
312 * @param p2 Second path.
313 *
314 * @return > 0 if p1 is longer, or the first differing PEER_Id is higher on p1.
315 * < 0 if p2 is longer, or the first differing PEER_Id is higher on p2.
316 * 0 if they are identical.
317 */
318int
319path_cmp (const struct CadetPeerPath *p1,
320 const struct CadetPeerPath *p2)
321{
322 if (p1->length > p2->length)
323 return 1;
324
325 if (p1->length < p2->length)
326 return -1;
327
328 return memcmp (p1->peers,
329 p2->peers,
330 sizeof (GNUNET_PEER_Id) * p1->length);
331}
332
333
334char *
335path_2s (struct CadetPeerPath *p)
336{
337 char *s;
338 char *old;
339 unsigned int i;
340
341 old = GNUNET_strdup ("");
342 for (i = 0; i < p->length; i++)
343 {
344 GNUNET_asprintf (&s, "%s %s",
345 old, GNUNET_i2s (GNUNET_PEER_resolve2 (p->peers[i])));
346 GNUNET_free_non_null (old);
347 old = s;
348 }
349 return old;
350}
351
352
353void
354path_debug (struct CadetPeerPath *p)
355{
356 unsigned int i;
357
358 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "PATH:\n");
359 for (i = 0; i < p->length; i++)
360 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " %s\n",
361 GNUNET_i2s (GNUNET_PEER_resolve2 (p->peers[i])));
362 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "END\n");
363}
diff --git a/src/cadet/cadet_path.h b/src/cadet/cadet_path.h
deleted file mode 100644
index bb68eec42..000000000
--- a/src/cadet/cadet_path.h
+++ /dev/null
@@ -1,226 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2001 - 2013 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 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 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file cadet/cadet_path.h
23 * @brief Path handling functions
24 * @author Bartlomiej Polot
25 */
26
27#ifndef CADET_PATH_H_
28#define CADET_PATH_H_
29
30#ifdef __cplusplus
31extern "C"
32{
33 #if 0 /* keep Emacsens' auto-indent happy */
34}
35#endif
36#endif
37
38
39/******************************************************************************/
40/************************ DATA STRUCTURES ****************************/
41/******************************************************************************/
42
43/**
44 * Information regarding a possible path to reach a single peer
45 */
46struct CadetPeerPath
47{
48
49 /**
50 * Linked list
51 */
52 struct CadetPeerPath *next;
53 struct CadetPeerPath *prev;
54
55 /**
56 * List of all the peers that form the path from origin to target.
57 */
58 GNUNET_PEER_Id *peers;
59
60 /**
61 * Number of peers (hops) in the path
62 */
63 unsigned int length;
64
65 /**
66 * User defined data store.
67 */
68 struct CadetConnection *c;
69
70 /**
71 * Path's score, how reliable is the path.
72 */
73// int score;
74
75 /**
76 * Task to delete the path.
77 * We tried it, it didn't work, don't try again in a while.
78 */
79 struct GNUNET_SCHEDULER_Task * path_delete;
80
81};
82
83/******************************************************************************/
84/************************* FUNCTIONS *****************************/
85/******************************************************************************/
86
87/**
88 * Create a new path.
89 *
90 * @param length How many hops will the path have.
91 *
92 * @return A newly allocated path with a peer array of the specified length.
93 */
94struct CadetPeerPath *
95path_new (unsigned int length);
96
97
98/**
99 * Invert the path.
100 *
101 * @param path The path to invert.
102 */
103void
104path_invert (struct CadetPeerPath *path);
105
106
107/**
108 * Duplicate a path, incrementing short peer's rc.
109 *
110 * @param path The path to duplicate.
111 */
112struct CadetPeerPath *
113path_duplicate (const struct CadetPeerPath *path);
114
115
116/**
117 * Get the length of a path.
118 *
119 * @param path The path to measure, with the local peer at any point of it.
120 *
121 * @return Number of hops to reach destination.
122 * UINT_MAX in case the peer is not in the path.
123 */
124unsigned int
125path_get_length (struct CadetPeerPath *path);
126
127/**
128 * Mark path as invalid: keep it aroud for a while to avoid trying it in a loop.
129 *
130 * DHT_get sometimes returns bad cached results, for instance, on a locally
131 * cached result where the PUT followed a path that is no longer current.
132 *
133 * @param p Path to invalidate.
134 */
135void
136path_invalidate (struct CadetPeerPath *p);
137
138/**
139 * Test if two paths are equivalent (equal or revese of each other).
140 *
141 * @param p1 First path
142 * @param p2 Second path
143 *
144 * @return GNUNET_YES if both paths are equivalent
145 * GNUNET_NO otherwise
146 */
147int
148path_equivalent (const struct CadetPeerPath *p1,
149 const struct CadetPeerPath *p2);
150
151/**
152 * Test if a path is valid (or at least not known to be invalid).
153 *
154 * @param path Path to test.
155 *
156 * @return #GNUNET_YES If the path is valid or unknown,
157 * #GNUNET_NO If the path is known to be invalid.
158 */
159int
160path_is_valid (const struct CadetPeerPath *path);
161
162/**
163 * Destroy the path and free any allocated resources linked to it
164 *
165 * @param p the path to destroy
166 *
167 * @return GNUNET_OK on success
168 */
169int
170path_destroy (struct CadetPeerPath *p);
171
172/**
173 * Compare two paths.
174 *
175 * @param p1 First path.
176 * @param p2 Second path.
177 *
178 * @return > 0 if p1 is longer, or the first differing PEER_Id is higher on p1.
179 * < 0 if p2 is longer, or the first differing PEER_Id is higher on p2.
180 * 0 if they are identical.
181 */
182int
183path_cmp (const struct CadetPeerPath *p1, const struct CadetPeerPath *p2);
184
185/**
186 * Builds a path from a PeerIdentity array.
187 *
188 * @param peers PeerIdentity array.
189 * @param size Size of the @c peers array.
190 * @param myid ID of local peer, to find @c own_pos.
191 * @param own_pos Output parameter: own position in the path.
192 *
193 * @return Fixed and shortened path.
194 */
195struct CadetPeerPath *
196path_build_from_peer_ids (struct GNUNET_PeerIdentity *peers,
197 unsigned int size,
198 GNUNET_PEER_Id myid,
199 unsigned int *own_pos);
200
201/**
202 * Path -> allocated one line string. Caller must free.
203 *
204 * @param p Path.
205 */
206char *
207path_2s (struct CadetPeerPath *p);
208
209/**
210 * Print info about the path for debug.
211 *
212 * @param p Path to debug.
213 */
214void
215path_debug (struct CadetPeerPath *p);
216
217#if 0 /* keep Emacsens' auto-indent happy */
218{
219 #endif
220 #ifdef __cplusplus
221}
222#endif
223
224
225/* ifndef CADET_PATH_H */
226#endif
diff --git a/src/cadet/cadet_protocol.h b/src/cadet/cadet_protocol.h
index 5ec34f7d7..de0cec5d0 100644
--- a/src/cadet/cadet_protocol.h
+++ b/src/cadet/cadet_protocol.h
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2001 - 2011 GNUnet e.V. 3 Copyright (C) 2007 - 2017 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -19,8 +19,10 @@
19*/ 19*/
20 20
21/** 21/**
22 * @author Bartlomiej Polot
23 * @file cadet/cadet_protocol.h 22 * @file cadet/cadet_protocol.h
23 * @brief P2P messages used by CADET
24 * @author Bartlomiej Polot
25 * @author Christian Grothoff
24 */ 26 */
25 27
26#ifndef CADET_PROTOCOL_H_ 28#ifndef CADET_PROTOCOL_H_
@@ -67,9 +69,12 @@ struct GNUNET_CADET_ConnectionCreateMessage
67 struct GNUNET_MessageHeader header; 69 struct GNUNET_MessageHeader header;
68 70
69 /** 71 /**
70 * For alignment. 72 * Connection options in network byte order.
73 * #GNUNET_CADET_OPTION_DEFAULT for buffered;
74 * #GNUNET_CADET_OPTION_NOBUFFER for unbuffered.
75 * Other flags are ignored and should not be set at this level.
71 */ 76 */
72 uint32_t reserved GNUNET_PACKED; 77 uint32_t options GNUNET_PACKED;
73 78
74 /** 79 /**
75 * ID of the connection 80 * ID of the connection
@@ -205,7 +210,9 @@ enum GNUNET_CADET_KX_Flags {
205struct GNUNET_CADET_TunnelKeyExchangeMessage 210struct GNUNET_CADET_TunnelKeyExchangeMessage
206{ 211{
207 /** 212 /**
208 * Type: #GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX. 213 * Type: #GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX or
214 * #GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX_AUTH as part
215 * of `struct GNUNET_CADET_TunnelKeyExchangeAuthMessage`.
209 */ 216 */
210 struct GNUNET_MessageHeader header; 217 struct GNUNET_MessageHeader header;
211 218
@@ -234,50 +241,36 @@ struct GNUNET_CADET_TunnelKeyExchangeMessage
234 */ 241 */
235 struct GNUNET_CRYPTO_EcdhePublicKey ratchet_key; 242 struct GNUNET_CRYPTO_EcdhePublicKey ratchet_key;
236 243
237#ifdef NEW_CADET
238 /**
239 * Proof that sender could compute the 3-DH, in lieu of a signature.
240 */
241 struct GNUNET_HashCode triple_dh_proof;
242#endif
243}; 244};
244 245
245 246
246/** 247/**
247 * Axolotl tunnel message. 248 * Message for a Key eXchange for a tunnel, with authentication.
249 * Used as a response to the initial KX as well as for rekeying.
248 */ 250 */
249struct GNUNET_CADET_TunnelEncryptedMessage 251struct GNUNET_CADET_TunnelKeyExchangeAuthMessage
250{ 252{
251 /**
252 * Type: #GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED
253 */
254 struct GNUNET_MessageHeader header;
255 253
256#if NEW_CADET
257 /** 254 /**
258 * Reserved, for alignment. 255 * Message header with key material.
259 */ 256 */
260 uint32_t reserved GNUNET_PACKED; 257 struct GNUNET_CADET_TunnelKeyExchangeMessage kx;
261#else
262 /**
263 * Maximum packet ID authorized.
264 */
265 struct CadetEncryptedMessageIdentifier cemi;
266#endif
267 258
268 /** 259 /**
269 * ID of the connection. 260 * KDF-proof that sender could compute the 3-DH, used in lieu of a
261 * signature or payload data.
270 */ 262 */
271 struct GNUNET_CADET_ConnectionTunnelIdentifier cid; 263 struct GNUNET_HashCode auth;
264
265};
272 266
273 /**
274 * MAC of the encrypted message, used to verify message integrity.
275 * Everything after this value will be encrypted with the header key
276 * and authenticated.
277 */
278 struct GNUNET_ShortHashCode hmac;
279 267
280 /**************** AX_HEADER start ****************/ 268/**
269 * Encrypted axolotl header with numbers that identify which
270 * keys in which ratchet are to be used to decrypt the body.
271 */
272struct GNUNET_CADET_AxHeader
273{
281 274
282 /** 275 /**
283 * Number of messages sent with the current ratchet key. 276 * Number of messages sent with the current ratchet key.
@@ -294,68 +287,47 @@ struct GNUNET_CADET_TunnelEncryptedMessage
294 */ 287 */
295 struct GNUNET_CRYPTO_EcdhePublicKey DHRs; 288 struct GNUNET_CRYPTO_EcdhePublicKey DHRs;
296 289
297 /**************** AX_HEADER end ****************/
298
299 /**
300 * Encrypted content follows.
301 */
302}; 290};
303 291
304 292
305#ifndef NEW_CADET
306
307/** 293/**
308 * Message to query a peer about its Flow Control status regarding a tunnel. 294 * Axolotl-encrypted tunnel message with application payload.
309 *
310 * It is NOT yet clear if we need this.
311 */ 295 */
312struct GNUNET_CADET_ConnectionHopByHopPollMessage 296struct GNUNET_CADET_TunnelEncryptedMessage
313{ 297{
314 /** 298 /**
315 * Type: #GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED_POLL 299 * Type: #GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED
316 */ 300 */
317 struct GNUNET_MessageHeader header; 301 struct GNUNET_MessageHeader header;
318 302
319 /** 303 /**
320 * Last packet sent. 304 * Reserved, for alignment.
321 */ 305 */
322 struct CadetEncryptedMessageIdentifier cemi; 306 uint32_t reserved GNUNET_PACKED;
323 307
324 /** 308 /**
325 * ID of the connection. 309 * ID of the connection.
326 */ 310 */
327 struct GNUNET_CADET_ConnectionTunnelIdentifier cid; 311 struct GNUNET_CADET_ConnectionTunnelIdentifier cid;
328 312
329};
330
331
332/**
333 * Message to acknowledge cadet encrypted traffic, used for
334 * flow-control on a hop-by-hop basis on the connection-level. Note
335 * that we do use the @e cemi from the tunnel layer as the connection
336 * layer's header is included/shared with the tunnel layer messages,
337 * and we only do flow control for the payload.
338 */
339struct GNUNET_CADET_ConnectionEncryptedAckMessage
340{
341 /** 313 /**
342 * Type: #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_HOP_BY_HOP_ENCRYPTED_ACK 314 * MAC of the encrypted message, used to verify message integrity.
315 * Everything after this value will be encrypted with the header key
316 * and authenticated.
343 */ 317 */
344 struct GNUNET_MessageHeader header; 318 struct GNUNET_ShortHashCode hmac;
345 319
346 /** 320 /**
347 * Maximum packet ID authorized. 321 * Axolotl-header that specifies which keys to use in which ratchet
322 * to decrypt the body that follows.
348 */ 323 */
349 struct CadetEncryptedMessageIdentifier cemi_max; 324 struct GNUNET_CADET_AxHeader ax_header;
350 325
351 /** 326 /**
352 * ID of the connection. 327 * Encrypted content follows.
353 */ 328 */
354 struct GNUNET_CADET_ConnectionTunnelIdentifier cid;
355}; 329};
356 330
357#endif
358
359 331
360/******************************************************************************/ 332/******************************************************************************/
361/******************************* CHANNEL ***********************************/ 333/******************************* CHANNEL ***********************************/
@@ -378,9 +350,9 @@ struct GNUNET_CADET_ChannelOpenMessage
378 uint32_t opt GNUNET_PACKED; 350 uint32_t opt GNUNET_PACKED;
379 351
380 /** 352 /**
381 * Destination port. 353 * Hash of destination port and listener.
382 */ 354 */
383 struct GNUNET_HashCode port; 355 struct GNUNET_HashCode h_port;
384 356
385 /** 357 /**
386 * ID of the channel within the tunnel. 358 * ID of the channel within the tunnel.
@@ -390,93 +362,56 @@ struct GNUNET_CADET_ChannelOpenMessage
390 362
391 363
392/** 364/**
393 * Message to manage a Channel 365 * Message to acknowledge opening a channel of type
394 * (#GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK, 366 * #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK.
395 * #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY).
396 */ 367 */
397struct GNUNET_CADET_ChannelManageMessage 368struct GNUNET_CADET_ChannelOpenAckMessage
398{ 369{
399 /** 370 /**
400 * Type: #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK or 371 * Type: #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK
401 * #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY
402 */ 372 */
403 struct GNUNET_MessageHeader header; 373 struct GNUNET_MessageHeader header;
404 374
405#ifdef NEW_CADET
406 /** 375 /**
407 * For alignment. 376 * For alignment.
408 */ 377 */
409 uint32_t reserved GNUNET_PACKED; 378 uint32_t reserved GNUNET_PACKED;
410#endif
411 379
412 /** 380 /**
413 * ID of the channel 381 * ID of the channel
414 */ 382 */
415 struct GNUNET_CADET_ChannelTunnelNumber ctn; 383 struct GNUNET_CADET_ChannelTunnelNumber ctn;
416};
417
418
419#ifndef NEW_CADET
420
421/**
422 * Message for cadet data traffic.
423 */
424struct GNUNET_CADET_ChannelAppDataMessage
425{
426 /**
427 * Type: #GNUNET_MESSAGE_TYPE_CADET_UNICAST,
428 * #GNUNET_MESSAGE_TYPE_CADET_TO_ORIGIN
429 */
430 struct GNUNET_MessageHeader header;
431
432 /**
433 * Unique ID of the payload message
434 */
435 /* NEW: struct ChannelMessageIdentifier */
436 uint32_t mid GNUNET_PACKED;
437 384
438 /** 385 /**
439 * ID of the channel 386 * Port number of the channel, used to prove to the
440 */ 387 * initiator that the receiver knows the port.
441 struct GNUNET_CADET_ChannelTunnelNumber ctn;
442
443 /**
444 * Payload follows
445 */ 388 */
389 struct GNUNET_HashCode port;
446}; 390};
447 391
448 392
449/** 393/**
450 * Message to acknowledge end-to-end data. 394 * Message to destroy a channel of type
395 * #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY.
451 */ 396 */
452struct GNUNET_CADET_ChannelDataAckMessage 397struct GNUNET_CADET_ChannelDestroyMessage
453{ 398{
454 /** 399 /**
455 * Type: #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK 400 * Type: #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY
456 */ 401 */
457 struct GNUNET_MessageHeader header; 402 struct GNUNET_MessageHeader header;
458 403
459 /** 404 /**
460 * ID of the channel 405 * For alignment.
461 */
462 struct GNUNET_CADET_ChannelTunnelNumber ctn;
463
464 /**
465 * Bitfield of already-received newer messages
466 * pid + 1 @ LSB
467 * pid + 64 @ MSB
468 */ 406 */
469 uint64_t futures GNUNET_PACKED; 407 uint32_t reserved GNUNET_PACKED;
470 408
471 /** 409 /**
472 * Last message ID received. 410 * ID of the channel
473 */ 411 */
474 /* NEW: struct ChannelMessageIdentifier */ 412 struct GNUNET_CADET_ChannelTunnelNumber ctn;
475 uint32_t mid GNUNET_PACKED;
476}; 413};
477 414
478#else
479
480 415
481/** 416/**
482 * Number used to uniquely identify messages in a CADET Channel. 417 * Number used to uniquely identify messages in a CADET Channel.
@@ -532,21 +467,21 @@ struct GNUNET_CADET_ChannelDataAckMessage
532 struct GNUNET_CADET_ChannelTunnelNumber ctn; 467 struct GNUNET_CADET_ChannelTunnelNumber ctn;
533 468
534 /** 469 /**
535 * Bitfield of already-received messages past @e mid. 470 * Bitfield of already-received newer messages. Note that bit 0
536 * pid + 1 @ LSB 471 * corresponds to @e mid + 1.
537 * pid + 64 @ MSB 472 *
473 * pid + 0 @ LSB
474 * pid + 63 @ MSB
538 */ 475 */
539 uint64_t futures GNUNET_PACKED; 476 uint64_t futures GNUNET_PACKED;
540 477
541 /** 478 /**
542 * Last message ID received. 479 * Next message ID expected.
543 */ 480 */
544 struct ChannelMessageIdentifier mid; 481 struct ChannelMessageIdentifier mid;
545}; 482};
546 483
547 484
548#endif
549
550GNUNET_NETWORK_STRUCT_END 485GNUNET_NETWORK_STRUCT_END
551 486
552#if 0 /* keep Emacsens' auto-indent happy */ 487#if 0 /* keep Emacsens' auto-indent happy */
diff --git a/src/cadet/cadet_test_lib.c b/src/cadet/cadet_test_lib.c
index 9a70dad49..1df6bff0d 100644
--- a/src/cadet/cadet_test_lib.c
+++ b/src/cadet/cadet_test_lib.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2012 GNUnet e.V. 3 Copyright (C) 2012, 2017 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -27,6 +27,7 @@
27#include "cadet_test_lib.h" 27#include "cadet_test_lib.h"
28#include "gnunet_cadet_service.h" 28#include "gnunet_cadet_service.h"
29 29
30
30/** 31/**
31 * Test context for a CADET Test. 32 * Test context for a CADET Test.
32 */ 33 */
@@ -40,7 +41,7 @@ struct GNUNET_CADET_TEST_Context
40 /** 41 /**
41 * Array of handles to the CADET for each peer. 42 * Array of handles to the CADET for each peer.
42 */ 43 */
43 struct GNUNET_CADET_Handle **cadetes; 44 struct GNUNET_CADET_Handle **cadets;
44 45
45 /** 46 /**
46 * Operation associated with the connection to the CADET. 47 * Operation associated with the connection to the CADET.
@@ -48,6 +49,11 @@ struct GNUNET_CADET_TEST_Context
48 struct GNUNET_TESTBED_Operation **ops; 49 struct GNUNET_TESTBED_Operation **ops;
49 50
50 /** 51 /**
52 * Number of peers running, size of the arrays above.
53 */
54 unsigned int num_peers;
55
56 /**
51 * Main function of the test to run once all CADETs are available. 57 * Main function of the test to run once all CADETs are available.
52 */ 58 */
53 GNUNET_CADET_TEST_AppMain app_main; 59 GNUNET_CADET_TEST_AppMain app_main;
@@ -58,30 +64,35 @@ struct GNUNET_CADET_TEST_Context
58 void *app_main_cls; 64 void *app_main_cls;
59 65
60 /** 66 /**
61 * Number of peers running, size of the arrays above. 67 * Handler for incoming tunnels.
62 */ 68 */
63 unsigned int num_peers; 69 GNUNET_CADET_ConnectEventHandler connects;
64 70
65 /** 71 /**
66 * Handler for incoming tunnels. 72 * Function called when the transmit window size changes.
67 */ 73 */
68 GNUNET_CADET_InboundChannelNotificationHandler *new_channel; 74 GNUNET_CADET_WindowSizeEventHandler window_changes;
69 75
70 /** 76 /**
71 * Cleaner for destroyed incoming tunnels. 77 * Cleaner for destroyed incoming tunnels.
72 */ 78 */
73 GNUNET_CADET_ChannelEndHandler *cleaner; 79 GNUNET_CADET_DisconnectEventHandler disconnects;
74 80
75 /** 81 /**
76 * Message handlers. 82 * Message handlers.
77 */ 83 */
78 struct GNUNET_CADET_MessageHandler* handlers; 84 struct GNUNET_MQ_MessageHandler *handlers;
79 85
80 /** 86 /**
81 * Application ports. 87 * Application ports.
82 */ 88 */
83 const struct GNUNET_HashCode **ports; 89 const struct GNUNET_HashCode **ports;
84 90
91 /**
92 * Number of ports in #ports.
93 */
94 unsigned int port_count;
95
85}; 96};
86 97
87 98
@@ -94,6 +105,11 @@ struct GNUNET_CADET_TEST_AdapterContext
94 * Peer number for the particular peer. 105 * Peer number for the particular peer.
95 */ 106 */
96 unsigned int peer; 107 unsigned int peer;
108
109 /**
110 * Port handlers for open ports.
111 */
112 struct GNUNET_CADET_Port **ports;
97 113
98 /** 114 /**
99 * General context. 115 * General context.
@@ -114,26 +130,28 @@ struct GNUNET_CADET_TEST_AdapterContext
114 */ 130 */
115static void * 131static void *
116cadet_connect_adapter (void *cls, 132cadet_connect_adapter (void *cls,
117 const struct GNUNET_CONFIGURATION_Handle *cfg) 133 const struct GNUNET_CONFIGURATION_Handle *cfg)
118{ 134{
119 struct GNUNET_CADET_TEST_AdapterContext *actx = cls; 135 struct GNUNET_CADET_TEST_AdapterContext *actx = cls;
120 struct GNUNET_CADET_TEST_Context *ctx = actx->ctx; 136 struct GNUNET_CADET_TEST_Context *ctx = actx->ctx;
121 struct GNUNET_CADET_Handle *h; 137 struct GNUNET_CADET_Handle *h;
138 unsigned int i;
122 139
123 h = GNUNET_CADET_connect (cfg, 140 h = GNUNET_CADET_connect (cfg);
124 (void *) (long) actx->peer,
125 ctx->cleaner,
126 ctx->handlers);
127 if (NULL == ctx->ports) 141 if (NULL == ctx->ports)
128 return h; 142 return h;
129 143
130 for (int i = 0; NULL != ctx->ports[i]; i++) 144 actx->ports = GNUNET_new_array (ctx->port_count, struct GNUNET_CADET_Port *);
145 for (i = 0; i < ctx->port_count; i++)
131 { 146 {
132 (void ) GNUNET_CADET_open_port (h, ctx->ports[i], 147 actx->ports[i] = GNUNET_CADET_open_port (h,
133 ctx->new_channel, 148 ctx->ports[i],
134 (void *) (long) actx->peer); 149 ctx->connects,
150 (void *) (long) actx->peer,
151 ctx->window_changes,
152 ctx->disconnects,
153 ctx->handlers);
135 } 154 }
136
137 return h; 155 return h;
138} 156}
139 157
@@ -152,6 +170,15 @@ cadet_disconnect_adapter (void *cls,
152 struct GNUNET_CADET_Handle *cadet = op_result; 170 struct GNUNET_CADET_Handle *cadet = op_result;
153 struct GNUNET_CADET_TEST_AdapterContext *actx = cls; 171 struct GNUNET_CADET_TEST_AdapterContext *actx = cls;
154 172
173 if (NULL != actx->ports)
174 {
175 for (int i = 0; i < actx->ctx->port_count; i++)
176 {
177 GNUNET_CADET_close_port (actx->ports[i]);
178 actx->ports[i] = NULL;
179 }
180 GNUNET_free (actx->ports);
181 }
155 GNUNET_free (actx); 182 GNUNET_free (actx);
156 GNUNET_CADET_disconnect (cadet); 183 GNUNET_CADET_disconnect (cadet);
157} 184}
@@ -186,18 +213,18 @@ cadet_connect_cb (void *cls,
186 for (i = 0; i < ctx->num_peers; i++) 213 for (i = 0; i < ctx->num_peers; i++)
187 if (op == ctx->ops[i]) 214 if (op == ctx->ops[i])
188 { 215 {
189 ctx->cadetes[i] = ca_result; 216 ctx->cadets[i] = ca_result;
190 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "...cadet %u connected\n", i); 217 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "...cadet %u connected\n", i);
191 } 218 }
192 for (i = 0; i < ctx->num_peers; i++) 219 for (i = 0; i < ctx->num_peers; i++)
193 if (NULL == ctx->cadetes[i]) 220 if (NULL == ctx->cadets[i])
194 return; /* still some CADET connections missing */ 221 return; /* still some CADET connections missing */
195 /* all CADET connections ready! */ 222 /* all CADET connections ready! */
196 ctx->app_main (ctx->app_main_cls, 223 ctx->app_main (ctx->app_main_cls,
197 ctx, 224 ctx,
198 ctx->num_peers, 225 ctx->num_peers,
199 ctx->peers, 226 ctx->peers,
200 ctx->cadetes); 227 ctx->cadets);
201} 228}
202 229
203 230
@@ -213,7 +240,7 @@ GNUNET_CADET_TEST_cleanup (struct GNUNET_CADET_TEST_Context *ctx)
213 ctx->ops[i] = NULL; 240 ctx->ops[i] = NULL;
214 } 241 }
215 GNUNET_free (ctx->ops); 242 GNUNET_free (ctx->ops);
216 GNUNET_free (ctx->cadetes); 243 GNUNET_free (ctx->cadets);
217 GNUNET_free (ctx); 244 GNUNET_free (ctx);
218 GNUNET_SCHEDULER_shutdown (); 245 GNUNET_SCHEDULER_shutdown ();
219} 246}
@@ -243,12 +270,23 @@ cadet_test_run (void *cls,
243 struct GNUNET_CADET_TEST_Context *ctx = cls; 270 struct GNUNET_CADET_TEST_Context *ctx = cls;
244 unsigned int i; 271 unsigned int i;
245 272
273 if (0 != links_failed)
274 {
275 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Some links failed (%u), ending\n",
276 links_failed);
277 exit (2);
278 }
279
246 if (num_peers != ctx->num_peers) 280 if (num_peers != ctx->num_peers)
247 { 281 {
248 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Peers started %u/%u, ending\n", 282 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Peers started %u/%u, ending\n",
249 num_peers, ctx->num_peers); 283 num_peers, ctx->num_peers);
250 exit (1); 284 exit (1);
251 } 285 }
286
287 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
288 "Testbed up, %u peers and %u links\n",
289 num_peers, links_succeeded);
252 ctx->peers = peers; 290 ctx->peers = peers;
253 for (i = 0; i < num_peers; i++) 291 for (i = 0; i < num_peers; i++)
254 { 292 {
@@ -270,31 +308,52 @@ cadet_test_run (void *cls,
270} 308}
271 309
272 310
311/**
312 * Run a test using the given name, configuration file and number of peers.
313 * All cadet callbacks will receive the peer number (long) as the closure.
314 *
315 * @param testname Name of the test (for logging).
316 * @param cfgfile Name of the configuration file.
317 * @param num_peers Number of peers to start.
318 * @param tmain Main function to run once the testbed is ready.
319 * @param tmain_cls Closure for @a tmain.
320 * @param connects Handler for incoming channels.
321 * @param window_changes Handler for the window size change notification.
322 * @param disconnects Cleaner for destroyed incoming channels.
323 * @param handlers Message handlers.
324 * @param ports Ports the peers offer, NULL-terminated.
325 */
273void 326void
274GNUNET_CADET_TEST_run (const char *testname, 327GNUNET_CADET_TEST_ruN (const char *testname,
275 const char *cfgname, 328 const char *cfgfile,
276 unsigned int num_peers, 329 unsigned int num_peers,
277 GNUNET_CADET_TEST_AppMain tmain, 330 GNUNET_CADET_TEST_AppMain tmain,
278 void *tmain_cls, 331 void *tmain_cls,
279 GNUNET_CADET_InboundChannelNotificationHandler new_channel, 332 GNUNET_CADET_ConnectEventHandler connects,
280 GNUNET_CADET_ChannelEndHandler cleaner, 333 GNUNET_CADET_WindowSizeEventHandler window_changes,
281 struct GNUNET_CADET_MessageHandler* handlers, 334 GNUNET_CADET_DisconnectEventHandler disconnects,
282 const struct GNUNET_HashCode **ports) 335 struct GNUNET_MQ_MessageHandler *handlers,
336 const struct GNUNET_HashCode **ports)
283{ 337{
284 struct GNUNET_CADET_TEST_Context *ctx; 338 struct GNUNET_CADET_TEST_Context *ctx;
285 339
286 ctx = GNUNET_new (struct GNUNET_CADET_TEST_Context); 340 ctx = GNUNET_new (struct GNUNET_CADET_TEST_Context);
287 ctx->num_peers = num_peers; 341 ctx->num_peers = num_peers;
288 ctx->ops = GNUNET_malloc (num_peers * sizeof (struct GNUNET_TESTBED_Operation *)); 342 ctx->ops = GNUNET_new_array (num_peers, struct GNUNET_TESTBED_Operation *);
289 ctx->cadetes = GNUNET_malloc (num_peers * sizeof (struct GNUNET_CADET_Handle *)); 343 ctx->cadets = GNUNET_new_array (num_peers, struct GNUNET_CADET_Handle *);
290 ctx->app_main = tmain; 344 ctx->app_main = tmain;
291 ctx->app_main_cls = tmain_cls; 345 ctx->app_main_cls = tmain_cls;
292 ctx->new_channel = new_channel; 346 ctx->connects = connects;
293 ctx->cleaner = cleaner; 347 ctx->window_changes = window_changes;
294 ctx->handlers = handlers; 348 ctx->disconnects = disconnects;
349 ctx->handlers = GNUNET_MQ_copy_handlers (handlers);
295 ctx->ports = ports; 350 ctx->ports = ports;
351 ctx->port_count = 0;
352 while (NULL != ctx->ports[ctx->port_count])
353 ctx->port_count++;
354
296 GNUNET_TESTBED_test_run (testname, 355 GNUNET_TESTBED_test_run (testname,
297 cfgname, 356 cfgfile,
298 num_peers, 357 num_peers,
299 0LL, NULL, NULL, 358 0LL, NULL, NULL,
300 &cadet_test_run, ctx); 359 &cadet_test_run, ctx);
diff --git a/src/cadet/cadet_test_lib.h b/src/cadet/cadet_test_lib.h
index 464977d42..4b3a6b18d 100644
--- a/src/cadet/cadet_test_lib.h
+++ b/src/cadet/cadet_test_lib.h
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2012 GNUnet e.V. 3 Copyright (C) 2012,2017 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -49,41 +49,41 @@ struct GNUNET_CADET_TEST_Context;
49 * @param ctx Argument to give to GNUNET_CADET_TEST_cleanup on test end. 49 * @param ctx Argument to give to GNUNET_CADET_TEST_cleanup on test end.
50 * @param num_peers Number of peers that are running. 50 * @param num_peers Number of peers that are running.
51 * @param peers Array of peers. 51 * @param peers Array of peers.
52 * @param cadetes Handle to each of the CADETs of the peers. 52 * @param cadets Handle to each of the CADETs of the peers.
53 */ 53 */
54typedef void (*GNUNET_CADET_TEST_AppMain) (void *cls, 54typedef void (*GNUNET_CADET_TEST_AppMain) (void *cls,
55 struct GNUNET_CADET_TEST_Context *ctx, 55 struct GNUNET_CADET_TEST_Context *ctx,
56 unsigned int num_peers, 56 unsigned int num_peers,
57 struct GNUNET_TESTBED_Peer **peers, 57 struct GNUNET_TESTBED_Peer **peers,
58 struct GNUNET_CADET_Handle **cadetes); 58 struct GNUNET_CADET_Handle **cadets);
59 59
60 60
61/** 61/**
62 * Run a test using the given name, configuration file and number of 62 * Run a test using the given name, configuration file and number of peers.
63 * peers. 63 * All cadet callbacks will receive the peer number (long) as the closure.
64 * All cadet callbacks will receive the peer number as the closure.
65 * 64 *
66 * @param testname Name of the test (for logging). 65 * @param testname Name of the test (for logging).
67 * @param cfgname Name of the configuration file. 66 * @param cfgfile Name of the configuration file.
68 * @param num_peers Number of peers to start. 67 * @param num_peers Number of peers to start.
69 * @param tmain Main function to run once the testbed is ready. 68 * @param tmain Main function to run once the testbed is ready.
70 * @param tmain_cls Closure for 'tmain'. 69 * @param tmain_cls Closure for @a tmain.
71 * @param new_channel Handler for incoming tunnels. 70 * @param connects Handler for incoming channels.
72 * @param cleaner Cleaner for destroyed incoming tunnels. 71 * @param window_changes Handler for the window size change notification.
72 * @param disconnects Cleaner for destroyed incoming channels.
73 * @param handlers Message handlers. 73 * @param handlers Message handlers.
74 * @param ports Ports the peers offer, NULL-terminated. 74 * @param ports Ports the peers offer, NULL-terminated.
75 */ 75 */
76void 76void
77GNUNET_CADET_TEST_run (const char *testname, 77GNUNET_CADET_TEST_ruN (const char *testname,
78 const char *cfgname, 78 const char *cfgfile,
79 unsigned int num_peers, 79 unsigned int num_peers,
80 GNUNET_CADET_TEST_AppMain tmain, 80 GNUNET_CADET_TEST_AppMain tmain,
81 void *tmain_cls, 81 void *tmain_cls,
82 GNUNET_CADET_InboundChannelNotificationHandler new_channel, 82 GNUNET_CADET_ConnectEventHandler connects,
83 GNUNET_CADET_ChannelEndHandler cleaner, 83 GNUNET_CADET_WindowSizeEventHandler window_changes,
84 struct GNUNET_CADET_MessageHandler* handlers, 84 GNUNET_CADET_DisconnectEventHandler disconnects,
85 const struct GNUNET_HashCode **ports); 85 struct GNUNET_MQ_MessageHandler *handlers,
86 86 const struct GNUNET_HashCode **ports);
87 87
88/** 88/**
89 * Clean up the testbed. 89 * Clean up the testbed.
diff --git a/src/cadet/desirability_table.c b/src/cadet/desirability_table.c
new file mode 100644
index 000000000..21ec3e388
--- /dev/null
+++ b/src/cadet/desirability_table.c
@@ -0,0 +1,35 @@
1/* This file is in the public domain. */
2
3/**
4 * @brief Program to simulate results from #GCP_get_desirability_of_path()
5 * for various plausible inputs.
6 * @author Christian Grothoff
7 */
8#include <stdio.h>
9
10int
11main ()
12{
13 for (unsigned int num_alts=1; num_alts<10; num_alts++)
14 for (unsigned int off=0; off<10; off++)
15 for (double delta=-(int) off;delta<=5;delta += 0.25)
16 {
17 double weight_alts;
18
19 if (delta <= - 1.0)
20 weight_alts = - 1.0 * num_alts / delta; /* discount alternative paths */
21 else if (delta >= 1.0)
22 weight_alts = 1.0 * num_alts * delta; /* overcount alternative paths */
23 else
24 weight_alts = 1.0 * num_alts; /* count alternative paths normally */
25
26 fprintf (stderr,
27 "Paths: %u Offset: %u Delta: %5.2f SCORE: %f\n",
28 num_alts,
29 off,
30 delta,
31 ((off + 1.0) / (weight_alts * weight_alts)));
32 }
33
34
35}
diff --git a/src/cadet/gnunet-cadet-profiler.c b/src/cadet/gnunet-cadet-profiler.c
index d688dc60b..15da05b6d 100644
--- a/src/cadet/gnunet-cadet-profiler.c
+++ b/src/cadet/gnunet-cadet-profiler.c
@@ -778,7 +778,9 @@ pong_handler (void *cls, struct GNUNET_CADET_Channel *channel,
778 latency = GNUNET_TIME_absolute_get_duration (send_time); 778 latency = GNUNET_TIME_absolute_get_duration (send_time);
779 r = ntohl (msg->round_number); 779 r = ntohl (msg->round_number);
780 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "%u <- %u (%u) latency: %s\n", 780 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "%u <- %u (%u) latency: %s\n",
781 get_index (peer), get_index (peer->dest), ntohl (msg->counter), 781 get_index (peer),
782 get_index (peer->dest),
783 (uint32_t) ntohl (msg->counter),
782 GNUNET_STRINGS_relative_time_to_string (latency, GNUNET_NO)); 784 GNUNET_STRINGS_relative_time_to_string (latency, GNUNET_NO));
783 785
784 /* Online variance calculation */ 786 /* Online variance calculation */
diff --git a/src/cadet/gnunet-cadet.c b/src/cadet/gnunet-cadet.c
index 80010ec54..675e7faf0 100644
--- a/src/cadet/gnunet-cadet.c
+++ b/src/cadet/gnunet-cadet.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2012 GNUnet e.V. 3 Copyright (C) 2012, 2017 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -22,6 +22,7 @@
22 * @file cadet/gnunet-cadet.c 22 * @file cadet/gnunet-cadet.c
23 * @brief Print information about cadet tunnels and peers. 23 * @brief Print information about cadet tunnels and peers.
24 * @author Bartlomiej Polot 24 * @author Bartlomiej Polot
25 * @author Christian Grothoff
25 */ 26 */
26#include "platform.h" 27#include "platform.h"
27#include "gnunet_util_lib.h" 28#include "gnunet_util_lib.h"
@@ -30,11 +31,6 @@
30 31
31 32
32/** 33/**
33 * Option -m.
34 */
35static int monitor_mode;
36
37/**
38 * Option -P. 34 * Option -P.
39 */ 35 */
40static int request_peers; 36static int request_peers;
@@ -100,11 +96,6 @@ static char *target_id;
100static char *target_port = "default"; 96static char *target_port = "default";
101 97
102/** 98/**
103 * Data pending in netcat mode.
104 */
105static size_t data_size;
106
107/**
108 * Cadet handle. 99 * Cadet handle.
109 */ 100 */
110static struct GNUNET_CADET_Handle *mh; 101static struct GNUNET_CADET_Handle *mh;
@@ -115,11 +106,6 @@ static struct GNUNET_CADET_Handle *mh;
115static struct GNUNET_CADET_Channel *ch; 106static struct GNUNET_CADET_Channel *ch;
116 107
117/** 108/**
118 * Transmit handle.
119 */
120static struct GNUNET_CADET_TransmitHandle *th;
121
122/**
123 * HashCode of the given port string 109 * HashCode of the given port string
124 */ 110 */
125static struct GNUNET_HashCode porthash; 111static struct GNUNET_HashCode porthash;
@@ -130,11 +116,6 @@ static struct GNUNET_HashCode porthash;
130struct GNUNET_CADET_Port *lp; 116struct GNUNET_CADET_Port *lp;
131 117
132/** 118/**
133 * Shutdown task handle.
134 */
135static struct GNUNET_SCHEDULER_Task *sd;
136
137/**
138 * Task for reading from stdin. 119 * Task for reading from stdin.
139 */ 120 */
140static struct GNUNET_SCHEDULER_Task *rd_task; 121static struct GNUNET_SCHEDULER_Task *rd_task;
@@ -145,6 +126,9 @@ static struct GNUNET_SCHEDULER_Task *rd_task;
145static struct GNUNET_SCHEDULER_Task *job; 126static struct GNUNET_SCHEDULER_Task *job;
146 127
147 128
129/**
130 * Wait for input on STDIO and send it out over the #ch.
131 */
148static void 132static void
149listen_stdio (void); 133listen_stdio (void);
150 134
@@ -214,22 +198,11 @@ shutdown_task (void *cls)
214{ 198{
215 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 199 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
216 "Shutdown\n"); 200 "Shutdown\n");
217 if (NULL != th)
218 {
219 GNUNET_CADET_notify_transmit_ready_cancel (th);
220 th = NULL;
221 }
222 if (NULL != ch) 201 if (NULL != ch)
223 { 202 {
224 GNUNET_CADET_channel_destroy (ch); 203 GNUNET_CADET_channel_destroy (ch);
225 ch = NULL; 204 ch = NULL;
226 } 205 }
227 else if (NULL != target_id) {
228 // FIXME: would be nicer to have proper NACK support from cadet_api
229 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
230 "Connection refused to %s\n",
231 target_id);
232 }
233 if (NULL != mh) 206 if (NULL != mh)
234 { 207 {
235 GNUNET_CADET_disconnect (mh); 208 GNUNET_CADET_disconnect (mh);
@@ -254,42 +227,38 @@ shutdown_task (void *cls)
254 227
255 228
256/** 229/**
257 * Function called to notify a client about the connection 230 * Task run in stdio mode, after some data is available at stdin.
258 * begin ready to queue more data. "buf" will be
259 * NULL and "size" zero if the connection was closed for
260 * writing in the meantime.
261 *
262 * FIXME
263 * 231 *
264 * @param cls closure 232 * @param cls Closure (unused).
265 * @param size number of bytes available in buf
266 * @param buf where the callee should write the message
267 * @return number of bytes written to buf
268 */ 233 */
269static size_t 234static void
270data_ready (void *cls, size_t size, void *buf) 235read_stdio (void *cls)
271{ 236{
237 struct GNUNET_MQ_Envelope *env;
272 struct GNUNET_MessageHeader *msg; 238 struct GNUNET_MessageHeader *msg;
273 size_t total_size; 239 char buf[60000];
274 240 ssize_t data_size;
275 th = NULL;
276 241
277 if (NULL == buf || 0 == size) 242 rd_task = NULL;
243 data_size = read (0,
244 buf,
245 60000);
246 if (data_size < 1)
278 { 247 {
279 GNUNET_SCHEDULER_shutdown(); 248 GNUNET_SCHEDULER_shutdown();
280 return 0; 249 return;
281 } 250 }
282
283 total_size = data_size + sizeof (struct GNUNET_MessageHeader);
284 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 251 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
285 "sending %u bytes\n", 252 "Read %u bytes from stdio\n",
286 (unsigned int) data_size); 253 (unsigned int) data_size);
287 GNUNET_assert (size >= total_size); 254 env = GNUNET_MQ_msg_extra (msg,
288 255 data_size,
289 msg = buf; 256 GNUNET_MESSAGE_TYPE_CADET_CLI);
290 msg->size = htons (total_size); 257 GNUNET_memcpy (&msg[1],
291 msg->type = htons (GNUNET_MESSAGE_TYPE_CADET_CLI); 258 buf,
292 GNUNET_memcpy (&msg[1], cls, data_size); 259 data_size);
260 GNUNET_MQ_send (GNUNET_CADET_get_mq (ch),
261 env);
293 if (GNUNET_NO == echo) 262 if (GNUNET_NO == echo)
294 { 263 {
295 listen_stdio (); 264 listen_stdio ();
@@ -298,53 +267,27 @@ data_ready (void *cls, size_t size, void *buf)
298 { 267 {
299 echo_time = GNUNET_TIME_absolute_get (); 268 echo_time = GNUNET_TIME_absolute_get ();
300 } 269 }
301
302 return total_size;
303} 270}
304 271
305 272
306/** 273/**
307 * Task run in stdio mode, after some data is available at stdin. 274 * Wait for input on STDIO and send it out over the #ch.
308 *
309 * @param cls Closure (unused).
310 */ 275 */
311static void 276static void
312read_stdio (void *cls) 277listen_stdio ()
313{
314 static char buf[60000];
315
316 data_size = read (0, buf, 60000);
317 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
318 "stdio read %u bytes\n",
319 (unsigned int) data_size);
320 if (data_size < 1)
321 {
322 GNUNET_SCHEDULER_shutdown();
323 return;
324 }
325 GNUNET_assert (NULL == th);
326 th = GNUNET_CADET_notify_transmit_ready (ch, GNUNET_NO,
327 GNUNET_TIME_UNIT_FOREVER_REL,
328 sizeof (struct GNUNET_MessageHeader)
329 + data_size,
330 &data_ready, buf);
331}
332
333
334/**
335 * Start listening to stdin
336 */
337static void
338listen_stdio (void)
339{ 278{
340 struct GNUNET_NETWORK_FDSet *rs; 279 struct GNUNET_NETWORK_FDSet *rs;
341 280
281 /* FIXME: why use 'rs' here, seems overly complicated... */
342 rs = GNUNET_NETWORK_fdset_create (); 282 rs = GNUNET_NETWORK_fdset_create ();
343 GNUNET_NETWORK_fdset_set_native (rs, 0); 283 GNUNET_NETWORK_fdset_set_native (rs,
284 0); /* STDIN */
344 rd_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, 285 rd_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
345 GNUNET_TIME_UNIT_FOREVER_REL, 286 GNUNET_TIME_UNIT_FOREVER_REL,
346 rs, NULL, 287 rs,
347 &read_stdio, NULL); 288 NULL,
289 &read_stdio,
290 NULL);
348 GNUNET_NETWORK_fdset_destroy (rs); 291 GNUNET_NETWORK_fdset_destroy (rs);
349} 292}
350 293
@@ -355,32 +298,17 @@ listen_stdio (void)
355 * 298 *
356 * It must NOT call #GNUNET_CADET_channel_destroy on the channel. 299 * It must NOT call #GNUNET_CADET_channel_destroy on the channel.
357 * 300 *
358 * @param cls closure (set from #GNUNET_CADET_connect) 301 * @param cls closure
359 * @param channel connection to the other end (henceforth invalid) 302 * @param channel connection to the other end (henceforth invalid)
360 * @param channel_ctx place where local state associated
361 * with the channel is stored
362 */ 303 */
363static void 304static void
364channel_ended (void *cls, 305channel_ended (void *cls,
365 const struct GNUNET_CADET_Channel *channel, 306 const struct GNUNET_CADET_Channel *channel)
366 void *channel_ctx)
367{ 307{
368 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Channel ended!\n"); 308 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
369 if (channel != ch) 309 "Channel ended!\n");
370 { 310 GNUNET_assert (channel == ch);
371 GNUNET_break (0); 311 ch = NULL;
372 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ended: %p, expected: %p\n", channel, ch);
373 }
374 else
375 {
376 ch = NULL;
377 }
378 if (NULL != th)
379 {
380 GNUNET_CADET_notify_transmit_ready_cancel (th);
381 th = NULL;
382 }
383
384 GNUNET_SCHEDULER_shutdown (); 312 GNUNET_SCHEDULER_shutdown ();
385} 313}
386 314
@@ -397,65 +325,27 @@ channel_ended (void *cls,
397 * @param cls closure 325 * @param cls closure
398 * @param channel new handle to the channel 326 * @param channel new handle to the channel
399 * @param initiator peer that started the channel 327 * @param initiator peer that started the channel
400 * @param port Port this channel is for. 328 * @return initial channel context for the channel, we use @a channel
401 * @param options CadetOption flag field, with all active option bits set to 1.
402 *
403 * @return initial channel context for the channel
404 * (can be NULL -- that's not an error)
405 */ 329 */
406static void * 330static void *
407channel_incoming (void *cls, 331channel_incoming (void *cls,
408 struct GNUNET_CADET_Channel *channel, 332 struct GNUNET_CADET_Channel *channel,
409 const struct GNUNET_PeerIdentity *initiator, 333 const struct GNUNET_PeerIdentity *initiator)
410 const struct GNUNET_HashCode *port,
411 enum GNUNET_CADET_ChannelOption options)
412{ 334{
413 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, 335 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
414 "Connected from %s\n", 336 "Incoming connection from %s\n",
415 GNUNET_i2s_full (initiator)); 337 GNUNET_i2s_full (initiator));
416 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 338 GNUNET_assert (NULL == ch);
417 "Incoming channel %p on port %s\n", 339 GNUNET_assert (NULL != lp);
418 channel, GNUNET_h2s (port)); 340 GNUNET_CADET_close_port (lp);
419 if (NULL != ch) 341 lp = NULL;
420 {
421 GNUNET_break (0);
422 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
423 "A channel already exists (%p)\n", ch);
424 /*
425 * From now on multiple channels will be sending data to us
426 * making the service of this command unpredictable in its
427 * current implementation. So for now let's just bail out.
428 */
429 GNUNET_SCHEDULER_shutdown();
430 return NULL;
431 }
432 if (NULL == listen_port)
433 {
434 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Not listening to channels\n");
435 return NULL;
436 }
437#if 0
438 // Closing the listen port currently breaks open connections.
439 // Is this an intentional departure from POSIX socket behavior?
440 //
441 if (NULL != lp) {
442 /* Now that we have our circuit up and running, let's not
443 * get confused by further incoming connect requests.
444 */
445 GNUNET_CADET_close_port (lp);
446 lp = NULL;
447 }
448#endif
449 ch = channel; 342 ch = channel;
450 if (GNUNET_NO == echo) 343 if (GNUNET_NO == echo)
451 {
452 listen_stdio (); 344 listen_stdio ();
453 return NULL; 345 return channel;
454 }
455 data_size = 0;
456 return NULL;
457} 346}
458 347
348
459/** 349/**
460 * @brief Send an echo request to the remote peer. 350 * @brief Send an echo request to the remote peer.
461 * 351 *
@@ -464,13 +354,16 @@ channel_incoming (void *cls,
464static void 354static void
465send_echo (void *cls) 355send_echo (void *cls)
466{ 356{
357 struct GNUNET_MQ_Envelope *env;
358 struct GNUNET_MessageHeader *msg;
359
360 echo_task = NULL;
467 if (NULL == ch) 361 if (NULL == ch)
468 return; 362 return;
469 GNUNET_assert (NULL == th); 363 env = GNUNET_MQ_msg (msg,
470 th = GNUNET_CADET_notify_transmit_ready (ch, GNUNET_NO, 364 GNUNET_MESSAGE_TYPE_CADET_CLI);
471 GNUNET_TIME_UNIT_FOREVER_REL, 365 GNUNET_MQ_send (GNUNET_CADET_get_mq (ch),
472 sizeof (struct GNUNET_MessageHeader), 366 env);
473 &data_ready, NULL);
474} 367}
475 368
476 369
@@ -483,44 +376,23 @@ static void
483request_dump (void *cls) 376request_dump (void *cls)
484{ 377{
485 GNUNET_CADET_request_dump (mh); 378 GNUNET_CADET_request_dump (mh);
486 GNUNET_SCHEDULER_cancel (sd); 379 GNUNET_SCHEDULER_shutdown ();
487 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
488 &shutdown_task, NULL);
489} 380}
490 381
491 382
492/** 383/**
493 * Call CADET's monitor API, get info of one connection. 384 * Check data message sanity. Does nothing so far (all messages are OK).
494 * 385 *
495 * @param cls Closure (unused). 386 * @param cls Closure (unused).
387 * @param message The message to check.
388 * @return #GNUNET_OK to keep the channel open,
389 * #GNUNET_SYSERR to close it (signal serious error).
496 */ 390 */
497static void 391static int
498create_channel (void *cls) 392check_data (void *cls,
393 const struct GNUNET_MessageHeader *message)
499{ 394{
500 struct GNUNET_PeerIdentity pid; 395 return GNUNET_OK; /* all is well-formed */
501 enum GNUNET_CADET_ChannelOption opt;
502
503 GNUNET_assert (NULL == ch);
504
505 if (GNUNET_OK !=
506 GNUNET_CRYPTO_eddsa_public_key_from_string (target_id,
507 strlen (target_id),
508 &pid.public_key))
509 {
510 FPRINTF (stderr,
511 _("Invalid target `%s'\n"),
512 target_id);
513 GNUNET_SCHEDULER_shutdown ();
514 return;
515 }
516 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting to `%s'\n", target_id);
517 opt = GNUNET_CADET_OPTION_DEFAULT | GNUNET_CADET_OPTION_RELIABLE;
518 GNUNET_CRYPTO_hash (target_port, strlen(target_port), &porthash);
519 ch = GNUNET_CADET_channel_create (mh, NULL, &pid, &porthash, opt);
520 if (GNUNET_NO == echo)
521 listen_stdio ();
522 else
523 echo_task = GNUNET_SCHEDULER_add_now (&send_echo, NULL);
524} 396}
525 397
526 398
@@ -531,42 +403,36 @@ create_channel (void *cls)
531 * in order to receive the next message. This doesn't need to be immediate: 403 * in order to receive the next message. This doesn't need to be immediate:
532 * can be delayed if some processing is done on the message. 404 * can be delayed if some processing is done on the message.
533 * 405 *
534 * @param cls Closure (set from #GNUNET_CADET_connect). 406 * @param cls NULL
535 * @param channel Connection to the other end.
536 * @param channel_ctx Place to store local state associated with the channel.
537 * @param message The actual message. 407 * @param message The actual message.
538 * @return #GNUNET_OK to keep the channel open,
539 * #GNUNET_SYSERR to close it (signal serious error).
540 */ 408 */
541static int 409static void
542data_callback (void *cls, 410handle_data (void *cls,
543 struct GNUNET_CADET_Channel *channel, 411 const struct GNUNET_MessageHeader *message)
544 void **channel_ctx,
545 const struct GNUNET_MessageHeader *message)
546{ 412{
413 size_t payload_size = ntohs (message->size) - sizeof (*message);
547 uint16_t len; 414 uint16_t len;
548 ssize_t done; 415 ssize_t done;
549 uint16_t off; 416 uint16_t off;
550 const char *buf; 417 const char *buf;
551 GNUNET_break (ch == channel);
552 GNUNET_CADET_receive_done (channel);
553 418
419 GNUNET_CADET_receive_done (ch);
554 if (GNUNET_YES == echo) 420 if (GNUNET_YES == echo)
555 { 421 {
556 if (NULL != listen_port) 422 if (NULL != listen_port)
557 { 423 {
558 /* Just listening to echo incoming messages*/ 424 struct GNUNET_MQ_Envelope *env;
559 if (NULL != th) 425 struct GNUNET_MessageHeader *msg;
560 { 426
561 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 427 env = GNUNET_MQ_msg_extra (msg,
562 "Last echo reply not yet sent, dropping current reply.\n"); 428 payload_size,
563 return GNUNET_OK; 429 GNUNET_MESSAGE_TYPE_CADET_CLI);
564 } 430 GNUNET_memcpy (&msg[1],
565 th = GNUNET_CADET_notify_transmit_ready (channel, GNUNET_NO, 431 &message[1],
566 GNUNET_TIME_UNIT_FOREVER_REL, 432 payload_size);
567 sizeof (struct GNUNET_MessageHeader), 433 GNUNET_MQ_send (GNUNET_CADET_get_mq (ch),
568 &data_ready, NULL); 434 env);
569 return GNUNET_OK; 435 return;
570 } 436 }
571 else 437 else
572 { 438 {
@@ -574,30 +440,37 @@ data_callback (void *cls,
574 440
575 latency = GNUNET_TIME_absolute_get_duration (echo_time); 441 latency = GNUNET_TIME_absolute_get_duration (echo_time);
576 echo_time = GNUNET_TIME_UNIT_FOREVER_ABS; 442 echo_time = GNUNET_TIME_UNIT_FOREVER_ABS;
577 FPRINTF (stdout, "time: %s\n", 443 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
578 GNUNET_STRINGS_relative_time_to_string (latency, GNUNET_NO)); 444 "time: %s\n",
445 GNUNET_STRINGS_relative_time_to_string (latency,
446 GNUNET_NO));
579 echo_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, 447 echo_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
580 &send_echo, NULL); 448 &send_echo,
449 NULL);
581 } 450 }
582 } 451 }
583 452
584 len = ntohs (message->size) - sizeof (*message); 453 len = ntohs (message->size) - sizeof (*message);
585 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got %u bytes\n", len); 454 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
455 "Got %u bytes\n",
456 len);
586 buf = (const char *) &message[1]; 457 buf = (const char *) &message[1];
587 off = 0; 458 off = 0;
588 while (off < len) 459 while (off < len)
589 { 460 {
590 done = write (1, &buf[off], len - off); 461 done = write (1,
462 &buf[off],
463 len - off);
591 if (done <= 0) 464 if (done <= 0)
592 { 465 {
593 if (-1 == done) 466 if (-1 == done)
594 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, 467 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
595 "write"); 468 "write");
596 return GNUNET_SYSERR; 469 GNUNET_SCHEDULER_shutdown ();
470 return;
597 } 471 }
598 off += done; 472 off += done;
599 } 473 }
600 return GNUNET_OK;
601} 474}
602 475
603 476
@@ -623,16 +496,17 @@ peers_callback (void *cls,
623{ 496{
624 if (NULL == peer) 497 if (NULL == peer)
625 { 498 {
626 if (GNUNET_YES != monitor_mode) 499 GNUNET_SCHEDULER_shutdown();
627 {
628 GNUNET_SCHEDULER_shutdown();
629 }
630 return; 500 return;
631 } 501 }
632 FPRINTF (stdout, "%s tunnel: %c, paths: %u\n", 502 FPRINTF (stdout,
633 GNUNET_i2s_full (peer), tunnel ? 'Y' : 'N', n_paths); 503 "%s tunnel: %c, paths: %u\n",
504 GNUNET_i2s_full (peer),
505 tunnel ? 'Y' : 'N',
506 n_paths);
634} 507}
635 508
509
636/** 510/**
637 * Method called to retrieve information about a specific peer 511 * Method called to retrieve information about a specific peer
638 * known to the service. 512 * known to the service.
@@ -652,19 +526,26 @@ peer_callback (void *cls,
652 int tunnel, 526 int tunnel,
653 int neighbor, 527 int neighbor,
654 unsigned int n_paths, 528 unsigned int n_paths,
655 struct GNUNET_PeerIdentity *paths) 529 const struct GNUNET_PeerIdentity *paths)
656{ 530{
657 unsigned int i; 531 unsigned int i;
658 struct GNUNET_PeerIdentity *p; 532 const struct GNUNET_PeerIdentity *p;
659 533
660 FPRINTF (stdout, "%s [TUNNEL: %s, NEIGHBOR: %s, PATHS: %u]\n", 534 FPRINTF (stdout,
535 "%s [TUNNEL: %s, NEIGHBOR: %s, PATHS: %u]\n",
661 GNUNET_i2s_full (peer), 536 GNUNET_i2s_full (peer),
662 tunnel ? "Y" : "N", neighbor ? "Y" : "N", n_paths); 537 tunnel ? "Y" : "N",
538 neighbor ? "Y" : "N",
539 n_paths);
663 p = paths; 540 p = paths;
664 for (i = 0; i < n_paths && NULL != p;) 541 for (i = 0; i < n_paths && NULL != p;)
665 { 542 {
666 FPRINTF (stdout, "%s ", GNUNET_i2s (p)); 543 FPRINTF (stdout,
667 if (0 == memcmp (p, peer, sizeof (*p))) 544 "%s ",
545 GNUNET_i2s (p));
546 if (0 == memcmp (p,
547 peer,
548 sizeof (*p)))
668 { 549 {
669 FPRINTF (stdout, "\n"); 550 FPRINTF (stdout, "\n");
670 i++; 551 i++;
@@ -696,16 +577,16 @@ tunnels_callback (void *cls,
696{ 577{
697 if (NULL == peer) 578 if (NULL == peer)
698 { 579 {
699 if (GNUNET_YES != monitor_mode) 580 GNUNET_SCHEDULER_shutdown();
700 {
701 GNUNET_SCHEDULER_shutdown();
702 }
703 return; 581 return;
704 } 582 }
705 FPRINTF (stdout, "%s [ENC: %s, CON: %s] CHs: %u, CONNs: %u\n", 583 FPRINTF (stdout,
584 "%s [ENC: %s, CON: %s] CHs: %u, CONNs: %u\n",
706 GNUNET_i2s_full (peer), 585 GNUNET_i2s_full (peer),
707 enc_2s (estate), conn_2s (cstate), 586 enc_2s (estate),
708 channels, connections); 587 conn_2s (cstate),
588 channels,
589 connections);
709} 590}
710 591
711 592
@@ -746,11 +627,7 @@ tunnel_callback (void *cls,
746 FPRINTF (stdout, "\tencryption state: %s\n", enc_2s (estate)); 627 FPRINTF (stdout, "\tencryption state: %s\n", enc_2s (estate));
747 FPRINTF (stdout, "\tconnection state: %s\n", conn_2s (cstate)); 628 FPRINTF (stdout, "\tconnection state: %s\n", conn_2s (cstate));
748 } 629 }
749 if (GNUNET_YES != monitor_mode) 630 GNUNET_SCHEDULER_shutdown ();
750 {
751 GNUNET_SCHEDULER_shutdown ();
752 }
753 return;
754} 631}
755 632
756 633
@@ -874,93 +751,158 @@ run (void *cls,
874 const char *cfgfile, 751 const char *cfgfile,
875 const struct GNUNET_CONFIGURATION_Handle *cfg) 752 const struct GNUNET_CONFIGURATION_Handle *cfg)
876{ 753{
877 static const struct GNUNET_CADET_MessageHandler handlers[] = { 754 struct GNUNET_MQ_MessageHandler handlers[] = {
878 {&data_callback, GNUNET_MESSAGE_TYPE_CADET_CLI, 0}, 755 GNUNET_MQ_hd_var_size (data,
879 {NULL, 0, 0} /* FIXME add option to monitor msg types */ 756 GNUNET_MESSAGE_TYPE_CADET_CLI,
757 struct GNUNET_MessageHeader,
758 NULL),
759 GNUNET_MQ_handler_end ()
880 }; 760 };
881 761
882 /* FIXME add option to monitor apps */ 762 /* FIXME add option to monitor apps */
883 763
884 target_id = args[0]; 764 target_id = args[0];
885 if (target_id && args[1]) target_port = args[1]; 765 if (target_id && args[1])
766 target_port = args[1];
886 767
887 if ( (0 != (request_peers | request_tunnels) 768 if ( (0 != (request_peers | request_tunnels)
888 || 0 != monitor_mode
889 || NULL != tunnel_id 769 || NULL != tunnel_id
890 || NULL != conn_id 770 || NULL != conn_id
891 || NULL != channel_id) 771 || NULL != channel_id)
892 && target_id != NULL) 772 && target_id != NULL)
893 { 773 {
894 FPRINTF (stderr, 774 FPRINTF (stderr,
895 _("You must NOT give a TARGET " 775 _("Extra arguments are not applicable "
896 "when using 'request all' options\n")); 776 "in combination with this option.\n"));
897 return; 777 return;
898 } 778 }
899 779
900 if (GNUNET_YES == dump) 780 if (GNUNET_YES == dump)
901 { 781 {
902 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 782 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
903 "requesting debug dump\n"); 783 "Requesting debug dump\n");
904 GNUNET_SCHEDULER_add_now (&request_dump, NULL); 784 job = GNUNET_SCHEDULER_add_now (&request_dump,
905 } 785 NULL);
906 else if (NULL != target_id)
907 {
908 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
909 "Creating channel to %s\n",
910 target_id);
911 GNUNET_SCHEDULER_add_now (&create_channel, NULL);
912 } 786 }
913 else if (NULL != peer_id) 787 else if (NULL != peer_id)
914 { 788 {
915 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Show peer\n"); 789 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
916 job = GNUNET_SCHEDULER_add_now (&show_peer, NULL); 790 "Show peer\n");
791 job = GNUNET_SCHEDULER_add_now (&show_peer,
792 NULL);
917 } 793 }
918 else if (NULL != tunnel_id) 794 else if (NULL != tunnel_id)
919 { 795 {
920 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Show tunnel\n"); 796 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
921 job = GNUNET_SCHEDULER_add_now (&show_tunnel, NULL); 797 "Show tunnel\n");
798 job = GNUNET_SCHEDULER_add_now (&show_tunnel,
799 NULL);
922 } 800 }
923 else if (NULL != channel_id) 801 else if (NULL != channel_id)
924 { 802 {
925 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Show channel\n"); 803 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
926 job = GNUNET_SCHEDULER_add_now (&show_channel, NULL); 804 "Show channel\n");
805 job = GNUNET_SCHEDULER_add_now (&show_channel,
806 NULL);
927 } 807 }
928 else if (NULL != conn_id) 808 else if (NULL != conn_id)
929 { 809 {
930 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Show connection\n"); 810 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
931 job = GNUNET_SCHEDULER_add_now (&show_connection, NULL); 811 "Show connection\n");
812 job = GNUNET_SCHEDULER_add_now (&show_connection,
813 NULL);
932 } 814 }
933 else if (GNUNET_YES == request_peers) 815 else if (GNUNET_YES == request_peers)
934 { 816 {
935 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Show all peers\n"); 817 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
936 job = GNUNET_SCHEDULER_add_now (&get_peers, NULL); 818 "Show all peers\n");
819 job = GNUNET_SCHEDULER_add_now (&get_peers,
820 NULL);
937 } 821 }
938 else if (GNUNET_YES == request_tunnels) 822 else if (GNUNET_YES == request_tunnels)
939 { 823 {
940 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Show all tunnels\n"); 824 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
941 job = GNUNET_SCHEDULER_add_now (&get_tunnels, NULL); 825 "Show all tunnels\n");
826 job = GNUNET_SCHEDULER_add_now (&get_tunnels,
827 NULL);
942 } 828 }
943 else if (NULL == listen_port) 829
830 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
831 "Connecting to CADET service\n");
832 mh = GNUNET_CADET_connect (cfg);
833 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
834 NULL);
835 if (NULL == mh)
944 { 836 {
945 FPRINTF (stderr, "No action requested\n"); 837 GNUNET_SCHEDULER_shutdown ();
946 return; 838 return;
947 } 839 }
948
949 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting to CADET service\n");
950 mh = GNUNET_CADET_connect (cfg,
951 NULL, /* cls */
952 &channel_ended, /* cleaner */
953 handlers);
954 if (NULL == mh)
955 GNUNET_SCHEDULER_add_now (&shutdown_task, NULL);
956 else
957 sd = GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL);
958
959 if (NULL != listen_port) 840 if (NULL != listen_port)
960 { 841 {
961 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Opening CADET listen port\n"); 842 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
962 GNUNET_CRYPTO_hash (listen_port, strlen(listen_port), &porthash); 843 "Opening CADET listen port\n");
963 lp = GNUNET_CADET_open_port (mh, &porthash, &channel_incoming, NULL); 844 GNUNET_CRYPTO_hash (listen_port,
845 strlen (listen_port),
846 &porthash);
847 lp = GNUNET_CADET_open_port (mh,
848 &porthash,
849 &channel_incoming,
850 NULL,
851 NULL /* window changes */,
852 &channel_ended,
853 handlers);
854 }
855 if (NULL != target_id)
856 {
857 struct GNUNET_PeerIdentity pid;
858 enum GNUNET_CADET_ChannelOption opt;
859
860 if (GNUNET_OK !=
861 GNUNET_CRYPTO_eddsa_public_key_from_string (target_id,
862 strlen (target_id),
863 &pid.public_key))
864 {
865 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
866 _("Invalid target `%s'\n"),
867 target_id);
868 GNUNET_SCHEDULER_shutdown ();
869 return;
870 }
871 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
872 "Connecting to `%s:%s'\n",
873 target_id,
874 target_port);
875 opt = GNUNET_CADET_OPTION_DEFAULT | GNUNET_CADET_OPTION_RELIABLE;
876 GNUNET_CRYPTO_hash (target_port,
877 strlen(target_port),
878 &porthash);
879 ch = GNUNET_CADET_channel_create (mh,
880 NULL,
881 &pid,
882 &porthash,
883 opt,
884 NULL /* window changes */,
885 &channel_ended,
886 handlers);
887 if (GNUNET_YES == echo)
888 {
889 echo_task = GNUNET_SCHEDULER_add_now (&send_echo,
890 NULL);
891 }
892 else
893 {
894 listen_stdio ();
895 }
896 }
897
898 if ( (NULL == lp) &&
899 (NULL == job) &&
900 (NULL == ch) )
901 {
902 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
903 _("No action requested\n"));
904 GNUNET_SCHEDULER_shutdown ();
905 return;
964 } 906 }
965} 907}
966 908
@@ -973,51 +915,70 @@ run (void *cls,
973 * @return 0 ok, 1 on error 915 * @return 0 ok, 1 on error
974 */ 916 */
975int 917int
976main (int argc, char *const *argv) 918main (int argc,
919 char *const *argv)
977{ 920{
978 int res; 921 int res;
979 const char helpstr[] = "Create channels and retreive info about cadets status."; 922 const char helpstr[] = "Create tunnels and retrieve info about CADET's status.";
980 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 923 struct GNUNET_GETOPT_CommandLineOption options[] = {
981// {'a', "channel", "TUNNEL_ID:CHANNEL_ID", 924 /* I would use the terminology 'circuit' here... --lynX */
982// gettext_noop ("provide information about a particular channel"), 925 GNUNET_GETOPT_option_string ('C',
983// GNUNET_YES, &GNUNET_GETOPT_set_string, &channel_id}, 926 "connection",
984 {'C', "connection", "CONNECTION_ID", 927 "CONNECTION_ID",
985 gettext_noop ("provide information about a particular connection"), 928 gettext_noop ("Provide information about a particular connection"),
986 GNUNET_YES, &GNUNET_GETOPT_set_string, &conn_id}, 929 &conn_id),
987 {'e', "echo", NULL, 930
988 gettext_noop ("activate echo mode"), 931 GNUNET_GETOPT_option_flag ('e',
989 GNUNET_NO, &GNUNET_GETOPT_set_one, &echo}, 932 "echo",
990 {'d', "dump", NULL, 933 gettext_noop ("Activate echo mode"),
991 gettext_noop ("dump debug information to STDERR"), 934 &echo),
992 GNUNET_NO, &GNUNET_GETOPT_set_one, &dump}, 935
993// {'m', "monitor", NULL, 936 GNUNET_GETOPT_option_flag ('d',
994// gettext_noop ("provide information about all events (continuously)"), 937 "dump",
995// GNUNET_NO, &GNUNET_GETOPT_set_one, &monitor_mode}, 938 gettext_noop ("Dump debug information to STDERR"),
996 {'o', "open-port", NULL, 939 &dump),
997 gettext_noop ("port to listen to"), 940
998 GNUNET_YES, &GNUNET_GETOPT_set_string, &listen_port}, 941 GNUNET_GETOPT_option_string ('o',
999 {'p', "peer", "PEER_ID", 942 "open-port",
1000 gettext_noop ("provide information about a patricular peer"), 943 "SHARED_SECRET",
1001 GNUNET_YES, &GNUNET_GETOPT_set_string, &peer_id}, 944 gettext_noop ("Listen for connections using a shared secret among sender and recipient"),
1002 {'P', "peers", NULL, 945 &listen_port),
1003 gettext_noop ("provide information about all peers"), 946
1004 GNUNET_NO, &GNUNET_GETOPT_set_one, &request_peers}, 947
1005 {'t', "tunnel", "TUNNEL_ID", 948 GNUNET_GETOPT_option_string ('p',
1006 gettext_noop ("provide information about a particular tunnel"), 949 "peer",
1007 GNUNET_YES, &GNUNET_GETOPT_set_string, &tunnel_id}, 950 "PEER_ID",
1008 {'T', "tunnels", NULL, 951 gettext_noop ("Provide information about a patricular peer"),
1009 gettext_noop ("provide information about all tunnels"), 952 &peer_id),
1010 GNUNET_NO, &GNUNET_GETOPT_set_one, &request_tunnels}, 953
954
955 GNUNET_GETOPT_option_flag ('P',
956 "peers",
957 gettext_noop ("Provide information about all peers"),
958 &request_peers),
959
960 GNUNET_GETOPT_option_string ('t',
961 "tunnel",
962 "TUNNEL_ID",
963 gettext_noop ("Provide information about a particular tunnel"),
964 &tunnel_id),
965
966
967 GNUNET_GETOPT_option_flag ('T',
968 "tunnels",
969 gettext_noop ("Provide information about all tunnels"),
970 &request_tunnels),
1011 971
1012 GNUNET_GETOPT_OPTION_END 972 GNUNET_GETOPT_OPTION_END
1013 }; 973 };
1014 974
1015 monitor_mode = GNUNET_NO; 975 if (GNUNET_OK !=
1016 976 GNUNET_STRINGS_get_utf8_args (argc, argv,
1017 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) 977 &argc, &argv))
1018 return 2; 978 return 2;
1019 979
1020 res = GNUNET_PROGRAM_run (argc, argv, "gnunet-cadet (OPTIONS | TARGET PORT)", 980 res = GNUNET_PROGRAM_run (argc, argv,
981 "gnunet-cadet (OPTIONS | PEER_ID SHARED_SECRET)",
1021 gettext_noop (helpstr), 982 gettext_noop (helpstr),
1022 options, &run, NULL); 983 options, &run, NULL);
1023 984
@@ -1025,8 +986,7 @@ main (int argc, char *const *argv)
1025 986
1026 if (GNUNET_OK == res) 987 if (GNUNET_OK == res)
1027 return 0; 988 return 0;
1028 else 989 return 1;
1029 return 1;
1030} 990}
1031 991
1032/* end of gnunet-cadet.c */ 992/* end of gnunet-cadet.c */
diff --git a/src/cadet/gnunet-service-cadet-new.c b/src/cadet/gnunet-service-cadet-new.c
deleted file mode 100644
index 97489f3fd..000000000
--- a/src/cadet/gnunet-service-cadet-new.c
+++ /dev/null
@@ -1,1428 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2001-2013, 2017 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 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 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file cadet/gnunet-service-cadet-new.c
23 * @brief GNUnet CADET service with encryption
24 * @author Bartlomiej Polot
25 * @author Christian Grothoff
26 *
27 * Dictionary:
28 * - peer: other cadet instance. If there is direct connection it's a neighbor.
29 * - path: series of directly connected peer from one peer to another.
30 * - connection: path which is being used in a tunnel.
31 * - tunnel: encrypted connection to a peer, neighbor or not.
32 * - channel: logical link between two clients, on the same or different peers.
33 * have properties like reliability.
34 */
35
36#include "platform.h"
37#include "gnunet_util_lib.h"
38#include "cadet.h"
39#include "gnunet_statistics_service.h"
40#include "gnunet-service-cadet-new.h"
41#include "gnunet-service-cadet-new_channel.h"
42#include "gnunet-service-cadet-new_connection.h"
43#include "gnunet-service-cadet-new_core.h"
44#include "gnunet-service-cadet-new_dht.h"
45#include "gnunet-service-cadet-new_hello.h"
46#include "gnunet-service-cadet-new_tunnels.h"
47#include "gnunet-service-cadet-new_peer.h"
48#include "gnunet-service-cadet-new_paths.h"
49
50#define LOG(level, ...) GNUNET_log (level,__VA_ARGS__)
51
52
53/**
54 * Struct containing information about a client of the service
55 */
56struct CadetClient
57{
58 /**
59 * Linked list next
60 */
61 struct CadetClient *next;
62
63 /**
64 * Linked list prev
65 */
66 struct CadetClient *prev;
67
68 /**
69 * Tunnels that belong to this client, indexed by local id,
70 * value is a `struct CadetChannel`.
71 */
72 struct GNUNET_CONTAINER_MultiHashMap32 *channels;
73
74 /**
75 * Handle to communicate with the client
76 */
77 struct GNUNET_MQ_Handle *mq;
78
79 /**
80 * Client handle.
81 */
82 struct GNUNET_SERVICE_Client *client;
83
84 /**
85 * Ports that this client has declared interest in.
86 * Indexed by port, contains *Client.
87 */
88 struct GNUNET_CONTAINER_MultiHashMap *ports;
89
90 /**
91 * Channel ID to use for the next incoming channel for this client.
92 * Wraps around (in theory).
93 */
94 struct GNUNET_CADET_ClientChannelNumber next_ccn;
95
96 /**
97 * ID of the client, mainly for debug messages. Purely internal to this file.
98 */
99 unsigned int id;
100};
101
102/******************************************************************************/
103/*********************** GLOBAL VARIABLES ****************************/
104/******************************************************************************/
105
106/****************************** Global variables ******************************/
107
108/**
109 * Handle to our configuration.
110 */
111const struct GNUNET_CONFIGURATION_Handle *cfg;
112
113/**
114 * Handle to the statistics service.
115 */
116struct GNUNET_STATISTICS_Handle *stats;
117
118/**
119 * Handle to communicate with ATS.
120 */
121struct GNUNET_ATS_ConnectivityHandle *ats_ch;
122
123/**
124 * Local peer own ID.
125 */
126struct GNUNET_PeerIdentity my_full_id;
127
128/**
129 * Own private key.
130 */
131struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key;
132
133/**
134 * Signal that shutdown is happening: prevent recovery measures.
135 */
136int shutting_down;
137
138/**
139 * DLL with all the clients, head.
140 */
141static struct CadetClient *clients_head;
142
143/**
144 * DLL with all the clients, tail.
145 */
146static struct CadetClient *clients_tail;
147
148/**
149 * Next ID to assign to a client.
150 */
151static unsigned int next_client_id;
152
153/**
154 * All ports clients of this peer have opened.
155 */
156struct GNUNET_CONTAINER_MultiHashMap *open_ports;
157
158/**
159 * Map from ports to channels where the ports were closed at the
160 * time we got the inbound connection.
161 * Indexed by port, contains `struct CadetChannel`.
162 */
163struct GNUNET_CONTAINER_MultiHashMap *loose_channels;
164
165/**
166 * Map from PIDs to `struct CadetPeer` entries.
167 */
168struct GNUNET_CONTAINER_MultiPeerMap *peers;
169
170/**
171 * Map from `struct GNUNET_CADET_ConnectionTunnelIdentifier`
172 * hash codes to `struct CadetConnection` objects.
173 */
174struct GNUNET_CONTAINER_MultiShortmap *connections;
175
176/**
177 * How many messages are needed to trigger an AXOLOTL ratchet advance.
178 */
179unsigned long long ratchet_messages;
180
181/**
182 * How long until we trigger a ratched advance due to time.
183 */
184struct GNUNET_TIME_Relative ratchet_time;
185
186
187/**
188 * Send a message to a client.
189 *
190 * @param c client to get the message
191 * @param env envelope with the message
192 */
193void
194GSC_send_to_client (struct CadetClient *c,
195 struct GNUNET_MQ_Envelope *env)
196{
197 GNUNET_MQ_send (c->mq,
198 env);
199}
200
201
202/**
203 * Return identifier for a client as a string.
204 *
205 * @param c client to identify
206 * @return string for debugging
207 */
208const char *
209GSC_2s (struct CadetClient *c)
210{
211 static char buf[32];
212
213 GNUNET_snprintf (buf,
214 sizeof (buf),
215 "Client(%u)",
216 c->id);
217 return buf;
218}
219
220
221/**
222 * Lookup channel of client @a c by @a ccn.
223 *
224 * @param c client to look in
225 * @param ccn channel ID to look up
226 * @return NULL if no such channel exists
227 */
228static struct CadetChannel *
229lookup_channel (struct CadetClient *c,
230 struct GNUNET_CADET_ClientChannelNumber ccn)
231{
232 return GNUNET_CONTAINER_multihashmap32_get (c->channels,
233 ntohl (ccn.channel_of_client));
234}
235
236
237/**
238 * Obtain the next LID to use for incoming connections to
239 * the given client.
240 *
241 * @param c client handle
242 */
243static struct GNUNET_CADET_ClientChannelNumber
244client_get_next_ccn (struct CadetClient *c)
245{
246 struct GNUNET_CADET_ClientChannelNumber ccn = c->next_ccn;
247
248 /* increment until we have a free one... */
249 while (NULL !=
250 lookup_channel (c,
251 ccn))
252 {
253 ccn.channel_of_client
254 = htonl (1 + (ntohl (ccn.channel_of_client)));
255 if (ntohl (ccn.channel_of_client) >=
256 GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
257 ccn.channel_of_client = htonl (0);
258 }
259 c->next_ccn.channel_of_client
260 = htonl (1 + (ntohl (ccn.channel_of_client)));
261 return ccn;
262}
263
264
265/**
266 * Bind incoming channel to this client, and notify client about
267 * incoming connection. Caller is responsible for notifying the other
268 * peer about our acceptance of the channel.
269 *
270 * @param c client to bind to
271 * @param ch channel to be bound
272 * @param dest peer that establishes the connection
273 * @param port port number
274 * @param options options
275 * @return local channel number assigned to the new client
276 */
277struct GNUNET_CADET_ClientChannelNumber
278GSC_bind (struct CadetClient *c,
279 struct CadetChannel *ch,
280 struct CadetPeer *dest,
281 const struct GNUNET_HashCode *port,
282 uint32_t options)
283{
284 struct GNUNET_MQ_Envelope *env;
285 struct GNUNET_CADET_LocalChannelCreateMessage *cm;
286 struct GNUNET_CADET_ClientChannelNumber ccn;
287
288 ccn = client_get_next_ccn (c);
289 GNUNET_assert (GNUNET_YES ==
290 GNUNET_CONTAINER_multihashmap32_put (c->channels,
291 ntohl (ccn.channel_of_client),
292 ch,
293 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
294 LOG (GNUNET_ERROR_TYPE_DEBUG,
295 "Accepting incoming %s from %s on open port %s (%u), assigning ccn %X\n",
296 GCCH_2s (ch),
297 GCP_2s (dest),
298 GNUNET_h2s (port),
299 ntohl (options),
300 ntohl (ccn.channel_of_client));
301 /* notify local client about incoming connection! */
302 env = GNUNET_MQ_msg (cm,
303 GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE);
304 cm->ccn = ccn;
305 cm->port = *port;
306 cm->opt = htonl (options);
307 cm->peer = *GCP_get_id (dest);
308 GSC_send_to_client (c,
309 env);
310 return ccn;
311}
312
313
314/**
315 * Callback invoked on all peers to destroy all tunnels
316 * that may still exist.
317 *
318 * @param cls NULL
319 * @param pid identify of a peer
320 * @param value a `struct CadetPeer` that may still have a tunnel
321 * @return #GNUNET_OK (iterate over all entries)
322 */
323static int
324destroy_tunnels_now (void *cls,
325 const struct GNUNET_PeerIdentity *pid,
326 void *value)
327{
328 struct CadetPeer *cp = value;
329 struct CadetTunnel *t = GCP_get_tunnel (cp,
330 GNUNET_NO);
331
332 if (NULL != t)
333 GCT_destroy_tunnel_now (t);
334 return GNUNET_OK;
335}
336
337
338/**
339 * Callback invoked on all peers to destroy all tunnels
340 * that may still exist.
341 *
342 * @param cls NULL
343 * @param pid identify of a peer
344 * @param value a `struct CadetPeer` that may still have a tunnel
345 * @return #GNUNET_OK (iterate over all entries)
346 */
347static int
348destroy_paths_now (void *cls,
349 const struct GNUNET_PeerIdentity *pid,
350 void *value)
351{
352 struct CadetPeer *cp = value;
353
354 GCP_drop_owned_paths (cp);
355 return GNUNET_OK;
356}
357
358
359/**
360 * Shutdown everything once the clients have disconnected.
361 */
362static void
363shutdown_rest ()
364{
365 if (NULL != stats)
366 {
367 GNUNET_STATISTICS_destroy (stats,
368 GNUNET_NO);
369 stats = NULL;
370 }
371 if (NULL != open_ports)
372 {
373 GNUNET_CONTAINER_multihashmap_destroy (open_ports);
374 open_ports = NULL;
375 }
376 if (NULL != loose_channels)
377 {
378 GNUNET_CONTAINER_multihashmap_destroy (loose_channels);
379 loose_channels = NULL;
380 }
381 /* Destroy tunnels. Note that all channels must be destroyed first! */
382 GCP_iterate_all (&destroy_tunnels_now,
383 NULL);
384 /* All tunnels, channels, connections and CORE must be down before this point. */
385 GCP_iterate_all (&destroy_paths_now,
386 NULL);
387 /* All paths, tunnels, channels, connections and CORE must be down before this point. */
388 GCP_destroy_all_peers ();
389 if (NULL != peers)
390 {
391 GNUNET_CONTAINER_multipeermap_destroy (peers);
392 peers = NULL;
393 }
394 if (NULL != connections)
395 {
396 GNUNET_CONTAINER_multishortmap_destroy (connections);
397 connections = NULL;
398 }
399 if (NULL != ats_ch)
400 {
401 GNUNET_ATS_connectivity_done (ats_ch);
402 ats_ch = NULL;
403 }
404 GCD_shutdown ();
405 GCH_shutdown ();
406 GNUNET_free_non_null (my_private_key);
407 my_private_key = NULL;
408}
409
410
411/**
412 * Task run during shutdown.
413 *
414 * @param cls unused
415 */
416static void
417shutdown_task (void *cls)
418{
419 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
420 "Shutting down\n");
421 shutting_down = GNUNET_YES;
422 GCO_shutdown ();
423 if (NULL == clients_head)
424 shutdown_rest ();
425}
426
427
428/**
429 * We had a remote connection @a value to port @a port before
430 * client @a cls opened port @a port. Bind them now.
431 *
432 * @param cls the `struct CadetClient`
433 * @param port the port
434 * @param value the `struct CadetChannel`
435 * @return #GNUNET_YES (iterate over all such channels)
436 */
437static int
438bind_loose_channel (void *cls,
439 const struct GNUNET_HashCode *port,
440 void *value)
441{
442 struct CadetClient *c = cls;
443 struct CadetChannel *ch = value;
444
445 GCCH_bind (ch,
446 c);
447 GNUNET_assert (GNUNET_YES ==
448 GNUNET_CONTAINER_multihashmap_remove (loose_channels,
449 port,
450 value));
451 return GNUNET_YES;
452}
453
454
455/**
456 * Handle port open request. Creates a mapping from the
457 * port to the respective client and checks whether we have
458 * loose channels trying to bind to the port. If so, those
459 * are bound.
460 *
461 * @param cls Identification of the client.
462 * @param pmsg The actual message.
463 */
464static void
465handle_port_open (void *cls,
466 const struct GNUNET_CADET_PortMessage *pmsg)
467{
468 struct CadetClient *c = cls;
469
470 LOG (GNUNET_ERROR_TYPE_DEBUG,
471 "Open port %s requested by %s\n",
472 GNUNET_h2s (&pmsg->port),
473 GSC_2s (c));
474 if (NULL == c->ports)
475 c->ports = GNUNET_CONTAINER_multihashmap_create (4,
476 GNUNET_NO);
477 if (GNUNET_OK !=
478 GNUNET_CONTAINER_multihashmap_put (c->ports,
479 &pmsg->port,
480 c,
481 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
482 {
483 GNUNET_break (0);
484 GNUNET_SERVICE_client_drop (c->client);
485 return;
486 }
487 (void) GNUNET_CONTAINER_multihashmap_put (open_ports,
488 &pmsg->port,
489 c,
490 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
491 GNUNET_CONTAINER_multihashmap_get_multiple (loose_channels,
492 &pmsg->port,
493 &bind_loose_channel,
494 c);
495 GNUNET_SERVICE_client_continue (c->client);
496}
497
498
499/**
500 * Handler for port close requests. Marks this port as closed
501 * (unless of course we have another client with the same port
502 * open). Note that existing channels accepted on the port are
503 * not affected.
504 *
505 * @param cls Identification of the client.
506 * @param pmsg The actual message.
507 */
508static void
509handle_port_close (void *cls,
510 const struct GNUNET_CADET_PortMessage *pmsg)
511{
512 struct CadetClient *c = cls;
513
514 LOG (GNUNET_ERROR_TYPE_DEBUG,
515 "Closing port %s as requested by %s\n",
516 GNUNET_h2s (&pmsg->port),
517 GSC_2s (c));
518 if (GNUNET_YES !=
519 GNUNET_CONTAINER_multihashmap_remove (c->ports,
520 &pmsg->port,
521 c))
522 {
523 GNUNET_break (0);
524 GNUNET_SERVICE_client_drop (c->client);
525 return;
526 }
527 GNUNET_assert (GNUNET_YES ==
528 GNUNET_CONTAINER_multihashmap_remove (open_ports,
529 &pmsg->port,
530 c));
531 GNUNET_SERVICE_client_continue (c->client);
532}
533
534
535/**
536 * Handler for requests for us creating a new channel to another peer and port.
537 *
538 * @param cls Identification of the client.
539 * @param tcm The actual message.
540 */
541static void
542handle_channel_create (void *cls,
543 const struct GNUNET_CADET_LocalChannelCreateMessage *tcm)
544{
545 struct CadetClient *c = cls;
546 struct CadetChannel *ch;
547
548 if (ntohl (tcm->ccn.channel_of_client) < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
549 {
550 /* Channel ID not in allowed range. */
551 GNUNET_break (0);
552 GNUNET_SERVICE_client_drop (c->client);
553 return;
554 }
555 ch = lookup_channel (c,
556 tcm->ccn);
557 if (NULL != ch)
558 {
559 /* Channel ID already in use. Not allowed. */
560 GNUNET_break (0);
561 GNUNET_SERVICE_client_drop (c->client);
562 return;
563 }
564 LOG (GNUNET_ERROR_TYPE_DEBUG,
565 "New channel to %s at port %s requested by %s\n",
566 GNUNET_i2s (&tcm->peer),
567 GNUNET_h2s (&tcm->port),
568 GSC_2s (c));
569
570 /* Create channel */
571 ch = GCCH_channel_local_new (c,
572 tcm->ccn,
573 GCP_get (&tcm->peer,
574 GNUNET_YES),
575 &tcm->port,
576 ntohl (tcm->opt));
577 if (NULL == ch)
578 {
579 GNUNET_break (0);
580 GNUNET_SERVICE_client_drop (c->client);
581 return;
582 }
583 GNUNET_assert (GNUNET_YES ==
584 GNUNET_CONTAINER_multihashmap32_put (c->channels,
585 ntohl (tcm->ccn.channel_of_client),
586 ch,
587 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
588
589 GNUNET_SERVICE_client_continue (c->client);
590}
591
592
593/**
594 * Handler for requests of destroying an existing channel.
595 *
596 * @param cls client identification of the client
597 * @param msg the actual message
598 */
599static void
600handle_channel_destroy (void *cls,
601 const struct GNUNET_CADET_LocalChannelDestroyMessage *msg)
602{
603 struct CadetClient *c = cls;
604 struct CadetChannel *ch;
605
606 ch = lookup_channel (c,
607 msg->ccn);
608 if (NULL == ch)
609 {
610 /* Client attempted to destroy unknown channel */
611 GNUNET_break (0);
612 GNUNET_SERVICE_client_drop (c->client);
613 return;
614 }
615 LOG (GNUNET_ERROR_TYPE_INFO,
616 "%s is destroying %s\n",
617 GSC_2s(c),
618 GCCH_2s (ch));
619 GNUNET_assert (GNUNET_YES ==
620 GNUNET_CONTAINER_multihashmap32_remove (c->channels,
621 ntohl (msg->ccn.channel_of_client),
622 ch));
623 GCCH_channel_local_destroy (ch,
624 c,
625 msg->ccn);
626 GNUNET_SERVICE_client_continue (c->client);
627}
628
629
630/**
631 * Check for client traffic data message is well-formed.
632 *
633 * @param cls identification of the client
634 * @param msg the actual message
635 * @return #GNUNET_OK if @a msg is OK, #GNUNET_SYSERR if not
636 */
637static int
638check_local_data (void *cls,
639 const struct GNUNET_CADET_LocalData *msg)
640{
641 size_t payload_size;
642 size_t payload_claimed_size;
643 const char *buf;
644 struct GNUNET_MessageHeader pa;
645
646 /* FIXME: what is the format we shall allow for @a msg?
647 ONE payload item or multiple? Seems current cadet_api
648 at least in theory allows more than one. Next-gen
649 cadet_api will likely no more, so we could then
650 simplify this mess again. */
651 /* Sanity check for message size */
652 payload_size = ntohs (msg->header.size) - sizeof (*msg);
653 buf = (const char *) &msg[1];
654 while (payload_size >= sizeof (struct GNUNET_MessageHeader))
655 {
656 /* need to memcpy() for alignment */
657 GNUNET_memcpy (&pa,
658 buf,
659 sizeof (pa));
660 payload_claimed_size = ntohs (pa.size);
661 if ( (payload_size < payload_claimed_size) ||
662 (payload_claimed_size < sizeof (struct GNUNET_MessageHeader)) ||
663 (GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE < payload_claimed_size) )
664 {
665 GNUNET_break (0);
666 LOG (GNUNET_ERROR_TYPE_DEBUG,
667 "Local data of %u total size had sub-message %u at %u with %u bytes\n",
668 ntohs (msg->header.size),
669 ntohs (pa.type),
670 (unsigned int) (buf - (const char *) &msg[1]),
671 (unsigned int) payload_claimed_size);
672 return GNUNET_SYSERR;
673 }
674 payload_size -= payload_claimed_size;
675 buf += payload_claimed_size;
676 }
677 if (0 != payload_size)
678 {
679 GNUNET_break_op (0);
680 return GNUNET_SYSERR;
681 }
682 return GNUNET_OK;
683}
684
685
686/**
687 * Handler for client payload traffic to be send on a channel to
688 * another peer.
689 *
690 * @param cls identification of the client
691 * @param msg the actual message
692 */
693static void
694handle_local_data (void *cls,
695 const struct GNUNET_CADET_LocalData *msg)
696{
697 struct CadetClient *c = cls;
698 struct CadetChannel *ch;
699 size_t payload_size;
700 const char *buf;
701
702 ch = lookup_channel (c,
703 msg->ccn);
704 if (NULL == ch)
705 {
706 /* Channel does not exist! */
707 GNUNET_break (0);
708 GNUNET_SERVICE_client_drop (c->client);
709 return;
710 }
711 payload_size = ntohs (msg->header.size) - sizeof (*msg);
712 buf = (const char *) &msg[1];
713 LOG (GNUNET_ERROR_TYPE_DEBUG,
714 "Received %u bytes payload from %s for %s\n",
715 (unsigned int) payload_size,
716 GSC_2s (c),
717 GCCH_2s (ch));
718 if (GNUNET_OK !=
719 GCCH_handle_local_data (ch,
720 msg->ccn,
721 buf,
722 payload_size))
723 {
724 GNUNET_SERVICE_client_drop (c->client);
725 return;
726 }
727 GNUNET_SERVICE_client_continue (c->client);
728}
729
730
731/**
732 * Handler for client's ACKs for payload traffic.
733 *
734 * @param cls identification of the client.
735 * @param msg The actual message.
736 */
737static void
738handle_local_ack (void *cls,
739 const struct GNUNET_CADET_LocalAck *msg)
740{
741 struct CadetClient *c = cls;
742 struct CadetChannel *ch;
743
744 ch = lookup_channel (c,
745 msg->ccn);
746 if (NULL == ch)
747 {
748 /* Channel does not exist! */
749 GNUNET_break (0);
750 GNUNET_SERVICE_client_drop (c->client);
751 return;
752 }
753 LOG (GNUNET_ERROR_TYPE_DEBUG,
754 "Got a local ACK from %s for %s\n",
755 GSC_2s(c),
756 GCCH_2s (ch));
757 GCCH_handle_local_ack (ch,
758 msg->ccn);
759 GNUNET_SERVICE_client_continue (c->client);
760}
761
762
763/**
764 * Iterator over all peers to send a monitoring client info about each peer.
765 *
766 * @param cls Closure ().
767 * @param peer Peer ID (tunnel remote peer).
768 * @param value Peer info.
769 * @return #GNUNET_YES, to keep iterating.
770 */
771static int
772get_all_peers_iterator (void *cls,
773 const struct GNUNET_PeerIdentity *peer,
774 void *value)
775{
776 struct CadetClient *c = cls;
777 struct CadetPeer *p = value;
778 struct GNUNET_MQ_Envelope *env;
779 struct GNUNET_CADET_LocalInfoPeer *msg;
780
781 env = GNUNET_MQ_msg (msg,
782 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS);
783 msg->destination = *peer;
784 msg->paths = htons (GCP_count_paths (p));
785 msg->tunnel = htons (NULL != GCP_get_tunnel (p,
786 GNUNET_NO));
787 GNUNET_MQ_send (c->mq,
788 env);
789 return GNUNET_YES;
790}
791
792
793/**
794 * Handler for client's INFO PEERS request.
795 *
796 * @param cls Identification of the client.
797 * @param message The actual message.
798 */
799static void
800handle_get_peers (void *cls,
801 const struct GNUNET_MessageHeader *message)
802{
803 struct CadetClient *c = cls;
804 struct GNUNET_MQ_Envelope *env;
805 struct GNUNET_MessageHeader *reply;
806
807 GCP_iterate_all (&get_all_peers_iterator,
808 c);
809 env = GNUNET_MQ_msg (reply,
810 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS);
811 GNUNET_MQ_send (c->mq,
812 env);
813 GNUNET_SERVICE_client_continue (c->client);
814}
815
816
817/**
818 * Iterator over all paths of a peer to build an InfoPeer message.
819 * Message contains blocks of peers, first not included.
820 *
821 * @param cls message queue for transmission
822 * @param path Path itself
823 * @param off offset of the peer on @a path
824 * @return #GNUNET_YES if should keep iterating.
825 * #GNUNET_NO otherwise.
826 */
827static int
828path_info_iterator (void *cls,
829 struct CadetPeerPath *path,
830 unsigned int off)
831{
832 struct GNUNET_MQ_Handle *mq = cls;
833 struct GNUNET_MQ_Envelope *env;
834 struct GNUNET_MessageHeader *resp;
835 struct GNUNET_PeerIdentity *id;
836 uint16_t path_size;
837 unsigned int i;
838 unsigned int path_length;
839
840 path_length = GCPP_get_length (path);
841 path_size = sizeof (struct GNUNET_PeerIdentity) * (path_length - 1);
842 if (sizeof (*resp) + path_size > UINT16_MAX)
843 {
844 LOG (GNUNET_ERROR_TYPE_WARNING,
845 "Path of %u entries is too long for info message\n",
846 path_length);
847 return GNUNET_YES;
848 }
849 env = GNUNET_MQ_msg_extra (resp,
850 path_size,
851 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER);
852 id = (struct GNUNET_PeerIdentity *) &resp[1];
853
854 /* Don't copy first peer. First peer is always the local one. Last
855 * peer is always the destination (leave as 0, EOL).
856 */
857 for (i = 0; i < off; i++)
858 id[i] = *GCP_get_id (GCPP_get_peer_at_offset (path,
859 i + 1));
860 GNUNET_MQ_send (mq,
861 env);
862 return GNUNET_YES;
863}
864
865
866/**
867 * Handler for client's SHOW_PEER request.
868 *
869 * @param cls Identification of the client.
870 * @param msg The actual message.
871 */
872static void
873handle_show_peer (void *cls,
874 const struct GNUNET_CADET_LocalInfo *msg)
875{
876 struct CadetClient *c = cls;
877 struct CadetPeer *p;
878 struct GNUNET_MQ_Envelope *env;
879 struct GNUNET_MessageHeader *resp;
880
881 p = GCP_get (&msg->peer,
882 GNUNET_NO);
883 if (NULL != p)
884 GCP_iterate_paths (p,
885 &path_info_iterator,
886 c->mq);
887 /* Send message with 0/0 to indicate the end */
888 env = GNUNET_MQ_msg (resp,
889 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER_END);
890 GNUNET_MQ_send (c->mq,
891 env);
892 GNUNET_SERVICE_client_continue (c->client);
893}
894
895
896/**
897 * Iterator over all tunnels to send a monitoring client info about each tunnel.
898 *
899 * @param cls Closure ().
900 * @param peer Peer ID (tunnel remote peer).
901 * @param value a `struct CadetPeer`
902 * @return #GNUNET_YES, to keep iterating.
903 */
904static int
905get_all_tunnels_iterator (void *cls,
906 const struct GNUNET_PeerIdentity *peer,
907 void *value)
908{
909 struct CadetClient *c = cls;
910 struct CadetPeer *p = value;
911 struct GNUNET_MQ_Envelope *env;
912 struct GNUNET_CADET_LocalInfoTunnel *msg;
913 struct CadetTunnel *t;
914
915 t = GCP_get_tunnel (p,
916 GNUNET_NO);
917 if (NULL == t)
918 return GNUNET_YES;
919 env = GNUNET_MQ_msg (msg,
920 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS);
921 msg->destination = *peer;
922 msg->channels = htonl (GCT_count_channels (t));
923 msg->connections = htonl (GCT_count_any_connections (t));
924 msg->cstate = htons (0);
925 msg->estate = htons ((uint16_t) GCT_get_estate (t));
926 GNUNET_MQ_send (c->mq,
927 env);
928 return GNUNET_YES;
929}
930
931
932/**
933 * Handler for client's #GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS request.
934 *
935 * @param cls client Identification of the client.
936 * @param message The actual message.
937 */
938static void
939handle_info_tunnels (void *cls,
940 const struct GNUNET_MessageHeader *message)
941{
942 struct CadetClient *c = cls;
943 struct GNUNET_MQ_Envelope *env;
944 struct GNUNET_MessageHeader *reply;
945
946 GCP_iterate_all (&get_all_tunnels_iterator,
947 c);
948 env = GNUNET_MQ_msg (reply,
949 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS);
950 GNUNET_MQ_send (c->mq,
951 env);
952 GNUNET_SERVICE_client_continue (c->client);
953}
954
955
956/**
957 * Update the message with information about the connection.
958 *
959 * @param cls a `struct GNUNET_CADET_LocalInfoTunnel` message to update
960 * @param c a connection about which we should store information in @a cls
961 */
962static void
963iter_connection (void *cls,
964 struct CadetConnection *c)
965{
966 struct GNUNET_CADET_LocalInfoTunnel *msg = cls;
967 struct GNUNET_CADET_ConnectionTunnelIdentifier *h;
968
969 h = (struct GNUNET_CADET_ConnectionTunnelIdentifier *) &msg[1];
970 h[msg->connections++] = *(GCC_get_id (c));
971}
972
973
974/**
975 * Update the message with information about the channel.
976 *
977 * @param cls a `struct GNUNET_CADET_LocalInfoTunnel` message to update
978 * @param ch a channel about which we should store information in @a cls
979 */
980static void
981iter_channel (void *cls,
982 struct CadetChannel *ch)
983{
984 struct GNUNET_CADET_LocalInfoTunnel *msg = cls;
985 struct GNUNET_CADET_ConnectionTunnelIdentifier *h = (struct GNUNET_CADET_ConnectionTunnelIdentifier *) &msg[1];
986 struct GNUNET_CADET_ChannelTunnelNumber *chn
987 = (struct GNUNET_CADET_ChannelTunnelNumber *) &h[msg->connections];
988
989 chn[msg->channels++] = GCCH_get_id (ch);
990}
991
992
993/**
994 * Handler for client's #GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL request.
995 *
996 * @param cls Identification of the client.
997 * @param msg The actual message.
998 */
999static void
1000handle_info_tunnel (void *cls,
1001 const struct GNUNET_CADET_LocalInfo *msg)
1002{
1003 struct CadetClient *c = cls;
1004 struct GNUNET_MQ_Envelope *env;
1005 struct GNUNET_CADET_LocalInfoTunnel *resp;
1006 struct CadetTunnel *t;
1007 struct CadetPeer *p;
1008 unsigned int ch_n;
1009 unsigned int c_n;
1010
1011 p = GCP_get (&msg->peer,
1012 GNUNET_NO);
1013 t = GCP_get_tunnel (p,
1014 GNUNET_NO);
1015 if (NULL == t)
1016 {
1017 /* We don't know the tunnel */
1018 struct GNUNET_MQ_Envelope *env;
1019 struct GNUNET_CADET_LocalInfoTunnel *warn;
1020
1021 LOG (GNUNET_ERROR_TYPE_INFO,
1022 "Tunnel to %s unknown\n",
1023 GNUNET_i2s_full (&msg->peer));
1024 env = GNUNET_MQ_msg (warn,
1025 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL);
1026 warn->destination = msg->peer;
1027 GNUNET_MQ_send (c->mq,
1028 env);
1029 GNUNET_SERVICE_client_continue (c->client);
1030 return;
1031 }
1032
1033 /* Initialize context */
1034 ch_n = GCT_count_channels (t);
1035 c_n = GCT_count_any_connections (t);
1036 env = GNUNET_MQ_msg_extra (resp,
1037 c_n * sizeof (struct GNUNET_CADET_ConnectionTunnelIdentifier) +
1038 ch_n * sizeof (struct GNUNET_CADET_ChannelTunnelNumber),
1039 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL);
1040 resp->destination = msg->peer;
1041 /* Do not reorder! #iter_channel needs counters in HBO! */
1042 GCT_iterate_connections (t,
1043 &iter_connection,
1044 resp);
1045 GCT_iterate_channels (t,
1046 &iter_channel,
1047 resp);
1048 resp->connections = htonl (resp->connections);
1049 resp->channels = htonl (resp->channels);
1050 resp->cstate = htons (0);
1051 resp->estate = htons (GCT_get_estate (t));
1052 GNUNET_MQ_send (c->mq,
1053 env);
1054 GNUNET_SERVICE_client_continue (c->client);
1055}
1056
1057
1058/**
1059 * Iterator over all peers to dump info for each peer.
1060 *
1061 * @param cls Closure (unused).
1062 * @param peer Peer ID (tunnel remote peer).
1063 * @param value Peer info.
1064 *
1065 * @return #GNUNET_YES, to keep iterating.
1066 */
1067static int
1068show_peer_iterator (void *cls,
1069 const struct GNUNET_PeerIdentity *peer,
1070 void *value)
1071{
1072 struct CadetPeer *p = value;
1073 struct CadetTunnel *t;
1074
1075 t = GCP_get_tunnel (p,
1076 GNUNET_NO);
1077 if (NULL != t)
1078 GCT_debug (t,
1079 GNUNET_ERROR_TYPE_ERROR);
1080 LOG (GNUNET_ERROR_TYPE_ERROR, "\n");
1081 return GNUNET_YES;
1082}
1083
1084
1085/**
1086 * Handler for client's INFO_DUMP request.
1087 *
1088 * @param cls Identification of the client.
1089 * @param message The actual message.
1090 */
1091static void
1092handle_info_dump (void *cls,
1093 const struct GNUNET_MessageHeader *message)
1094{
1095 struct CadetClient *c = cls;
1096
1097 LOG (GNUNET_ERROR_TYPE_INFO,
1098 "Received dump info request from client %u\n",
1099 c->id);
1100
1101 LOG (GNUNET_ERROR_TYPE_ERROR,
1102 "*************************** DUMP START ***************************\n");
1103 for (struct CadetClient *ci = clients_head;
1104 NULL != ci;
1105 ci = ci->next)
1106 {
1107 LOG (GNUNET_ERROR_TYPE_ERROR,
1108 "Client %u (%p), handle: %p, ports: %u, channels: %u\n",
1109 ci->id,
1110 ci,
1111 ci->client,
1112 (NULL != c->ports)
1113 ? GNUNET_CONTAINER_multihashmap_size (ci->ports)
1114 : 0,
1115 GNUNET_CONTAINER_multihashmap32_size (ci->channels));
1116 }
1117 LOG (GNUNET_ERROR_TYPE_ERROR, "***************************\n");
1118 GCP_iterate_all (&show_peer_iterator,
1119 NULL);
1120
1121 LOG (GNUNET_ERROR_TYPE_ERROR,
1122 "**************************** DUMP END ****************************\n");
1123
1124 GNUNET_SERVICE_client_continue (c->client);
1125}
1126
1127
1128
1129/**
1130 * Callback called when a client connects to the service.
1131 *
1132 * @param cls closure for the service
1133 * @param client the new client that connected to the service
1134 * @param mq the message queue used to send messages to the client
1135 * @return @a c
1136 */
1137static void *
1138client_connect_cb (void *cls,
1139 struct GNUNET_SERVICE_Client *client,
1140 struct GNUNET_MQ_Handle *mq)
1141{
1142 struct CadetClient *c;
1143
1144 c = GNUNET_new (struct CadetClient);
1145 c->client = client;
1146 c->mq = mq;
1147 c->id = next_client_id++; /* overflow not important: just for debug */
1148 c->channels
1149 = GNUNET_CONTAINER_multihashmap32_create (32);
1150 GNUNET_CONTAINER_DLL_insert (clients_head,
1151 clients_tail,
1152 c);
1153 GNUNET_STATISTICS_update (stats,
1154 "# clients",
1155 +1,
1156 GNUNET_NO);
1157 LOG (GNUNET_ERROR_TYPE_DEBUG,
1158 "%s connected\n",
1159 GSC_2s (c));
1160 return c;
1161}
1162
1163
1164/**
1165 * A channel was destroyed by the other peer. Tell our client.
1166 *
1167 * @param c client that lost a channel
1168 * @param ccn channel identification number for the client
1169 * @param ch the channel object
1170 */
1171void
1172GSC_handle_remote_channel_destroy (struct CadetClient *c,
1173 struct GNUNET_CADET_ClientChannelNumber ccn,
1174 struct CadetChannel *ch)
1175{
1176 struct GNUNET_MQ_Envelope *env;
1177 struct GNUNET_CADET_LocalChannelDestroyMessage *tdm;
1178
1179 env = GNUNET_MQ_msg (tdm,
1180 GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY);
1181 tdm->ccn = ccn;
1182 GSC_send_to_client (c,
1183 env);
1184 GNUNET_assert (GNUNET_YES ==
1185 GNUNET_CONTAINER_multihashmap32_remove (c->channels,
1186 ntohl (ccn.channel_of_client),
1187 ch));
1188}
1189
1190
1191/**
1192 * Iterator for deleting each channel whose client endpoint disconnected.
1193 *
1194 * @param cls Closure (client that has disconnected).
1195 * @param key The local channel id in host byte order
1196 * @param value The value stored at the key (channel to destroy).
1197 * @return #GNUNET_OK, keep iterating.
1198 */
1199static int
1200channel_destroy_iterator (void *cls,
1201 uint32_t key,
1202 void *value)
1203{
1204 struct CadetClient *c = cls;
1205 struct GNUNET_CADET_ClientChannelNumber ccn;
1206 struct CadetChannel *ch = value;
1207
1208 LOG (GNUNET_ERROR_TYPE_DEBUG,
1209 "Destroying %s, due to %s disconnecting.\n",
1210 GCCH_2s (ch),
1211 GSC_2s (c));
1212 GNUNET_assert (GNUNET_YES ==
1213 GNUNET_CONTAINER_multihashmap32_remove (c->channels,
1214 key,
1215 ch));
1216 ccn.channel_of_client = htonl (key);
1217 GCCH_channel_local_destroy (ch,
1218 c,
1219 ccn);
1220 return GNUNET_OK;
1221}
1222
1223
1224/**
1225 * Remove client's ports from the global hashmap on disconnect.
1226 *
1227 * @param cls Closure (unused).
1228 * @param key the port.
1229 * @param value the `struct CadetClient` to remove
1230 * @return #GNUNET_OK, keep iterating.
1231 */
1232static int
1233client_release_ports (void *cls,
1234 const struct GNUNET_HashCode *key,
1235 void *value)
1236{
1237 struct CadetClient *c = value;
1238
1239 LOG (GNUNET_ERROR_TYPE_DEBUG,
1240 "Closing port %s due to %s disconnect.\n",
1241 GNUNET_h2s (key),
1242 GSC_2s (c));
1243 GNUNET_assert (GNUNET_YES ==
1244 GNUNET_CONTAINER_multihashmap_remove (open_ports,
1245 key,
1246 value));
1247 GNUNET_assert (GNUNET_YES ==
1248 GNUNET_CONTAINER_multihashmap_remove (c->ports,
1249 key,
1250 value));
1251 return GNUNET_OK;
1252}
1253
1254
1255/**
1256 * Callback called when a client disconnected from the service
1257 *
1258 * @param cls closure for the service
1259 * @param client the client that disconnected
1260 * @param internal_cls should be equal to @a c
1261 */
1262static void
1263client_disconnect_cb (void *cls,
1264 struct GNUNET_SERVICE_Client *client,
1265 void *internal_cls)
1266{
1267 struct CadetClient *c = internal_cls;
1268
1269 GNUNET_assert (c->client == client);
1270 LOG (GNUNET_ERROR_TYPE_DEBUG,
1271 "%s is disconnecting.\n",
1272 GSC_2s (c));
1273 if (NULL != c->channels)
1274 {
1275 GNUNET_CONTAINER_multihashmap32_iterate (c->channels,
1276 &channel_destroy_iterator,
1277 c);
1278 GNUNET_CONTAINER_multihashmap32_destroy (c->channels);
1279 }
1280 if (NULL != c->ports)
1281 {
1282 GNUNET_CONTAINER_multihashmap_iterate (c->ports,
1283 &client_release_ports,
1284 c);
1285 GNUNET_CONTAINER_multihashmap_destroy (c->ports);
1286 }
1287 GNUNET_CONTAINER_DLL_remove (clients_head,
1288 clients_tail,
1289 c);
1290 GNUNET_STATISTICS_update (stats,
1291 "# clients",
1292 -1,
1293 GNUNET_NO);
1294 GNUNET_free (c);
1295 if ( (NULL == clients_head) &&
1296 (GNUNET_YES == shutting_down) )
1297 shutdown_rest ();
1298}
1299
1300
1301/**
1302 * Setup CADET internals.
1303 *
1304 * @param cls closure
1305 * @param server the initialized server
1306 * @param c configuration to use
1307 */
1308static void
1309run (void *cls,
1310 const struct GNUNET_CONFIGURATION_Handle *c,
1311 struct GNUNET_SERVICE_Handle *service)
1312{
1313 cfg = c;
1314 if (GNUNET_OK !=
1315 GNUNET_CONFIGURATION_get_value_number (c,
1316 "CADET",
1317 "RATCHET_MESSAGES",
1318 &ratchet_messages))
1319 {
1320 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
1321 "CADET",
1322 "RATCHET_MESSAGES",
1323 "needs to be a number");
1324 ratchet_messages = 64;
1325 }
1326 if (GNUNET_OK !=
1327 GNUNET_CONFIGURATION_get_value_time (c,
1328 "CADET",
1329 "RATCHET_TIME",
1330 &ratchet_time))
1331 {
1332 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
1333 "CADET",
1334 "RATCHET_TIME",
1335 "need delay value");
1336 ratchet_time = GNUNET_TIME_UNIT_HOURS;
1337 }
1338
1339 my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (c);
1340 if (NULL == my_private_key)
1341 {
1342 GNUNET_break (0);
1343 GNUNET_SCHEDULER_shutdown ();
1344 return;
1345 }
1346 GNUNET_CRYPTO_eddsa_key_get_public (my_private_key,
1347 &my_full_id.public_key);
1348 stats = GNUNET_STATISTICS_create ("cadet",
1349 c);
1350 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
1351 NULL);
1352 ats_ch = GNUNET_ATS_connectivity_init (c);
1353 /* FIXME: optimize code to allow GNUNET_YES here! */
1354 open_ports = GNUNET_CONTAINER_multihashmap_create (16,
1355 GNUNET_NO);
1356 loose_channels = GNUNET_CONTAINER_multihashmap_create (16,
1357 GNUNET_NO);
1358 peers = GNUNET_CONTAINER_multipeermap_create (16,
1359 GNUNET_YES);
1360 connections = GNUNET_CONTAINER_multishortmap_create (256,
1361 GNUNET_YES);
1362 GCH_init (c);
1363 GCD_init (c);
1364 GCO_init (c);
1365 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1366 "CADET started for peer %s\n",
1367 GNUNET_i2s (&my_full_id));
1368
1369}
1370
1371
1372/**
1373 * Define "main" method using service macro.
1374 */
1375GNUNET_SERVICE_MAIN
1376("cadet",
1377 GNUNET_SERVICE_OPTION_NONE,
1378 &run,
1379 &client_connect_cb,
1380 &client_disconnect_cb,
1381 NULL,
1382 GNUNET_MQ_hd_fixed_size (port_open,
1383 GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_OPEN,
1384 struct GNUNET_CADET_PortMessage,
1385 NULL),
1386 GNUNET_MQ_hd_fixed_size (port_close,
1387 GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE,
1388 struct GNUNET_CADET_PortMessage,
1389 NULL),
1390 GNUNET_MQ_hd_fixed_size (channel_create,
1391 GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE,
1392 struct GNUNET_CADET_LocalChannelCreateMessage,
1393 NULL),
1394 GNUNET_MQ_hd_fixed_size (channel_destroy,
1395 GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY,
1396 struct GNUNET_CADET_LocalChannelDestroyMessage,
1397 NULL),
1398 GNUNET_MQ_hd_var_size (local_data,
1399 GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA,
1400 struct GNUNET_CADET_LocalData,
1401 NULL),
1402 GNUNET_MQ_hd_fixed_size (local_ack,
1403 GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK,
1404 struct GNUNET_CADET_LocalAck,
1405 NULL),
1406 GNUNET_MQ_hd_fixed_size (get_peers,
1407 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS,
1408 struct GNUNET_MessageHeader,
1409 NULL),
1410 GNUNET_MQ_hd_fixed_size (show_peer,
1411 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER,
1412 struct GNUNET_CADET_LocalInfo,
1413 NULL),
1414 GNUNET_MQ_hd_fixed_size (info_tunnels,
1415 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS,
1416 struct GNUNET_MessageHeader,
1417 NULL),
1418 GNUNET_MQ_hd_fixed_size (info_tunnel,
1419 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL,
1420 struct GNUNET_CADET_LocalInfo,
1421 NULL),
1422 GNUNET_MQ_hd_fixed_size (info_dump,
1423 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_DUMP,
1424 struct GNUNET_MessageHeader,
1425 NULL),
1426 GNUNET_MQ_handler_end ());
1427
1428/* end of gnunet-service-cadet-new.c */
diff --git a/src/cadet/gnunet-service-cadet-new_channel.c b/src/cadet/gnunet-service-cadet-new_channel.c
deleted file mode 100644
index 0c6241817..000000000
--- a/src/cadet/gnunet-service-cadet-new_channel.c
+++ /dev/null
@@ -1,1613 +0,0 @@
1
2/*
3 This file is part of GNUnet.
4 Copyright (C) 2001-2017 GNUnet e.V.
5
6 GNUnet is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published
8 by the Free Software Foundation; either version 3, or (at your
9 option) any later version.
10
11 GNUnet is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNUnet; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
20*/
21/**
22 * @file cadet/gnunet-service-cadet-new_channel.c
23 * @brief logical links between CADET clients
24 * @author Bartlomiej Polot
25 * @author Christian Grothoff
26 *
27 * TODO:
28 * - FIXME: send ACKs back to loopback clients!
29 *
30 * - introduce shutdown so we can have half-closed channels, modify
31 * destroy to include MID to have FIN-ACK equivalents, etc.
32 * - estimate max bandwidth using bursts and use to for CONGESTION CONTROL!
33 * - check that '0xFFULL' really is sufficient for flow control!
34 * - revisit handling of 'unreliable' traffic!
35 * - revisit handling of 'out-of-order' option, especially in combination with/without 'reliable'.
36 * - figure out flow control without ACKs (unreliable traffic!)
37 */
38#include "platform.h"
39#include "gnunet_util_lib.h"
40#include "cadet.h"
41#include "gnunet_statistics_service.h"
42#include "gnunet-service-cadet-new.h"
43#include "gnunet-service-cadet-new_channel.h"
44#include "gnunet-service-cadet-new_connection.h"
45#include "gnunet-service-cadet-new_tunnels.h"
46#include "gnunet-service-cadet-new_peer.h"
47#include "gnunet-service-cadet-new_paths.h"
48
49#define LOG(level,...) GNUNET_log_from (level,"cadet-chn",__VA_ARGS__)
50
51/**
52 * How long do we initially wait before retransmitting?
53 */
54#define CADET_INITIAL_RETRANSMIT_TIME GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 250)
55
56/**
57 * How long do we wait before dropping state about incoming
58 * connection to closed port?
59 */
60#define TIMEOUT_CLOSED_PORT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 30)
61
62
63/**
64 * All the states a connection can be in.
65 */
66enum CadetChannelState
67{
68 /**
69 * Uninitialized status, should never appear in operation.
70 */
71 CADET_CHANNEL_NEW,
72
73 /**
74 * Connection create message sent, waiting for ACK.
75 */
76 CADET_CHANNEL_OPEN_SENT,
77
78 /**
79 * Connection confirmed, ready to carry traffic.
80 */
81 CADET_CHANNEL_READY
82};
83
84
85/**
86 * Info needed to retry a message in case it gets lost.
87 * Note that we DO use this structure also for unreliable
88 * messages.
89 */
90struct CadetReliableMessage
91{
92 /**
93 * Double linked list, FIFO style
94 */
95 struct CadetReliableMessage *next;
96
97 /**
98 * Double linked list, FIFO style
99 */
100 struct CadetReliableMessage *prev;
101
102 /**
103 * Which channel is this message in?
104 */
105 struct CadetChannel *ch;
106
107 /**
108 * Entry in the tunnels queue for this message, NULL if it has left
109 * the tunnel. Used to cancel transmission in case we receive an
110 * ACK in time.
111 */
112 struct CadetTunnelQueueEntry *qe;
113
114 /**
115 * How soon should we retry if we fail to get an ACK?
116 * Messages in the queue are sorted by this value.
117 */
118 struct GNUNET_TIME_Absolute next_retry;
119
120 /**
121 * How long do we wait for an ACK after transmission?
122 * Use for the back-off calculation.
123 */
124 struct GNUNET_TIME_Relative retry_delay;
125
126 /**
127 * Data message we are trying to send.
128 */
129 struct GNUNET_CADET_ChannelAppDataMessage *data_message;
130
131};
132
133
134/**
135 * List of received out-of-order data messages.
136 */
137struct CadetOutOfOrderMessage
138{
139 /**
140 * Double linked list, FIFO style
141 */
142 struct CadetOutOfOrderMessage *next;
143
144 /**
145 * Double linked list, FIFO style
146 */
147 struct CadetOutOfOrderMessage *prev;
148
149 /**
150 * ID of the message (messages up to this point needed
151 * before we give this one to the client).
152 */
153 struct ChannelMessageIdentifier mid;
154
155 /**
156 * The envelope with the payload of the out-of-order message
157 */
158 struct GNUNET_MQ_Envelope *env;
159
160};
161
162
163/**
164 * Client endpoint of a `struct CadetChannel`. A channel may be a
165 * loopback channel, in which case it has two of these endpoints.
166 * Note that flow control also is required in both directions.
167 */
168struct CadetChannelClient
169{
170 /**
171 * Client handle. Not by itself sufficient to designate
172 * the client endpoint, as the same client handle may
173 * be used for both the owner and the destination, and
174 * we thus also need the channel ID to identify the client.
175 */
176 struct CadetClient *c;
177
178 /**
179 * Head of DLL of messages received out of order or while client was unready.
180 */
181 struct CadetOutOfOrderMessage *head_recv;
182
183 /**
184 * Tail DLL of messages received out of order or while client was unready.
185 */
186 struct CadetOutOfOrderMessage *tail_recv;
187
188 /**
189 * Local tunnel number for this client.
190 * (if owner >= #GNUNET_CADET_LOCAL_CHANNEL_ID_CLI,
191 * otherwise < #GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
192 */
193 struct GNUNET_CADET_ClientChannelNumber ccn;
194
195 /**
196 * Can we send data to the client?
197 */
198 int client_ready;
199
200};
201
202
203/**
204 * Struct containing all information regarding a channel to a remote client.
205 */
206struct CadetChannel
207{
208 /**
209 * Tunnel this channel is in.
210 */
211 struct CadetTunnel *t;
212
213 /**
214 * Client owner of the tunnel, if any.
215 * (Used if this channel represends the initiating end of the tunnel.)
216 */
217 struct CadetChannelClient *owner;
218
219 /**
220 * Client destination of the tunnel, if any.
221 * (Used if this channel represents the listening end of the tunnel.)
222 */
223 struct CadetChannelClient *dest;
224
225 /**
226 * Last entry in the tunnel's queue relating to control messages
227 * (#GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN or
228 * #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK). Used to cancel
229 * transmission in case we receive updated information.
230 */
231 struct CadetTunnelQueueEntry *last_control_qe;
232
233 /**
234 * Head of DLL of messages sent and not yet ACK'd.
235 */
236 struct CadetReliableMessage *head_sent;
237
238 /**
239 * Tail of DLL of messages sent and not yet ACK'd.
240 */
241 struct CadetReliableMessage *tail_sent;
242
243 /**
244 * Task to resend/poll in case no ACK is received.
245 */
246 struct GNUNET_SCHEDULER_Task *retry_control_task;
247
248 /**
249 * Task to resend/poll in case no ACK is received.
250 */
251 struct GNUNET_SCHEDULER_Task *retry_data_task;
252
253 /**
254 * Last time the channel was used
255 */
256 struct GNUNET_TIME_Absolute timestamp;
257
258 /**
259 * Destination port of the channel.
260 */
261 struct GNUNET_HashCode port;
262
263 /**
264 * Counter for exponential backoff.
265 */
266 struct GNUNET_TIME_Relative retry_time;
267
268 /**
269 * How long does it usually take to get an ACK.
270 */
271 struct GNUNET_TIME_Relative expected_delay;
272
273 /**
274 * Bitfield of already-received messages past @e mid_recv.
275 */
276 uint64_t mid_futures;
277
278 /**
279 * Next MID expected for incoming traffic.
280 */
281 struct ChannelMessageIdentifier mid_recv;
282
283 /**
284 * Next MID to use for outgoing traffic.
285 */
286 struct ChannelMessageIdentifier mid_send;
287
288 /**
289 * Total (reliable) messages pending ACK for this channel.
290 */
291 unsigned int pending_messages;
292
293 /**
294 * Maximum (reliable) messages pending ACK for this channel
295 * before we throttle the client.
296 */
297 unsigned int max_pending_messages;
298
299 /**
300 * Number identifying this channel in its tunnel.
301 */
302 struct GNUNET_CADET_ChannelTunnelNumber ctn;
303
304 /**
305 * Channel state.
306 */
307 enum CadetChannelState state;
308
309 /**
310 * Is the tunnel bufferless (minimum latency)?
311 */
312 int nobuffer;
313
314 /**
315 * Is the tunnel reliable?
316 */
317 int reliable;
318
319 /**
320 * Is the tunnel out-of-order?
321 */
322 int out_of_order;
323
324 /**
325 * Is this channel a loopback channel, where the destination is us again?
326 */
327 int is_loopback;
328
329 /**
330 * Flag to signal the destruction of the channel. If this is set to
331 * #GNUNET_YES the channel will be destroyed once the queue is
332 * empty.
333 */
334 int destroy;
335
336};
337
338
339/**
340 * Get the static string for identification of the channel.
341 *
342 * @param ch Channel.
343 *
344 * @return Static string with the channel IDs.
345 */
346const char *
347GCCH_2s (const struct CadetChannel *ch)
348{
349 static char buf[128];
350
351 GNUNET_snprintf (buf,
352 sizeof (buf),
353 "Channel %s:%s ctn:%X(%X/%X)",
354 (GNUNET_YES == ch->is_loopback)
355 ? "loopback"
356 : GNUNET_i2s (GCP_get_id (GCT_get_destination (ch->t))),
357 GNUNET_h2s (&ch->port),
358 ch->ctn,
359 (NULL == ch->owner) ? 0 : ntohl (ch->owner->ccn.channel_of_client),
360 (NULL == ch->dest) ? 0 : ntohl (ch->dest->ccn.channel_of_client));
361 return buf;
362}
363
364
365/**
366 * Get the channel's public ID.
367 *
368 * @param ch Channel.
369 *
370 * @return ID used to identify the channel with the remote peer.
371 */
372struct GNUNET_CADET_ChannelTunnelNumber
373GCCH_get_id (const struct CadetChannel *ch)
374{
375 return ch->ctn;
376}
377
378
379/**
380 * Release memory associated with @a ccc
381 *
382 * @param ccc data structure to clean up
383 */
384static void
385free_channel_client (struct CadetChannelClient *ccc)
386{
387 struct CadetOutOfOrderMessage *com;
388
389 while (NULL != (com = ccc->head_recv))
390 {
391 GNUNET_CONTAINER_DLL_remove (ccc->head_recv,
392 ccc->tail_recv,
393 com);
394 GNUNET_MQ_discard (com->env);
395 GNUNET_free (com);
396 }
397 GNUNET_free (ccc);
398}
399
400
401/**
402 * Destroy the given channel.
403 *
404 * @param ch channel to destroy
405 */
406static void
407channel_destroy (struct CadetChannel *ch)
408{
409 struct CadetReliableMessage *crm;
410
411 while (NULL != (crm = ch->head_sent))
412 {
413 GNUNET_assert (ch == crm->ch);
414 if (NULL != crm->qe)
415 {
416 GCT_send_cancel (crm->qe);
417 crm->qe = NULL;
418 }
419 GNUNET_CONTAINER_DLL_remove (ch->head_sent,
420 ch->tail_sent,
421 crm);
422 GNUNET_free (crm->data_message);
423 GNUNET_free (crm);
424 }
425 if (NULL != ch->owner)
426 {
427 free_channel_client (ch->owner);
428 ch->owner = NULL;
429 }
430 if (NULL != ch->dest)
431 {
432 free_channel_client (ch->dest);
433 ch->dest = NULL;
434 }
435 if (NULL != ch->last_control_qe)
436 {
437 GCT_send_cancel (ch->last_control_qe);
438 ch->last_control_qe = NULL;
439 }
440 if (NULL != ch->retry_data_task)
441 {
442 GNUNET_SCHEDULER_cancel (ch->retry_data_task);
443 ch->retry_data_task = NULL;
444 }
445 if (NULL != ch->retry_control_task)
446 {
447 GNUNET_SCHEDULER_cancel (ch->retry_control_task);
448 ch->retry_control_task = NULL;
449 }
450 if (GNUNET_NO == ch->is_loopback)
451 {
452 GCT_remove_channel (ch->t,
453 ch,
454 ch->ctn);
455 ch->t = NULL;
456 }
457 GNUNET_free (ch);
458}
459
460
461/**
462 * Send a channel create message.
463 *
464 * @param cls Channel for which to send.
465 */
466static void
467send_channel_open (void *cls);
468
469
470/**
471 * Function called once the tunnel confirms that we sent the
472 * create message. Delays for a bit until we retry.
473 *
474 * @param cls our `struct CadetChannel`.
475 */
476static void
477channel_open_sent_cb (void *cls)
478{
479 struct CadetChannel *ch = cls;
480
481 GNUNET_assert (NULL != ch->last_control_qe);
482 ch->last_control_qe = NULL;
483 ch->retry_time = GNUNET_TIME_STD_BACKOFF (ch->retry_time);
484 LOG (GNUNET_ERROR_TYPE_DEBUG,
485 "Sent CADET_CHANNEL_OPEN on %s, retrying in %s\n",
486 GCCH_2s (ch),
487 GNUNET_STRINGS_relative_time_to_string (ch->retry_time,
488 GNUNET_YES));
489 ch->retry_control_task
490 = GNUNET_SCHEDULER_add_delayed (ch->retry_time,
491 &send_channel_open,
492 ch);
493}
494
495
496/**
497 * Send a channel open message.
498 *
499 * @param cls Channel for which to send.
500 */
501static void
502send_channel_open (void *cls)
503{
504 struct CadetChannel *ch = cls;
505 struct GNUNET_CADET_ChannelOpenMessage msgcc;
506 uint32_t options;
507
508 ch->retry_control_task = NULL;
509 LOG (GNUNET_ERROR_TYPE_DEBUG,
510 "Sending CHANNEL_OPEN message for %s\n",
511 GCCH_2s (ch));
512 options = 0;
513 if (ch->nobuffer)
514 options |= GNUNET_CADET_OPTION_NOBUFFER;
515 if (ch->reliable)
516 options |= GNUNET_CADET_OPTION_RELIABLE;
517 if (ch->out_of_order)
518 options |= GNUNET_CADET_OPTION_OUT_OF_ORDER;
519 msgcc.header.size = htons (sizeof (msgcc));
520 msgcc.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN);
521 msgcc.opt = htonl (options);
522 msgcc.port = ch->port;
523 msgcc.ctn = ch->ctn;
524 ch->state = CADET_CHANNEL_OPEN_SENT;
525 ch->last_control_qe = GCT_send (ch->t,
526 &msgcc.header,
527 &channel_open_sent_cb,
528 ch);
529}
530
531
532/**
533 * Function called once and only once after a channel was bound
534 * to its tunnel via #GCT_add_channel() is ready for transmission.
535 * Note that this is only the case for channels that this peer
536 * initiates, as for incoming channels we assume that they are
537 * ready for transmission immediately upon receiving the open
538 * message. Used to bootstrap the #GCT_send() process.
539 *
540 * @param ch the channel for which the tunnel is now ready
541 */
542void
543GCCH_tunnel_up (struct CadetChannel *ch)
544{
545 GNUNET_assert (NULL == ch->retry_control_task);
546 LOG (GNUNET_ERROR_TYPE_DEBUG,
547 "Tunnel up, sending CHANNEL_OPEN on %s now\n",
548 GCCH_2s (ch));
549 ch->retry_control_task
550 = GNUNET_SCHEDULER_add_now (&send_channel_open,
551 ch);
552}
553
554
555/**
556 * Create a new channel.
557 *
558 * @param owner local client owning the channel
559 * @param ccn local number of this channel at the @a owner
560 * @param destination peer to which we should build the channel
561 * @param port desired port at @a destination
562 * @param options options for the channel
563 * @return handle to the new channel
564 */
565struct CadetChannel *
566GCCH_channel_local_new (struct CadetClient *owner,
567 struct GNUNET_CADET_ClientChannelNumber ccn,
568 struct CadetPeer *destination,
569 const struct GNUNET_HashCode *port,
570 uint32_t options)
571{
572 struct CadetChannel *ch;
573 struct CadetChannelClient *ccco;
574
575 ccco = GNUNET_new (struct CadetChannelClient);
576 ccco->c = owner;
577 ccco->ccn = ccn;
578 ccco->client_ready = GNUNET_YES;
579
580 ch = GNUNET_new (struct CadetChannel);
581 ch->mid_recv.mid = htonl (1); /* The OPEN_ACK counts as message 0! */
582 ch->nobuffer = (0 != (options & GNUNET_CADET_OPTION_NOBUFFER));
583 ch->reliable = (0 != (options & GNUNET_CADET_OPTION_RELIABLE));
584 ch->out_of_order = (0 != (options & GNUNET_CADET_OPTION_OUT_OF_ORDER));
585 ch->max_pending_messages = (ch->nobuffer) ? 1 : 4; /* FIXME: 4!? Do not hardcode! */
586 ch->owner = ccco;
587 ch->port = *port;
588 if (0 == memcmp (&my_full_id,
589 GCP_get_id (destination),
590 sizeof (struct GNUNET_PeerIdentity)))
591 {
592 struct CadetClient *c;
593
594 ch->is_loopback = GNUNET_YES;
595 c = GNUNET_CONTAINER_multihashmap_get (open_ports,
596 port);
597 if (NULL == c)
598 {
599 /* port closed, wait for it to possibly open */
600 (void) GNUNET_CONTAINER_multihashmap_put (loose_channels,
601 port,
602 ch,
603 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
604 LOG (GNUNET_ERROR_TYPE_DEBUG,
605 "Created loose incoming loopback channel to port %s\n",
606 GNUNET_h2s (&ch->port));
607 }
608 else
609 {
610 ch->dest = GNUNET_new (struct CadetChannelClient);
611 ch->dest->c = c;
612 ch->dest->client_ready = GNUNET_YES;
613 GCCH_bind (ch,
614 ch->dest->c);
615 }
616 }
617 else
618 {
619 ch->t = GCP_get_tunnel (destination,
620 GNUNET_YES);
621 ch->retry_time = CADET_INITIAL_RETRANSMIT_TIME;
622 ch->ctn = GCT_add_channel (ch->t,
623 ch);
624 }
625 GNUNET_STATISTICS_update (stats,
626 "# channels",
627 1,
628 GNUNET_NO);
629 LOG (GNUNET_ERROR_TYPE_DEBUG,
630 "Created channel to port %s at peer %s for %s using %s\n",
631 GNUNET_h2s (port),
632 GCP_2s (destination),
633 GSC_2s (owner),
634 (GNUNET_YES == ch->is_loopback) ? "loopback" : GCT_2s (ch->t));
635 return ch;
636}
637
638
639/**
640 * We had an incoming channel to a port that is closed.
641 * It has not been opened for a while, drop it.
642 *
643 * @param cls the channel to drop
644 */
645static void
646timeout_closed_cb (void *cls)
647{
648 struct CadetChannel *ch = cls;
649
650 ch->retry_control_task = NULL;
651 LOG (GNUNET_ERROR_TYPE_DEBUG,
652 "Closing incoming channel to port %s from peer %s due to timeout\n",
653 GNUNET_h2s (&ch->port),
654 GCP_2s (GCT_get_destination (ch->t)));
655 channel_destroy (ch);
656}
657
658
659/**
660 * Create a new channel based on a request coming in over the network.
661 *
662 * @param t tunnel to the remote peer
663 * @param ctn identifier of this channel in the tunnel
664 * @param port desired local port
665 * @param options options for the channel
666 * @return handle to the new channel
667 */
668struct CadetChannel *
669GCCH_channel_incoming_new (struct CadetTunnel *t,
670 struct GNUNET_CADET_ChannelTunnelNumber ctn,
671 const struct GNUNET_HashCode *port,
672 uint32_t options)
673{
674 struct CadetChannel *ch;
675 struct CadetClient *c;
676
677 ch = GNUNET_new (struct CadetChannel);
678 ch->port = *port;
679 ch->t = t;
680 ch->ctn = ctn;
681 ch->retry_time = CADET_INITIAL_RETRANSMIT_TIME;
682 ch->nobuffer = (0 != (options & GNUNET_CADET_OPTION_NOBUFFER));
683 ch->reliable = (0 != (options & GNUNET_CADET_OPTION_RELIABLE));
684 ch->out_of_order = (0 != (options & GNUNET_CADET_OPTION_OUT_OF_ORDER));
685 ch->max_pending_messages = (ch->nobuffer) ? 1 : 4; /* FIXME: 4!? Do not hardcode! */
686 GNUNET_STATISTICS_update (stats,
687 "# channels",
688 1,
689 GNUNET_NO);
690
691 c = GNUNET_CONTAINER_multihashmap_get (open_ports,
692 port);
693 if (NULL == c)
694 {
695 /* port closed, wait for it to possibly open */
696 (void) GNUNET_CONTAINER_multihashmap_put (loose_channels,
697 port,
698 ch,
699 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
700 ch->retry_control_task
701 = GNUNET_SCHEDULER_add_delayed (TIMEOUT_CLOSED_PORT,
702 &timeout_closed_cb,
703 ch);
704 LOG (GNUNET_ERROR_TYPE_DEBUG,
705 "Created loose incoming channel to port %s from peer %s\n",
706 GNUNET_h2s (&ch->port),
707 GCP_2s (GCT_get_destination (ch->t)));
708 }
709 else
710 {
711 GCCH_bind (ch,
712 c);
713 }
714 GNUNET_STATISTICS_update (stats,
715 "# channels",
716 1,
717 GNUNET_NO);
718 return ch;
719}
720
721
722/**
723 * Function called once the tunnel confirms that we sent the
724 * ACK message. Just remembers it was sent, we do not expect
725 * ACKs for ACKs ;-).
726 *
727 * @param cls our `struct CadetChannel`.
728 */
729static void
730send_ack_cb (void *cls)
731{
732 struct CadetChannel *ch = cls;
733
734 GNUNET_assert (NULL != ch->last_control_qe);
735 ch->last_control_qe = NULL;
736}
737
738
739/**
740 * Compute and send the current #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK to the other peer.
741 *
742 * @param ch channel to send the #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK for
743 */
744static void
745send_channel_data_ack (struct CadetChannel *ch)
746{
747 struct GNUNET_CADET_ChannelDataAckMessage msg;
748
749 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK);
750 msg.header.size = htons (sizeof (msg));
751 msg.ctn = ch->ctn;
752 msg.mid.mid = htonl (ntohl (ch->mid_recv.mid) - 1);
753 msg.futures = GNUNET_htonll (ch->mid_futures);
754 if (NULL != ch->last_control_qe)
755 GCT_send_cancel (ch->last_control_qe);
756 ch->last_control_qe = GCT_send (ch->t,
757 &msg.header,
758 &send_ack_cb,
759 ch);
760}
761
762
763/**
764 * Send our initial #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK to the client confirming that the
765 * connection is up.
766 *
767 * @param cls the `struct CadetChannel`
768 */
769static void
770send_open_ack (void *cls)
771{
772 struct CadetChannel *ch = cls;
773 struct GNUNET_CADET_ChannelManageMessage msg;
774
775 LOG (GNUNET_ERROR_TYPE_DEBUG,
776 "Sending CHANNEL_OPEN_ACK on %s\n",
777 GCCH_2s (ch));
778 ch->retry_control_task = NULL;
779 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK);
780 msg.header.size = htons (sizeof (msg));
781 msg.reserved = htonl (0);
782 msg.ctn = ch->ctn;
783 if (NULL != ch->last_control_qe)
784 GCT_send_cancel (ch->last_control_qe);
785 ch->last_control_qe = GCT_send (ch->t,
786 &msg.header,
787 &send_ack_cb,
788 ch);
789}
790
791
792/**
793 * We got a #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN message again for
794 * this channel. If the binding was successful, (re)transmit the
795 * #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK.
796 *
797 * @param ch channel that got the duplicate open
798 */
799void
800GCCH_handle_duplicate_open (struct CadetChannel *ch)
801{
802 if (NULL == ch->dest)
803 {
804 LOG (GNUNET_ERROR_TYPE_DEBUG,
805 "Ignoring duplicate channel OPEN on %s: port is closed\n",
806 GCCH_2s (ch));
807 return;
808 }
809 if (NULL != ch->retry_control_task)
810 {
811 LOG (GNUNET_ERROR_TYPE_DEBUG,
812 "Ignoring duplicate channel OPEN on %s: control message is pending\n",
813 GCCH_2s (ch));
814 return;
815 }
816 LOG (GNUNET_ERROR_TYPE_DEBUG,
817 "Retransmitting OPEN_ACK on %s\n",
818 GCCH_2s (ch));
819 ch->retry_control_task
820 = GNUNET_SCHEDULER_add_now (&send_open_ack,
821 ch);
822}
823
824
825/**
826 * Send a #GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK to the client to solicit more messages.
827 *
828 * @param ch channel the ack is for
829 * @param to_owner #GNUNET_YES to send to owner,
830 * #GNUNET_NO to send to dest
831 */
832static void
833send_ack_to_client (struct CadetChannel *ch,
834 int to_owner)
835{
836 struct GNUNET_MQ_Envelope *env;
837 struct GNUNET_CADET_LocalAck *ack;
838 struct CadetChannelClient *ccc;
839
840 env = GNUNET_MQ_msg (ack,
841 GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK);
842 ccc = (GNUNET_YES == to_owner) ? ch->owner : ch->dest;
843 ack->ccn = ccc->ccn;
844 LOG (GNUNET_ERROR_TYPE_DEBUG,
845 "Sending CADET_LOCAL_ACK to %s (%s) at ccn %X\n",
846 GSC_2s (ccc->c),
847 (GNUNET_YES == to_owner) ? "owner" : "dest",
848 ntohl (ack->ccn.channel_of_client));
849 GSC_send_to_client (ccc->c,
850 env);
851}
852
853
854/**
855 * A client is bound to the port that we have a channel
856 * open to. Send the acknowledgement for the connection
857 * request and establish the link with the client.
858 *
859 * @param ch open incoming channel
860 * @param c client listening on the respective port
861 */
862void
863GCCH_bind (struct CadetChannel *ch,
864 struct CadetClient *c)
865{
866 uint32_t options;
867 struct CadetChannelClient *cccd;
868
869 LOG (GNUNET_ERROR_TYPE_DEBUG,
870 "Binding %s from %s to port %s of %s\n",
871 GCCH_2s (ch),
872 GCT_2s (ch->t),
873 GNUNET_h2s (&ch->port),
874 GSC_2s (c));
875 if (NULL != ch->retry_control_task)
876 {
877 /* there might be a timeout task here */
878 GNUNET_SCHEDULER_cancel (ch->retry_control_task);
879 ch->retry_control_task = NULL;
880 }
881 options = 0;
882 if (ch->nobuffer)
883 options |= GNUNET_CADET_OPTION_NOBUFFER;
884 if (ch->reliable)
885 options |= GNUNET_CADET_OPTION_RELIABLE;
886 if (ch->out_of_order)
887 options |= GNUNET_CADET_OPTION_OUT_OF_ORDER;
888 cccd = GNUNET_new (struct CadetChannelClient);
889 ch->dest = cccd;
890 cccd->c = c;
891 cccd->client_ready = GNUNET_YES;
892 cccd->ccn = GSC_bind (c,
893 ch,
894 (GNUNET_YES == ch->is_loopback)
895 ? GCP_get (&my_full_id,
896 GNUNET_YES)
897 : GCT_get_destination (ch->t),
898 &ch->port,
899 options);
900 GNUNET_assert (ntohl (cccd->ccn.channel_of_client) <
901 GNUNET_CADET_LOCAL_CHANNEL_ID_CLI);
902 ch->mid_recv.mid = htonl (1); /* The OPEN counts as message 0! */
903 if (GNUNET_YES == ch->is_loopback)
904 {
905 ch->state = CADET_CHANNEL_OPEN_SENT;
906 GCCH_handle_channel_open_ack (ch);
907 }
908 else
909 {
910 /* notify other peer that we accepted the connection */
911 ch->retry_control_task
912 = GNUNET_SCHEDULER_add_now (&send_open_ack,
913 ch);
914 }
915 /* give client it's initial supply of ACKs */
916 GNUNET_assert (ntohl (cccd->ccn.channel_of_client) <
917 GNUNET_CADET_LOCAL_CHANNEL_ID_CLI);
918 for (unsigned int i=0;i<ch->max_pending_messages;i++)
919 send_ack_to_client (ch,
920 GNUNET_NO);
921}
922
923
924/**
925 * Destroy locally created channel. Called by the local client, so no
926 * need to tell the client.
927 *
928 * @param ch channel to destroy
929 * @param c client that caused the destruction
930 * @param ccn client number of the client @a c
931 */
932void
933GCCH_channel_local_destroy (struct CadetChannel *ch,
934 struct CadetClient *c,
935 struct GNUNET_CADET_ClientChannelNumber ccn)
936{
937 LOG (GNUNET_ERROR_TYPE_DEBUG,
938 "%s asks for destruction of %s\n",
939 GSC_2s (c),
940 GCCH_2s (ch));
941 GNUNET_assert (NULL != c);
942 if ( (NULL != ch->owner) &&
943 (c == ch->owner->c) &&
944 (ccn.channel_of_client == ch->owner->ccn.channel_of_client) )
945 {
946 free_channel_client (ch->owner);
947 ch->owner = NULL;
948 }
949 else if ( (NULL != ch->dest) &&
950 (c == ch->dest->c) &&
951 (ccn.channel_of_client == ch->dest->ccn.channel_of_client) )
952 {
953 free_channel_client (ch->dest);
954 ch->dest = NULL;
955 }
956 else
957 {
958 GNUNET_assert (0);
959 }
960
961 if (GNUNET_YES == ch->destroy)
962 {
963 /* other end already destroyed, with the local client gone, no need
964 to finish transmissions, just destroy immediately. */
965 channel_destroy (ch);
966 return;
967 }
968 if ( (NULL != ch->head_sent) ||
969 (NULL != ch->owner) ||
970 (NULL != ch->dest) )
971 {
972 /* Wait for other end to destroy us as well,
973 and otherwise allow send queue to be transmitted first */
974 ch->destroy = GNUNET_YES;
975 return;
976 }
977 /* If the we ever sent the CHANNEL_CREATE, we need to send a destroy message. */
978 if (CADET_CHANNEL_NEW != ch->state)
979 GCT_send_channel_destroy (ch->t,
980 ch->ctn);
981 /* Nothing left to do, just finish destruction */
982 channel_destroy (ch);
983}
984
985
986/**
987 * We got an acknowledgement for the creation of the channel
988 * (the port is open on the other side). Begin transmissions.
989 *
990 * @param ch channel to destroy
991 */
992void
993GCCH_handle_channel_open_ack (struct CadetChannel *ch)
994{
995 switch (ch->state)
996 {
997 case CADET_CHANNEL_NEW:
998 /* this should be impossible */
999 GNUNET_break (0);
1000 break;
1001 case CADET_CHANNEL_OPEN_SENT:
1002 if (NULL == ch->owner)
1003 {
1004 /* We're not the owner, wrong direction! */
1005 GNUNET_break_op (0);
1006 return;
1007 }
1008 LOG (GNUNET_ERROR_TYPE_DEBUG,
1009 "Received CHANNEL_OPEN_ACK for waiting %s, entering READY state\n",
1010 GCCH_2s (ch));
1011 if (NULL != ch->retry_control_task) /* can be NULL if ch->is_loopback */
1012 {
1013 GNUNET_SCHEDULER_cancel (ch->retry_control_task);
1014 ch->retry_control_task = NULL;
1015 }
1016 ch->state = CADET_CHANNEL_READY;
1017 /* On first connect, send client as many ACKs as we allow messages
1018 to be buffered! */
1019 for (unsigned int i=0;i<ch->max_pending_messages;i++)
1020 send_ack_to_client (ch,
1021 GNUNET_YES);
1022 break;
1023 case CADET_CHANNEL_READY:
1024 /* duplicate ACK, maybe we retried the CREATE. Ignore. */
1025 LOG (GNUNET_ERROR_TYPE_DEBUG,
1026 "Received duplicate channel OPEN_ACK for %s\n",
1027 GCCH_2s (ch));
1028 GNUNET_STATISTICS_update (stats,
1029 "# duplicate CREATE_ACKs",
1030 1,
1031 GNUNET_NO);
1032 break;
1033 }
1034}
1035
1036
1037/**
1038 * Test if element @a e1 comes before element @a e2.
1039 *
1040 * TODO: use opportunity to create generic list insertion sort
1041 * logic in container!
1042 *
1043 * @param cls closure, our `struct CadetChannel`
1044 * @param e1 an element of to sort
1045 * @param e2 another element to sort
1046 * @return #GNUNET_YES if @e1 < @e2, otherwise #GNUNET_NO
1047 */
1048static int
1049is_before (void *cls,
1050 void *e1,
1051 void *e2)
1052{
1053 struct CadetOutOfOrderMessage *m1 = e1;
1054 struct CadetOutOfOrderMessage *m2 = e2;
1055 uint32_t v1 = ntohl (m1->mid.mid);
1056 uint32_t v2 = ntohl (m2->mid.mid);
1057 uint32_t delta;
1058
1059 delta = v1 - v2;
1060 if (delta > (uint32_t) INT_MAX)
1061 {
1062 /* in overflow range, we can safely assume we wrapped around */
1063 return GNUNET_NO;
1064 }
1065 else
1066 {
1067 return GNUNET_YES;
1068 }
1069}
1070
1071
1072/**
1073 * We got payload data for a channel. Pass it on to the client
1074 * and send an ACK to the other end (once flow control allows it!)
1075 *
1076 * @param ch channel that got data
1077 * @param msg message that was received
1078 */
1079void
1080GCCH_handle_channel_plaintext_data (struct CadetChannel *ch,
1081 const struct GNUNET_CADET_ChannelAppDataMessage *msg)
1082{
1083 struct GNUNET_MQ_Envelope *env;
1084 struct GNUNET_CADET_LocalData *ld;
1085 struct CadetChannelClient *ccc;
1086 struct CadetOutOfOrderMessage *com;
1087 size_t payload_size;
1088
1089 GNUNET_assert (GNUNET_NO == ch->is_loopback);
1090 if ( (GNUNET_YES == ch->destroy) &&
1091 (NULL == ch->owner) &&
1092 (NULL == ch->dest) )
1093 {
1094 /* This client is gone, but we still have messages to send to
1095 the other end (which is why @a ch is not yet dead). However,
1096 we cannot pass messages to our client anymore. */
1097 LOG (GNUNET_ERROR_TYPE_DEBUG,
1098 "Dropping incoming payload on %s as this end is already closed\n",
1099 GCCH_2s (ch));
1100 /* FIXME: send back ACK/NACK/Closed notification
1101 to stop retransmissions! */
1102 return;
1103 }
1104 payload_size = ntohs (msg->header.size) - sizeof (*msg);
1105 env = GNUNET_MQ_msg_extra (ld,
1106 payload_size,
1107 GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA);
1108 ld->ccn = (NULL == ch->dest) ? ch->owner->ccn : ch->dest->ccn;
1109 GNUNET_memcpy (&ld[1],
1110 &msg[1],
1111 payload_size);
1112 ccc = (NULL != ch->owner) ? ch->owner : ch->dest;
1113 if ( (GNUNET_YES == ccc->client_ready) &&
1114 ( (GNUNET_YES == ch->out_of_order) ||
1115 (msg->mid.mid == ch->mid_recv.mid) ) )
1116 {
1117 LOG (GNUNET_ERROR_TYPE_DEBUG,
1118 "Giving %u bytes of payload from %s to client %s\n",
1119 (unsigned int) payload_size,
1120 GCCH_2s (ch),
1121 GSC_2s (ccc->c));
1122 ccc->client_ready = GNUNET_NO;
1123 GSC_send_to_client (ccc->c,
1124 env);
1125 ch->mid_recv.mid = htonl (1 + ntohl (ch->mid_recv.mid));
1126 ch->mid_futures >>= 1;
1127 }
1128 else
1129 {
1130 /* FIXME-SECURITY: if the element is WAY too far ahead,
1131 drop it (can't buffer too much!) */
1132 LOG (GNUNET_ERROR_TYPE_DEBUG,
1133 "Queuing %s payload of %u bytes on %s (mid %u, need %u first)\n",
1134 (GNUNET_YES == ccc->client_ready)
1135 ? "out-of-order"
1136 : "client-not-ready",
1137 (unsigned int) payload_size,
1138 GCCH_2s (ch),
1139 ntohl (msg->mid.mid),
1140 ntohl (ch->mid_recv.mid));
1141
1142 com = GNUNET_new (struct CadetOutOfOrderMessage);
1143 com->mid = msg->mid;
1144 com->env = env;
1145 /* sort into list ordered by "is_before" */
1146 if ( (NULL == ccc->head_recv) ||
1147 (GNUNET_YES == is_before (ch,
1148 com,
1149 ccc->head_recv)) )
1150 {
1151 GNUNET_CONTAINER_DLL_insert (ccc->head_recv,
1152 ccc->tail_recv,
1153 com);
1154 }
1155 else
1156 {
1157 struct CadetOutOfOrderMessage *pos;
1158
1159 for (pos = ccc->head_recv;
1160 NULL != pos;
1161 pos = pos->next)
1162 {
1163 if (GNUNET_YES !=
1164 is_before (NULL,
1165 pos,
1166 com))
1167 break;
1168 }
1169 if (NULL == pos)
1170 GNUNET_CONTAINER_DLL_insert_tail (ccc->head_recv,
1171 ccc->tail_recv,
1172 com);
1173 else
1174 GNUNET_CONTAINER_DLL_insert_after (ccc->head_recv,
1175 ccc->tail_recv,
1176 com,
1177 pos->prev);
1178 }
1179 }
1180}
1181
1182
1183/**
1184 * We got an acknowledgement for payload data for a channel.
1185 * Possibly resume transmissions.
1186 *
1187 * @param ch channel that got the ack
1188 * @param ack details about what was received
1189 */
1190void
1191GCCH_handle_channel_plaintext_data_ack (struct CadetChannel *ch,
1192 const struct GNUNET_CADET_ChannelDataAckMessage *ack)
1193{
1194 struct CadetReliableMessage *crm;
1195
1196 GNUNET_break (GNUNET_NO == ch->is_loopback);
1197 if (GNUNET_NO == ch->reliable)
1198 {
1199 /* not expecting ACKs on unreliable channel, odd */
1200 GNUNET_break_op (0);
1201 return;
1202 }
1203 for (crm = ch->head_sent;
1204 NULL != crm;
1205 crm = crm->next)
1206 if (ack->mid.mid == crm->data_message->mid.mid)
1207 break;
1208 if (NULL == crm)
1209 {
1210 /* ACK for message we already dropped, might have been a
1211 duplicate ACK? Ignore. */
1212 LOG (GNUNET_ERROR_TYPE_DEBUG,
1213 "Duplicate DATA_ACK on %s, ignoring\n",
1214 GCCH_2s (ch));
1215 GNUNET_STATISTICS_update (stats,
1216 "# duplicate DATA_ACKs",
1217 1,
1218 GNUNET_NO);
1219 return;
1220 }
1221 GNUNET_CONTAINER_DLL_remove (ch->head_sent,
1222 ch->tail_sent,
1223 crm);
1224 GNUNET_free (crm->data_message);
1225 GNUNET_free (crm);
1226 ch->pending_messages--;
1227 send_ack_to_client (ch,
1228 (NULL == ch->owner)
1229 ? GNUNET_NO
1230 : GNUNET_YES);
1231 GNUNET_assert (ch->pending_messages < ch->max_pending_messages);
1232 LOG (GNUNET_ERROR_TYPE_DEBUG,
1233 "Received DATA_ACK on %s for message %u (%u ACKs pending)\n",
1234 GCCH_2s (ch),
1235 (unsigned int) ntohl (ack->mid.mid),
1236 ch->pending_messages);
1237 send_ack_to_client (ch,
1238 (NULL == ch->owner)
1239 ? GNUNET_NO
1240 : GNUNET_YES);
1241}
1242
1243
1244/**
1245 * Destroy channel, based on the other peer closing the
1246 * connection. Also needs to remove this channel from
1247 * the tunnel.
1248 *
1249 * @param ch channel to destroy
1250 */
1251void
1252GCCH_handle_remote_destroy (struct CadetChannel *ch)
1253{
1254 struct CadetChannelClient *ccc;
1255
1256 GNUNET_assert (GNUNET_NO == ch->is_loopback);
1257 LOG (GNUNET_ERROR_TYPE_DEBUG,
1258 "Received remote channel DESTROY for %s\n",
1259 GCCH_2s (ch));
1260 if (GNUNET_YES == ch->destroy)
1261 {
1262 /* Local client already gone, this is instant-death. */
1263 channel_destroy (ch);
1264 return;
1265 }
1266 ccc = (NULL != ch->owner) ? ch->owner : ch->dest;
1267 if (NULL != ccc->head_recv)
1268 {
1269 LOG (GNUNET_ERROR_TYPE_WARNING,
1270 "Lost end of transmission due to remote shutdown on %s\n",
1271 GCCH_2s (ch));
1272 /* FIXME: change API to notify client about truncated transmission! */
1273 }
1274 ch->destroy = GNUNET_YES;
1275 GSC_handle_remote_channel_destroy (ccc->c,
1276 ccc->ccn,
1277 ch);
1278 channel_destroy (ch);
1279}
1280
1281
1282/**
1283 * Function called once the tunnel has sent one of our messages.
1284 * If the message is unreliable, simply frees the `crm`. If the
1285 * message was reliable, calculate retransmission time and
1286 * wait for ACK (or retransmit).
1287 *
1288 * @param cls the `struct CadetReliableMessage` that was sent
1289 */
1290static void
1291data_sent_cb (void *cls);
1292
1293
1294/**
1295 * We need to retry a transmission, the last one took too long to
1296 * be acknowledged.
1297 *
1298 * @param cls the `struct CadetChannel` where we need to retransmit
1299 */
1300static void
1301retry_transmission (void *cls)
1302{
1303 struct CadetChannel *ch = cls;
1304 struct CadetReliableMessage *crm = ch->head_sent;
1305
1306 ch->retry_data_task = NULL;
1307 GNUNET_assert (NULL == crm->qe);
1308 crm->qe = GCT_send (ch->t,
1309 &crm->data_message->header,
1310 &data_sent_cb,
1311 crm);
1312}
1313
1314
1315/**
1316 * Function called once the tunnel has sent one of our messages.
1317 * If the message is unreliable, simply frees the `crm`. If the
1318 * message was reliable, calculate retransmission time and
1319 * wait for ACK (or retransmit).
1320 *
1321 * @param cls the `struct CadetReliableMessage` that was sent
1322 */
1323static void
1324data_sent_cb (void *cls)
1325{
1326 struct CadetReliableMessage *crm = cls;
1327 struct CadetChannel *ch = crm->ch;
1328 struct CadetReliableMessage *off;
1329
1330 GNUNET_assert (GNUNET_NO == ch->is_loopback);
1331 crm->qe = NULL;
1332 GNUNET_CONTAINER_DLL_remove (ch->head_sent,
1333 ch->tail_sent,
1334 crm);
1335 if (GNUNET_NO == ch->reliable)
1336 {
1337 GNUNET_free (crm);
1338 ch->pending_messages--;
1339 send_ack_to_client (ch,
1340 (NULL == ch->owner)
1341 ? GNUNET_NO
1342 : GNUNET_YES);
1343 return;
1344 }
1345 if (0 == crm->retry_delay.rel_value_us)
1346 crm->retry_delay = ch->expected_delay;
1347 crm->next_retry = GNUNET_TIME_relative_to_absolute (crm->retry_delay);
1348
1349 /* find position for re-insertion into the DLL */
1350 if ( (NULL == ch->head_sent) ||
1351 (crm->next_retry.abs_value_us < ch->head_sent->next_retry.abs_value_us) )
1352 {
1353 /* insert at HEAD, also (re)schedule retry task! */
1354 GNUNET_CONTAINER_DLL_insert (ch->head_sent,
1355 ch->tail_sent,
1356 crm);
1357 if (NULL != ch->retry_data_task)
1358 GNUNET_SCHEDULER_cancel (ch->retry_data_task);
1359 ch->retry_data_task
1360 = GNUNET_SCHEDULER_add_delayed (crm->retry_delay,
1361 &retry_transmission,
1362 ch);
1363 return;
1364 }
1365 for (off = ch->head_sent; NULL != off; off = off->next)
1366 if (crm->next_retry.abs_value_us < off->next_retry.abs_value_us)
1367 break;
1368 if (NULL == off)
1369 {
1370 /* insert at tail */
1371 GNUNET_CONTAINER_DLL_insert_tail (ch->head_sent,
1372 ch->tail_sent,
1373 crm);
1374 }
1375 else
1376 {
1377 /* insert before off */
1378 GNUNET_CONTAINER_DLL_insert_after (ch->head_sent,
1379 ch->tail_sent,
1380 off->prev,
1381 crm);
1382 }
1383}
1384
1385
1386/**
1387 * Handle data given by a client.
1388 *
1389 * Check whether the client is allowed to send in this tunnel, save if
1390 * channel is reliable and send an ACK to the client if there is still
1391 * buffer space in the tunnel.
1392 *
1393 * @param ch Channel.
1394 * @param sender_ccn ccn of the sender
1395 * @param buf payload to transmit.
1396 * @param buf_len number of bytes in @a buf
1397 * @return #GNUNET_OK if everything goes well,
1398 * #GNUNET_SYSERR in case of an error.
1399 */
1400int
1401GCCH_handle_local_data (struct CadetChannel *ch,
1402 struct GNUNET_CADET_ClientChannelNumber sender_ccn,
1403 const char *buf,
1404 size_t buf_len)
1405{
1406 struct CadetReliableMessage *crm;
1407
1408 if (ch->pending_messages > ch->max_pending_messages)
1409 {
1410 GNUNET_break (0);
1411 return GNUNET_SYSERR;
1412 }
1413 ch->pending_messages++;
1414
1415 if (GNUNET_YES == ch->is_loopback)
1416 {
1417 struct CadetChannelClient *receiver;
1418 struct GNUNET_MQ_Envelope *env;
1419 struct GNUNET_CADET_LocalData *ld;
1420 int to_owner;
1421
1422 env = GNUNET_MQ_msg_extra (ld,
1423 buf_len,
1424 GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA);
1425 if (sender_ccn.channel_of_client ==
1426 ch->owner->ccn.channel_of_client)
1427 {
1428 receiver = ch->dest;
1429 to_owner = GNUNET_NO;
1430 }
1431 else
1432 {
1433 GNUNET_assert (sender_ccn.channel_of_client ==
1434 ch->dest->ccn.channel_of_client);
1435 receiver = ch->owner;
1436 to_owner = GNUNET_YES;
1437 }
1438 ld->ccn = receiver->ccn;
1439 GNUNET_memcpy (&ld[1],
1440 buf,
1441 buf_len);
1442 /* FIXME: this does not provide for flow control! */
1443 GSC_send_to_client (receiver->c,
1444 env);
1445 send_ack_to_client (ch,
1446 to_owner);
1447 return GNUNET_OK;
1448 }
1449
1450 /* Everything is correct, send the message. */
1451 crm = GNUNET_malloc (sizeof (*crm));
1452 crm->ch = ch;
1453 crm->data_message = GNUNET_malloc (sizeof (struct GNUNET_CADET_ChannelAppDataMessage)
1454 + buf_len);
1455 crm->data_message->header.size = htons (sizeof (struct GNUNET_CADET_ChannelAppDataMessage) + buf_len);
1456 crm->data_message->header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA);
1457 ch->mid_send.mid = htonl (ntohl (ch->mid_send.mid) + 1);
1458 crm->data_message->mid = ch->mid_send;
1459 crm->data_message->ctn = ch->ctn;
1460 GNUNET_memcpy (&crm->data_message[1],
1461 buf,
1462 buf_len);
1463 GNUNET_CONTAINER_DLL_insert (ch->head_sent,
1464 ch->tail_sent,
1465 crm);
1466 LOG (GNUNET_ERROR_TYPE_DEBUG,
1467 "Sending %u bytes from local client to %s\n",
1468 buf_len,
1469 GCCH_2s (ch));
1470 crm->qe = GCT_send (ch->t,
1471 &crm->data_message->header,
1472 &data_sent_cb,
1473 crm);
1474 return GNUNET_OK;
1475}
1476
1477
1478/**
1479 * Handle ACK from client on local channel. Means the client is ready
1480 * for more data, see if we have any for it.
1481 *
1482 * @param ch channel to destroy
1483 * @param client_ccn ccn of the client sending the ack
1484 */
1485void
1486GCCH_handle_local_ack (struct CadetChannel *ch,
1487 struct GNUNET_CADET_ClientChannelNumber client_ccn)
1488{
1489 struct CadetChannelClient *ccc;
1490 struct CadetOutOfOrderMessage *com;
1491
1492 if ( (NULL != ch->owner) &&
1493 (ch->owner->ccn.channel_of_client == client_ccn.channel_of_client) )
1494 ccc = ch->owner;
1495 else if ( (NULL != ch->dest) &&
1496 (ch->dest->ccn.channel_of_client == client_ccn.channel_of_client) )
1497 ccc = ch->dest;
1498 else
1499 GNUNET_assert (0);
1500 ccc->client_ready = GNUNET_YES;
1501 com = ccc->head_recv;
1502 if (NULL == com)
1503 {
1504 LOG (GNUNET_ERROR_TYPE_DEBUG,
1505 "Got LOCAL_ACK, %s-%X ready to receive more data (but none pending)!\n",
1506 GSC_2s (ccc->c),
1507 ntohl (ccc->ccn.channel_of_client));
1508 return; /* none pending */
1509 }
1510 if ( (com->mid.mid != ch->mid_recv.mid) &&
1511 (GNUNET_NO == ch->out_of_order) )
1512 return; /* missing next one in-order */
1513
1514 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1515 "Got LOCAL ACK, passing payload message to %s-%X on %s\n",
1516 GSC_2s (ccc->c),
1517 ntohl (ccc->ccn.channel_of_client),
1518 GCCH_2s (ch));
1519
1520 /* all good, pass next message to client */
1521 GNUNET_CONTAINER_DLL_remove (ccc->head_recv,
1522 ccc->tail_recv,
1523 com);
1524 /* FIXME: if unreliable, this is not aggressive
1525 enough, as it would be OK to have lost some! */
1526 ch->mid_recv.mid = htonl (1 + ntohl (com->mid.mid));
1527 ch->mid_futures >>= 1; /* equivalent to division by 2 */
1528 ccc->client_ready = GNUNET_NO;
1529 GSC_send_to_client (ccc->c,
1530 com->env);
1531 GNUNET_free (com);
1532 if ( (0xFFULL == (ch->mid_futures & 0xFFULL)) &&
1533 (GNUNET_YES == ch->reliable) )
1534 {
1535 /* The next 15 messages were also already received (0xFF), this
1536 suggests that the sender may be blocked on flow control
1537 urgently waiting for an ACK from us. (As we have an inherent
1538 maximum of 64 bits, and 15 is getting too close for comfort.)
1539 So we should send one now. */
1540 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1541 "Sender on %s likely blocked on flow-control, sending ACK now.\n",
1542 GCCH_2s (ch));
1543 if (GNUNET_YES == ch->reliable)
1544 send_channel_data_ack (ch);
1545 }
1546
1547 if (NULL != ccc->head_recv)
1548 return;
1549 if (GNUNET_NO == ch->destroy)
1550 return;
1551 GCT_send_channel_destroy (ch->t,
1552 ch->ctn);
1553 channel_destroy (ch);
1554}
1555
1556
1557#define LOG2(level, ...) GNUNET_log_from_nocheck(level,"cadet-chn",__VA_ARGS__)
1558
1559
1560/**
1561 * Log channel info.
1562 *
1563 * @param ch Channel.
1564 * @param level Debug level to use.
1565 */
1566void
1567GCCH_debug (struct CadetChannel *ch,
1568 enum GNUNET_ErrorType level)
1569{
1570 int do_log;
1571
1572 do_log = GNUNET_get_log_call_status (level & (~GNUNET_ERROR_TYPE_BULK),
1573 "cadet-chn",
1574 __FILE__, __FUNCTION__, __LINE__);
1575 if (0 == do_log)
1576 return;
1577
1578 if (NULL == ch)
1579 {
1580 LOG2 (level, "CHN *** DEBUG NULL CHANNEL ***\n");
1581 return;
1582 }
1583 LOG2 (level,
1584 "CHN %s:%X (%p)\n",
1585 GCT_2s (ch->t),
1586 ch->ctn,
1587 ch);
1588 if (NULL != ch->owner)
1589 {
1590 LOG2 (level,
1591 "CHN origin %s ready %s local-id: %u\n",
1592 GSC_2s (ch->owner->c),
1593 ch->owner->client_ready ? "YES" : "NO",
1594 ntohl (ch->owner->ccn.channel_of_client));
1595 }
1596 if (NULL != ch->dest)
1597 {
1598 LOG2 (level,
1599 "CHN destination %s ready %s local-id: %u\n",
1600 GSC_2s (ch->dest->c),
1601 ch->dest->client_ready ? "YES" : "NO",
1602 ntohl (ch->dest->ccn.channel_of_client));
1603 }
1604 LOG2 (level,
1605 "CHN Message IDs recv: %d (%LLX), send: %d\n",
1606 ntohl (ch->mid_recv.mid),
1607 (unsigned long long) ch->mid_futures,
1608 ntohl (ch->mid_send.mid));
1609}
1610
1611
1612
1613/* end of gnunet-service-cadet-new_channel.c */
diff --git a/src/cadet/gnunet-service-cadet-new_channel.h b/src/cadet/gnunet-service-cadet-new_channel.h
deleted file mode 100644
index e572b7633..000000000
--- a/src/cadet/gnunet-service-cadet-new_channel.h
+++ /dev/null
@@ -1,249 +0,0 @@
1
2/*
3 This file is part of GNUnet.
4 Copyright (C) 2001-2017 GNUnet e.V.
5
6 GNUnet is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published
8 by the Free Software Foundation; either version 3, or (at your
9 option) any later version.
10
11 GNUnet is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNUnet; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
20*/
21
22/**
23 * @file cadet/gnunet-service-cadet-new_channel.h
24 * @brief GNUnet CADET service with encryption
25 * @author Bartlomiej Polot
26 * @author Christian Grothoff
27 */
28#ifndef GNUNET_SERVICE_CADET_CHANNEL_H
29#define GNUNET_SERVICE_CADET_CHANNEL_H
30
31#include "gnunet-service-cadet-new.h"
32#include "gnunet-service-cadet-new_peer.h"
33#include "cadet_protocol.h"
34
35
36/**
37 * A channel is a bidirectional connection between two CADET
38 * clients. Communiation can be reliable, unreliable, in-order
39 * or out-of-order. One client is the "local" client, this
40 * one initiated the connection. The other client is the
41 * "incoming" client, this one listened on a port to accept
42 * the connection from the "local" client.
43 */
44struct CadetChannel;
45
46
47/**
48 * Get the static string for identification of the channel.
49 *
50 * @param ch Channel.
51 *
52 * @return Static string with the channel IDs.
53 */
54const char *
55GCCH_2s (const struct CadetChannel *ch);
56
57
58/**
59 * Log channel info.
60 *
61 * @param ch Channel.
62 * @param level Debug level to use.
63 */
64void
65GCCH_debug (struct CadetChannel *ch,
66 enum GNUNET_ErrorType level);
67
68
69/**
70 * Get the channel's public ID.
71 *
72 * @param ch Channel.
73 *
74 * @return ID used to identify the channel with the remote peer.
75 */
76struct GNUNET_CADET_ChannelTunnelNumber
77GCCH_get_id (const struct CadetChannel *ch);
78
79
80/**
81 * Create a new channel.
82 *
83 * @param owner local client owning the channel
84 * @param owner_id local chid of this channel at the @a owner
85 * @param destination peer to which we should build the channel
86 * @param port desired port at @a destination
87 * @param options options for the channel
88 * @return handle to the new channel
89 */
90struct CadetChannel *
91GCCH_channel_local_new (struct CadetClient *owner,
92 struct GNUNET_CADET_ClientChannelNumber owner_id,
93 struct CadetPeer *destination,
94 const struct GNUNET_HashCode *port,
95 uint32_t options);
96
97
98/**
99 * A client is bound to the port that we have a channel
100 * open to. Send the acknowledgement for the connection
101 * request and establish the link with the client.
102 *
103 * @param ch open incoming channel
104 * @param c client listening on the respective port
105 */
106void
107GCCH_bind (struct CadetChannel *ch,
108 struct CadetClient *c);
109
110
111/**
112 * Destroy locally created channel. Called by the
113 * local client, so no need to tell the client.
114 *
115 * @param ch channel to destroy
116 * @param c client that caused the destruction
117 * @param ccn client number of the client @a c
118 */
119void
120GCCH_channel_local_destroy (struct CadetChannel *ch,
121 struct CadetClient *c,
122 struct GNUNET_CADET_ClientChannelNumber ccn);
123
124
125/**
126 * Function called once and only once after a channel was bound
127 * to its tunnel via #GCT_add_channel() is ready for transmission.
128 * Note that this is only the case for channels that this peer
129 * initiates, as for incoming channels we assume that they are
130 * ready for transmission immediately upon receiving the open
131 * message. Used to bootstrap the #GCT_send() process.
132 *
133 * @param ch the channel for which the tunnel is now ready
134 */
135void
136GCCH_tunnel_up (struct CadetChannel *ch);
137
138
139/**
140 * Create a new channel based on a request coming in over the network.
141 *
142 * @param t tunnel to the remote peer
143 * @param chid identifier of this channel in the tunnel
144 * @param origin peer to who initiated the channel
145 * @param port desired local port
146 * @param options options for the channel
147 * @return handle to the new channel
148 */
149struct CadetChannel *
150GCCH_channel_incoming_new (struct CadetTunnel *t,
151 struct GNUNET_CADET_ChannelTunnelNumber chid,
152 const struct GNUNET_HashCode *port,
153 uint32_t options);
154
155
156/**
157 * We got a #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN message again for
158 * this channel. If the binding was successful, (re)transmit the
159 * #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK.
160 *
161 * @param ch channel that got the duplicate open
162 */
163void
164GCCH_handle_duplicate_open (struct CadetChannel *ch);
165
166
167/**
168 * We got payload data for a channel. Pass it on to the client.
169 *
170 * @param ch channel that got data
171 * @param msg message that was received
172 */
173void
174GCCH_handle_channel_plaintext_data (struct CadetChannel *ch,
175 const struct GNUNET_CADET_ChannelAppDataMessage *msg);
176
177
178/**
179 * We got an acknowledgement for payload data for a channel.
180 * Possibly resume transmissions.
181 *
182 * @param ch channel that got the ack
183 * @param ack details about what was received
184 */
185void
186GCCH_handle_channel_plaintext_data_ack (struct CadetChannel *ch,
187 const struct GNUNET_CADET_ChannelDataAckMessage *ack);
188
189
190/**
191 * We got an acknowledgement for the creation of the channel
192 * (the port is open on the other side). Begin transmissions.
193 *
194 * @param ch channel to destroy
195 */
196void
197GCCH_handle_channel_open_ack (struct CadetChannel *ch);
198
199
200/**
201 * Destroy channel, based on the other peer closing the
202 * connection. Also needs to remove this channel from
203 * the tunnel.
204 *
205 * FIXME: need to make it possible to defer destruction until we have
206 * received all messages up to the destroy, and right now the destroy
207 * message (and this API) fails to give is the information we need!
208 *
209 * FIXME: also need to know if the other peer got a destroy from
210 * us before!
211 *
212 * @param ch channel to destroy
213 */
214void
215GCCH_handle_remote_destroy (struct CadetChannel *ch);
216
217
218/**
219 * Handle data given by a client.
220 *
221 * Check whether the client is allowed to send in this tunnel, save if
222 * channel is reliable and send an ACK to the client if there is still
223 * buffer space in the tunnel.
224 *
225 * @param ch Channel.
226 * @param sender_ccn ccn of the sender
227 * @param buf payload to transmit.
228 * @param buf_len number of bytes in @a buf
229 * @return #GNUNET_OK if everything goes well,
230 * #GNUNET_SYSERR in case of an error.
231 */
232int
233GCCH_handle_local_data (struct CadetChannel *ch,
234 struct GNUNET_CADET_ClientChannelNumber sender_ccn,
235 const char *buf,
236 size_t buf_len);
237
238
239/**
240 * Handle ACK from client on local channel.
241 *
242 * @param ch channel to destroy
243 * @param client_ccn ccn of the client sending the ack
244 */
245void
246GCCH_handle_local_ack (struct CadetChannel *ch,
247 struct GNUNET_CADET_ClientChannelNumber client_ccn);
248
249#endif
diff --git a/src/cadet/gnunet-service-cadet-new_connection.c b/src/cadet/gnunet-service-cadet-new_connection.c
deleted file mode 100644
index 60389008c..000000000
--- a/src/cadet/gnunet-service-cadet-new_connection.c
+++ /dev/null
@@ -1,709 +0,0 @@
1
2/*
3 This file is part of GNUnet.
4 Copyright (C) 2001-2017 GNUnet e.V.
5
6 GNUnet is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published
8 by the Free Software Foundation; either version 3, or (at your
9 option) any later version.
10
11 GNUnet is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNUnet; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
20*/
21
22/**
23 * @file cadet/gnunet-service-cadet-new_connection.c
24 * @brief management of CORE-level end-to-end connections; establishes
25 * end-to-end routes and transmits messages along the route
26 * @author Bartlomiej Polot
27 * @author Christian Grothoff
28 *
29 * TODO:
30 * - Optimization: keepalive messages / timeout (timeout to be done @ peer level!)
31 * - Optimization: keep performance metrics (?)
32 */
33#include "platform.h"
34#include "gnunet-service-cadet-new_channel.h"
35#include "gnunet-service-cadet-new_connection.h"
36#include "gnunet-service-cadet-new_paths.h"
37#include "gnunet-service-cadet-new_peer.h"
38#include "gnunet-service-cadet-new_tunnels.h"
39#include "gnunet_cadet_service.h"
40#include "cadet_protocol.h"
41
42
43#define LOG(level, ...) GNUNET_log_from(level,"cadet-con",__VA_ARGS__)
44
45
46/**
47 * All the states a connection can be in.
48 */
49enum CadetConnectionState
50{
51 /**
52 * Uninitialized status, we have not yet even gotten the message queue.
53 */
54 CADET_CONNECTION_NEW,
55
56 /**
57 * Connection create message in queue, awaiting transmission by CORE.
58 */
59 CADET_CONNECTION_SENDING_CREATE,
60
61 /**
62 * Connection create message sent, waiting for ACK.
63 */
64 CADET_CONNECTION_SENT,
65
66 /**
67 * We are an inbound connection, and received a CREATE. Need to
68 * send an CREATE_ACK back.
69 */
70 CADET_CONNECTION_CREATE_RECEIVED,
71
72 /**
73 * Connection confirmed, ready to carry traffic.
74 */
75 CADET_CONNECTION_READY
76
77};
78
79
80/**
81 * Low-level connection to a destination.
82 */
83struct CadetConnection
84{
85
86 /**
87 * ID of the connection.
88 */
89 struct GNUNET_CADET_ConnectionTunnelIdentifier cid;
90
91 /**
92 * To which peer does this connection go?
93 */
94 struct CadetPeer *destination;
95
96 /**
97 * Which tunnel is using this connection?
98 */
99 struct CadetTConnection *ct;
100
101 /**
102 * Path we are using to our destination.
103 */
104 struct CadetPeerPath *path;
105
106 /**
107 * Pending message, NULL if we are ready to transmit.
108 */
109 struct GNUNET_MQ_Envelope *env;
110
111 /**
112 * Handle for calling #GCP_request_mq_cancel() once we are finished.
113 */
114 struct GCP_MessageQueueManager *mq_man;
115
116 /**
117 * Task for connection maintenance.
118 */
119 struct GNUNET_SCHEDULER_Task *task;
120
121 /**
122 * Function to call once we are ready to transmit.
123 */
124 GCC_ReadyCallback ready_cb;
125
126 /**
127 * Closure for @e ready_cb.
128 */
129 void *ready_cb_cls;
130
131 /**
132 * How long do we wait before we try again with a CREATE message?
133 */
134 struct GNUNET_TIME_Relative retry_delay;
135
136 /**
137 * State of the connection.
138 */
139 enum CadetConnectionState state;
140
141 /**
142 * Offset of our @e destination in @e path.
143 */
144 unsigned int off;
145
146 /**
147 * Are we ready to transmit via @e mq_man right now?
148 */
149 int mqm_ready;
150
151};
152
153
154/**
155 * Destroy a connection.
156 *
157 * @param cc connection to destroy
158 */
159void
160GCC_destroy (struct CadetConnection *cc)
161{
162 struct GNUNET_MQ_Envelope *env = NULL;
163
164 LOG (GNUNET_ERROR_TYPE_DEBUG,
165 "Destroying %s\n",
166 GCC_2s (cc));
167 if (CADET_CONNECTION_SENDING_CREATE != cc->state)
168 {
169 struct GNUNET_CADET_ConnectionDestroyMessage *destroy_msg;
170
171 /* Need to notify next hop that we are down. */
172 env = GNUNET_MQ_msg (destroy_msg,
173 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY);
174 destroy_msg->cid = cc->cid;
175 }
176 if (NULL != cc->mq_man)
177 {
178 GCP_request_mq_cancel (cc->mq_man,
179 env);
180 cc->mq_man = NULL;
181 }
182 if (NULL != cc->task)
183 {
184 GNUNET_SCHEDULER_cancel (cc->task);
185 cc->task = NULL;
186 }
187 GCPP_del_connection (cc->path,
188 cc->off,
189 cc);
190 GNUNET_assert (GNUNET_YES ==
191 GNUNET_CONTAINER_multishortmap_remove (connections,
192 &GCC_get_id (cc)->connection_of_tunnel,
193 cc));
194 GNUNET_free (cc);
195}
196
197
198/**
199 * Return the tunnel associated with this connection.
200 *
201 * @param cc connection to query
202 * @return corresponding entry in the tunnel's connection list
203 */
204struct CadetTConnection *
205GCC_get_ct (struct CadetConnection *cc)
206{
207 return cc->ct;
208}
209
210
211/**
212 * A CADET_CONNECTION_ACK was received for this connection, implying
213 * that the end-to-end connection is up. Process it.
214 *
215 * @param cc the connection that got the ACK.
216 */
217void
218GCC_handle_connection_create_ack (struct CadetConnection *cc)
219{
220 LOG (GNUNET_ERROR_TYPE_DEBUG,
221 "Received CADET_CONNECTION_CREATE_ACK for %s in state %d (%s)\n",
222 GCC_2s (cc),
223 cc->state,
224 (GNUNET_YES == cc->mqm_ready) ? "MQM ready" : "MQM busy");
225 if (NULL != cc->task)
226 {
227 GNUNET_SCHEDULER_cancel (cc->task);
228 cc->task = NULL;
229 }
230#if FIXME_KEEPALIVE
231 cc->task = GNUNET_SCHEDULER_add_delayed (cc->keepalive_period,
232 &send_keepalive,
233 cc);
234#endif
235 cc->state = CADET_CONNECTION_READY;
236 if (GNUNET_YES == cc->mqm_ready)
237 cc->ready_cb (cc->ready_cb_cls,
238 GNUNET_YES);
239}
240
241
242/**
243 * Handle KX message.
244 *
245 * @param cc connection that received encrypted message
246 * @param msg the key exchange message
247 */
248void
249GCC_handle_kx (struct CadetConnection *cc,
250 const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg)
251{
252 if (CADET_CONNECTION_SENT == cc->state)
253 {
254 /* We didn't get the CADET_CONNECTION_CREATE_ACK, but instead got payload. That's fine,
255 clearly something is working, so pretend we got an ACK. */
256 LOG (GNUNET_ERROR_TYPE_DEBUG,
257 "Faking connection CADET_CONNECTION_CREATE_ACK for %s due to KX\n",
258 GCC_2s (cc));
259 GCC_handle_connection_create_ack (cc);
260 }
261 GCT_handle_kx (cc->ct,
262 msg);
263}
264
265
266/**
267 * Handle encrypted message.
268 *
269 * @param cc connection that received encrypted message
270 * @param msg the encrypted message to decrypt
271 */
272void
273GCC_handle_encrypted (struct CadetConnection *cc,
274 const struct GNUNET_CADET_TunnelEncryptedMessage *msg)
275{
276 if (CADET_CONNECTION_SENT == cc->state)
277 {
278 /* We didn't get the CREATE_ACK, but instead got payload. That's fine,
279 clearly something is working, so pretend we got an ACK. */
280 LOG (GNUNET_ERROR_TYPE_DEBUG,
281 "Faking connection ACK for %s due to ENCRYPTED payload\n",
282 GCC_2s (cc));
283 GCC_handle_connection_create_ack (cc);
284 }
285 GCT_handle_encrypted (cc->ct,
286 msg);
287}
288
289
290/**
291 * Send a CREATE message to the first hop.
292 *
293 * @param cls the `struct CadetConnection` to initiate
294 */
295static void
296send_create (void *cls)
297{
298 struct CadetConnection *cc = cls;
299 struct GNUNET_CADET_ConnectionCreateMessage *create_msg;
300 struct GNUNET_PeerIdentity *pids;
301 struct GNUNET_MQ_Envelope *env;
302 unsigned int path_length;
303
304 cc->task = NULL;
305 GNUNET_assert (GNUNET_YES == cc->mqm_ready);
306 path_length = GCPP_get_length (cc->path);
307 env = GNUNET_MQ_msg_extra (create_msg,
308 (1 + path_length) * sizeof (struct GNUNET_PeerIdentity),
309 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE);
310 create_msg->cid = cc->cid;
311 pids = (struct GNUNET_PeerIdentity *) &create_msg[1];
312 pids[0] = my_full_id;
313 for (unsigned int i=0;i<path_length;i++)
314 pids[i + 1] = *GCP_get_id (GCPP_get_peer_at_offset (cc->path,
315 i));
316 LOG (GNUNET_ERROR_TYPE_DEBUG,
317 "Sending CADET_CONNECTION_CREATE message for %s\n",
318 GCC_2s (cc));
319 cc->env = env;
320 cc->mqm_ready = GNUNET_NO;
321 cc->state = CADET_CONNECTION_SENT;
322 GCP_send (cc->mq_man,
323 env);
324}
325
326
327/**
328 * Send a CREATE_ACK message towards the origin.
329 *
330 * @param cls the `struct CadetConnection` to initiate
331 */
332static void
333send_create_ack (void *cls)
334{
335 struct CadetConnection *cc = cls;
336 struct GNUNET_CADET_ConnectionCreateAckMessage *ack_msg;
337 struct GNUNET_MQ_Envelope *env;
338
339 cc->task = NULL;
340 GNUNET_assert (CADET_CONNECTION_CREATE_RECEIVED == cc->state);
341 LOG (GNUNET_ERROR_TYPE_DEBUG,
342 "Sending CONNECTION_CREATE_ACK message for %s\n",
343 GCC_2s (cc));
344 GNUNET_assert (GNUNET_YES == cc->mqm_ready);
345 env = GNUNET_MQ_msg (ack_msg,
346 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK);
347 ack_msg->cid = cc->cid;
348 cc->env = env;
349 cc->mqm_ready = GNUNET_NO;
350 cc->state = CADET_CONNECTION_READY;
351 GCP_send (cc->mq_man,
352 env);
353}
354
355
356/**
357 * We got a #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE for a
358 * connection that we already have. Either our ACK got lost
359 * or something is fishy. Consider retransmitting the ACK.
360 *
361 * @param cc connection that got the duplicate CREATE
362 */
363void
364GCC_handle_duplicate_create (struct CadetConnection *cc)
365{
366 if (GNUNET_YES == cc->mqm_ready)
367 {
368 LOG (GNUNET_ERROR_TYPE_DEBUG,
369 "Got duplicate CREATE for %s, scheduling another ACK (%s)\n",
370 GCC_2s (cc),
371 (GNUNET_YES == cc->mqm_ready) ? "MQM ready" : "MQM busy");
372 /* Tell tunnel that we are not ready for transmission anymore
373 (until CREATE_ACK is done) */
374 cc->ready_cb (cc->ready_cb_cls,
375 GNUNET_NO);
376 /* Revert back to the state of having only received the 'CREATE',
377 and immediately proceed to send the CREATE_ACK. */
378 cc->state = CADET_CONNECTION_CREATE_RECEIVED;
379 if (NULL != cc->task)
380 GNUNET_SCHEDULER_cancel (cc->task);
381 cc->task = GNUNET_SCHEDULER_add_now (&send_create_ack,
382 cc);
383 }
384 else
385 {
386 /* We are currently sending something else back, which
387 can only be an ACK or payload, either of which would
388 do. So actually no need to do anything. */
389 LOG (GNUNET_ERROR_TYPE_DEBUG,
390 "Got duplicate CREATE for %s. MQ is busy, not queueing another ACK\n",
391 GCC_2s (cc));
392 }
393}
394
395
396/**
397 * There has been a change in the message queue existence for our
398 * peer at the first hop. Adjust accordingly.
399 *
400 * @param cls the `struct CadetConnection`
401 * @param available #GNUNET_YES if sending is now possible,
402 * #GNUNET_NO if sending is no longer possible
403 * #GNUNET_SYSERR if sending is no longer possible
404 * and the last envelope was discarded
405 */
406static void
407manage_first_hop_mq (void *cls,
408 int available)
409{
410 struct CadetConnection *cc = cls;
411
412 if (GNUNET_YES != available)
413 {
414 /* Connection is down, for now... */
415 LOG (GNUNET_ERROR_TYPE_DEBUG,
416 "Core MQ for %s went down\n",
417 GCC_2s (cc));
418 cc->mqm_ready = GNUNET_NO;
419 cc->state = CADET_CONNECTION_NEW;
420 cc->retry_delay = GNUNET_TIME_UNIT_ZERO;
421 if (NULL != cc->task)
422 {
423 GNUNET_SCHEDULER_cancel (cc->task);
424 cc->task = NULL;
425 }
426 cc->ready_cb (cc->ready_cb_cls,
427 GNUNET_NO);
428 return;
429 }
430
431 cc->mqm_ready = GNUNET_YES;
432 LOG (GNUNET_ERROR_TYPE_DEBUG,
433 "Core MQ for %s became available in state %d\n",
434 GCC_2s (cc),
435 cc->state);
436 switch (cc->state)
437 {
438 case CADET_CONNECTION_NEW:
439 /* Transmit immediately */
440 cc->task = GNUNET_SCHEDULER_add_now (&send_create,
441 cc);
442 break;
443 case CADET_CONNECTION_SENDING_CREATE:
444 /* Should not be possible to be called in this state. */
445 GNUNET_assert (0);
446 break;
447 case CADET_CONNECTION_SENT:
448 /* Retry a bit later... */
449 cc->retry_delay = GNUNET_TIME_STD_BACKOFF (cc->retry_delay);
450 cc->task = GNUNET_SCHEDULER_add_delayed (cc->retry_delay,
451 &send_create,
452 cc);
453 break;
454 case CADET_CONNECTION_CREATE_RECEIVED:
455 /* We got the 'CREATE' (incoming connection), should send the CREATE_ACK */
456 cc->task = GNUNET_SCHEDULER_add_now (&send_create_ack,
457 cc);
458 break;
459 case CADET_CONNECTION_READY:
460 cc->ready_cb (cc->ready_cb_cls,
461 GNUNET_YES);
462 break;
463 }
464}
465
466
467/**
468 * Create a connection to @a destination via @a path and notify @a cb
469 * whenever we are ready for more data. Shared logic independent of
470 * who is initiating the connection.
471 *
472 * @param destination where to go
473 * @param path which path to take (may not be the full path)
474 * @param ct which tunnel uses this connection
475 * @param init_state initial state for the connection
476 * @param ready_cb function to call when ready to transmit
477 * @param ready_cb_cls closure for @a cb
478 * @return handle to the connection
479 */
480static struct CadetConnection *
481connection_create (struct CadetPeer *destination,
482 struct CadetPeerPath *path,
483 struct CadetTConnection *ct,
484 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
485 enum CadetConnectionState init_state,
486 GCC_ReadyCallback ready_cb,
487 void *ready_cb_cls)
488{
489 struct CadetConnection *cc;
490 struct CadetPeer *first_hop;
491 unsigned int off;
492
493 off = GCPP_find_peer (path,
494 destination);
495 GNUNET_assert (UINT_MAX > off);
496 cc = GNUNET_new (struct CadetConnection);
497 cc->state = init_state;
498 cc->ct = ct;
499 cc->cid = *cid;
500 GNUNET_assert (GNUNET_OK ==
501 GNUNET_CONTAINER_multishortmap_put (connections,
502 &GCC_get_id (cc)->connection_of_tunnel,
503 cc,
504 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
505 cc->ready_cb = ready_cb;
506 cc->ready_cb_cls = ready_cb_cls;
507 cc->path = path;
508 cc->off = off;
509 LOG (GNUNET_ERROR_TYPE_DEBUG,
510 "Creating %s using path %s\n",
511 GCC_2s (cc),
512 GCPP_2s (path));
513 GCPP_add_connection (path,
514 off,
515 cc);
516 for (unsigned int i=0;i<off;i++)
517 GCP_add_connection (GCPP_get_peer_at_offset (path,
518 off),
519 cc);
520
521 first_hop = GCPP_get_peer_at_offset (path,
522 0);
523 cc->mq_man = GCP_request_mq (first_hop,
524 &manage_first_hop_mq,
525 cc);
526 return cc;
527}
528
529
530/**
531 * Create a connection to @a destination via @a path and
532 * notify @a cb whenever we are ready for more data. This
533 * is an inbound tunnel, so we must use the existing @a cid
534 *
535 * @param destination where to go
536 * @param path which path to take (may not be the full path)
537 * @param ct which tunnel uses this connection
538 * @param ready_cb function to call when ready to transmit
539 * @param ready_cb_cls closure for @a cb
540 * @return handle to the connection
541 */
542struct CadetConnection *
543GCC_create_inbound (struct CadetPeer *destination,
544 struct CadetPeerPath *path,
545 struct CadetTConnection *ct,
546 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
547 GCC_ReadyCallback ready_cb,
548 void *ready_cb_cls)
549{
550 return connection_create (destination,
551 path,
552 ct,
553 cid,
554 CADET_CONNECTION_CREATE_RECEIVED,
555 ready_cb,
556 ready_cb_cls);
557}
558
559
560/**
561 * Create a connection to @a destination via @a path and
562 * notify @a cb whenever we are ready for more data.
563 *
564 * @param destination where to go
565 * @param path which path to take (may not be the full path)
566 * @param ct tunnel that uses the connection
567 * @param ready_cb function to call when ready to transmit
568 * @param ready_cb_cls closure for @a cb
569 * @return handle to the connection
570 */
571struct CadetConnection *
572GCC_create (struct CadetPeer *destination,
573 struct CadetPeerPath *path,
574 struct CadetTConnection *ct,
575 GCC_ReadyCallback ready_cb,
576 void *ready_cb_cls)
577{
578 struct GNUNET_CADET_ConnectionTunnelIdentifier cid;
579
580 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
581 &cid,
582 sizeof (cid));
583 return connection_create (destination,
584 path,
585 ct,
586 &cid,
587 CADET_CONNECTION_NEW,
588 ready_cb,
589 ready_cb_cls);
590}
591
592
593/**
594 * Transmit message @a msg via connection @a cc. Must only be called
595 * (once) after the connection has signalled that it is ready via the
596 * `ready_cb`. Clients can also use #GCC_is_ready() to check if the
597 * connection is right now ready for transmission.
598 *
599 * @param cc connection identification
600 * @param env envelope with message to transmit; must NOT
601 * yet have a #GNUNET_MQ_notify_sent() callback attached to it
602 */
603void
604GCC_transmit (struct CadetConnection *cc,
605 struct GNUNET_MQ_Envelope *env)
606{
607 LOG (GNUNET_ERROR_TYPE_DEBUG,
608 "Scheduling message for transmission on %s\n",
609 GCC_2s (cc));
610 GNUNET_assert (GNUNET_YES == cc->mqm_ready);
611 GNUNET_assert (CADET_CONNECTION_READY == cc->state);
612 cc->mqm_ready = GNUNET_NO;
613 GCP_send (cc->mq_man,
614 env);
615}
616
617
618/**
619 * Obtain the path used by this connection.
620 *
621 * @param cc connection
622 * @return path to @a cc
623 */
624struct CadetPeerPath *
625GCC_get_path (struct CadetConnection *cc)
626{
627 return cc->path;
628}
629
630
631/**
632 * Obtain unique ID for the connection.
633 *
634 * @param cc connection.
635 * @return unique number of the connection
636 */
637const struct GNUNET_CADET_ConnectionTunnelIdentifier *
638GCC_get_id (struct CadetConnection *cc)
639{
640 return &cc->cid;
641}
642
643
644/**
645 * Get a (static) string for a connection.
646 *
647 * @param cc Connection.
648 */
649const char *
650GCC_2s (const struct CadetConnection *cc)
651{
652 static char buf[128];
653
654 if (NULL == cc)
655 return "Connection(NULL)";
656
657 if (NULL != cc->ct)
658 {
659 GNUNET_snprintf (buf,
660 sizeof (buf),
661 "Connection %s (%s)",
662 GNUNET_sh2s (&cc->cid.connection_of_tunnel),
663 GCT_2s (cc->ct->t));
664 return buf;
665 }
666 GNUNET_snprintf (buf,
667 sizeof (buf),
668 "Connection %s",
669 GNUNET_sh2s (&cc->cid.connection_of_tunnel));
670 return buf;
671}
672
673
674#define LOG2(level, ...) GNUNET_log_from_nocheck(level,"cadet-con",__VA_ARGS__)
675
676
677/**
678 * Log connection info.
679 *
680 * @param cc connection
681 * @param level Debug level to use.
682 */
683void
684GCC_debug (struct CadetConnection *cc,
685 enum GNUNET_ErrorType level)
686{
687 int do_log;
688
689 do_log = GNUNET_get_log_call_status (level & (~GNUNET_ERROR_TYPE_BULK),
690 "cadet-con",
691 __FILE__, __FUNCTION__, __LINE__);
692 if (0 == do_log)
693 return;
694 if (NULL == cc)
695 {
696 LOG2 (level,
697 "Connection (NULL)\n");
698 return;
699 }
700 LOG2 (level,
701 "%s to %s via path %s in state %d is %s\n",
702 GCC_2s (cc),
703 GCP_2s (cc->destination),
704 GCPP_2s (cc->path),
705 cc->state,
706 (GNUNET_YES == cc->mqm_ready) ? "ready" : "busy");
707}
708
709/* end of gnunet-service-cadet-new_connection.c */
diff --git a/src/cadet/gnunet-service-cadet-new_connection.h b/src/cadet/gnunet-service-cadet-new_connection.h
deleted file mode 100644
index efdf9929a..000000000
--- a/src/cadet/gnunet-service-cadet-new_connection.h
+++ /dev/null
@@ -1,207 +0,0 @@
1
2/*
3 This file is part of GNUnet.
4 Copyright (C) 2001-2017 GNUnet e.V.
5
6 GNUnet is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published
8 by the Free Software Foundation; either version 3, or (at your
9 option) any later version.
10
11 GNUnet is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNUnet; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
20*/
21
22/**
23 * @file cadet/gnunet-service-cadet-new_connection.h
24 * @brief
25 * @author Bartlomiej Polot
26 * @author Christian Grothoff
27 */
28#ifndef GNUNET_SERVICE_CADET_CONNECTION_H
29#define GNUNET_SERVICE_CADET_CONNECTION_H
30
31#include "gnunet_util_lib.h"
32#include "gnunet-service-cadet-new.h"
33#include "gnunet-service-cadet-new_peer.h"
34#include "cadet_protocol.h"
35
36
37/**
38 * Function called to notify tunnel about change in our readyness.
39 *
40 * @param cls closure
41 * @param is_ready #GNUNET_YES if the connection is now ready for transmission,
42 * #GNUNET_NO if the connection is no longer ready for transmission
43 */
44typedef void
45(*GCC_ReadyCallback)(void *cls,
46 int is_ready);
47
48
49/**
50 * Destroy a connection.
51 *
52 * @param cc connection to destroy
53 */
54void
55GCC_destroy (struct CadetConnection *cc);
56
57
58/**
59 * Create a connection to @a destination via @a path and
60 * notify @a cb whenever we are ready for more data.
61 *
62 * @param destination where to go
63 * @param path which path to take (may not be the full path)
64 * @param ct which tunnel uses this connection
65 * @param ready_cb function to call when ready to transmit
66 * @param ready_cb_cls closure for @a cb
67 * @return handle to the connection
68 */
69struct CadetConnection *
70GCC_create (struct CadetPeer *destination,
71 struct CadetPeerPath *path,
72 struct CadetTConnection *ct,
73 GCC_ReadyCallback ready_cb,
74 void *ready_cb_cls);
75
76
77/**
78 * Create a connection to @a destination via @a path and
79 * notify @a cb whenever we are ready for more data. This
80 * is an inbound tunnel, so we must use the existing @a cid
81 *
82 * @param destination where to go
83 * @param path which path to take (may not be the full path)
84 * @param ct which tunnel uses this connection
85 * @param ready_cb function to call when ready to transmit
86 * @param ready_cb_cls closure for @a cb
87 * @return handle to the connection
88 */
89struct CadetConnection *
90GCC_create_inbound (struct CadetPeer *destination,
91 struct CadetPeerPath *path,
92 struct CadetTConnection *ct,
93 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
94 GCC_ReadyCallback ready_cb,
95 void *ready_cb_cls);
96
97
98/**
99 * Transmit message @a msg via connection @a cc. Must only be called
100 * (once) after the connection has signalled that it is ready via the
101 * `ready_cb`. Clients can also use #GCC_is_ready() to check if the
102 * connection is right now ready for transmission.
103 *
104 * @param cc connection identification
105 * @param env envelope with message to transmit;
106 * the #GNUNET_MQ_notify_send() must not have yet been used
107 * for the envelope. Also, the message better match the
108 * connection identifier of this connection...
109 */
110void
111GCC_transmit (struct CadetConnection *cc,
112 struct GNUNET_MQ_Envelope *env);
113
114
115/**
116 * A CREATE_ACK was received for this connection, process it.
117 *
118 * @param cc the connection that got the ACK.
119 */
120void
121GCC_handle_connection_create_ack (struct CadetConnection *cc);
122
123
124/**
125 * We got a #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE for a
126 * connection that we already have. Either our ACK got lost
127 * or something is fishy. Consider retransmitting the ACK.
128 *
129 * @param cc connection that got the duplicate CREATE
130 */
131void
132GCC_handle_duplicate_create (struct CadetConnection *cc);
133
134
135/**
136 * Handle KX message.
137 *
138 * @param cc connection that received encrypted message
139 * @param msg the key exchange message
140 */
141void
142GCC_handle_kx (struct CadetConnection *cc,
143 const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg);
144
145
146/**
147 * Handle encrypted message.
148 *
149 * @param cc connection that received encrypted message
150 * @param msg the encrypted message to decrypt
151 */
152void
153GCC_handle_encrypted (struct CadetConnection *cc,
154 const struct GNUNET_CADET_TunnelEncryptedMessage *msg);
155
156
157/**
158 * Return the tunnel associated with this connection.
159 *
160 * @param cc connection to query
161 * @return corresponding entry in the tunnel's connection list
162 */
163struct CadetTConnection *
164GCC_get_ct (struct CadetConnection *cc);
165
166
167/**
168 * Obtain the path used by this connection.
169 *
170 * @param cc connection
171 * @return path to @a cc
172 */
173struct CadetPeerPath *
174GCC_get_path (struct CadetConnection *cc);
175
176
177/**
178 * Obtain unique ID for the connection.
179 *
180 * @param cc connection.
181 * @return unique number of the connection
182 */
183const struct GNUNET_CADET_ConnectionTunnelIdentifier *
184GCC_get_id (struct CadetConnection *cc);
185
186
187/**
188 * Get a (static) string for a connection.
189 *
190 * @param cc Connection.
191 */
192const char *
193GCC_2s (const struct CadetConnection *cc);
194
195
196/**
197 * Log connection info.
198 *
199 * @param cc connection
200 * @param level Debug level to use.
201 */
202void
203GCC_debug (struct CadetConnection *cc,
204 enum GNUNET_ErrorType level);
205
206
207#endif
diff --git a/src/cadet/gnunet-service-cadet-new_dht.c b/src/cadet/gnunet-service-cadet-new_dht.c
deleted file mode 100644
index 849562f23..000000000
--- a/src/cadet/gnunet-service-cadet-new_dht.c
+++ /dev/null
@@ -1,351 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2013, 2017 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 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 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20/**
21 * @file cadet/gnunet-service-cadet-new_dht.c
22 * @brief Information we track per peer.
23 * @author Bartlomiej Polot
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include "gnunet_util_lib.h"
29#include "gnunet_dht_service.h"
30#include "gnunet_statistics_service.h"
31#include "gnunet-service-cadet-new.h"
32#include "gnunet-service-cadet-new_dht.h"
33#include "gnunet-service-cadet-new_hello.h"
34#include "gnunet-service-cadet-new_peer.h"
35#include "gnunet-service-cadet-new_paths.h"
36
37/**
38 * How long do we wait before first announcing our presence to the DHT.
39 * Used to wait for our HELLO to be available. Note that we also get
40 * notifications when our HELLO is ready, so this is just the maximum
41 * we wait for the first notification.
42 */
43#define STARTUP_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 500)
44
45/**
46 * How long do we wait after we get an updated HELLO before publishing?
47 * Allows for the HELLO to be updated again quickly, for example in
48 * case multiple addresses changed and we got a partial update.
49 */
50#define CHANGE_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 100)
51
52
53#define LOG(level, ...) GNUNET_log_from (level,"cadet-dht",__VA_ARGS__)
54
55
56/**
57 * Handle for DHT searches.
58 */
59struct GCD_search_handle
60{
61 /**
62 * DHT_GET handle.
63 */
64 struct GNUNET_DHT_GetHandle *dhtget;
65
66};
67
68
69/**
70 * Handle to use DHT.
71 */
72static struct GNUNET_DHT_Handle *dht_handle;
73
74/**
75 * How often to PUT own ID in the DHT.
76 */
77static struct GNUNET_TIME_Relative id_announce_time;
78
79/**
80 * DHT replication level, see DHT API: #GNUNET_DHT_get_start(), #GNUNET_DHT_put().
81 */
82static unsigned long long dht_replication_level;
83
84/**
85 * Task to periodically announce itself in the network.
86 */
87static struct GNUNET_SCHEDULER_Task *announce_id_task;
88
89/**
90 * Delay for the next ID announce.
91 */
92static struct GNUNET_TIME_Relative announce_delay;
93
94
95/**
96 * Function to process paths received for a new peer addition. The recorded
97 * paths form the initial tunnel, which can be optimized later.
98 * Called on each result obtained for the DHT search.
99 *
100 * @param cls closure
101 * @param exp when will this value expire
102 * @param key key of the result
103 * @param get_path path of the get request
104 * @param get_path_length lenght of @a get_path
105 * @param put_path path of the put request
106 * @param put_path_length length of the @a put_path
107 * @param type type of the result
108 * @param size number of bytes in data
109 * @param data pointer to the result data
110 */
111static void
112dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp,
113 const struct GNUNET_HashCode *key,
114 const struct GNUNET_PeerIdentity *get_path,
115 unsigned int get_path_length,
116 const struct GNUNET_PeerIdentity *put_path,
117 unsigned int put_path_length,
118 enum GNUNET_BLOCK_Type type,
119 size_t size,
120 const void *data)
121{
122 const struct GNUNET_HELLO_Message *hello = data;
123 struct CadetPeer *peer;
124
125 GCPP_try_path_from_dht (get_path,
126 get_path_length,
127 put_path,
128 put_path_length);
129 if ( (size >= sizeof (struct GNUNET_HELLO_Message)) &&
130 (ntohs (hello->header.size) == size) &&
131 (size == GNUNET_HELLO_size (hello)) )
132 {
133 peer = GCP_get (&put_path[0],
134 GNUNET_YES);
135 LOG (GNUNET_ERROR_TYPE_DEBUG,
136 "Got HELLO for %s\n",
137 GCP_2s (peer));
138 GCP_set_hello (peer,
139 hello);
140 }
141}
142
143
144/**
145 * Periodically announce self id in the DHT
146 *
147 * @param cls closure
148 */
149static void
150announce_id (void *cls)
151{
152 struct GNUNET_HashCode phash;
153 const struct GNUNET_HELLO_Message *hello;
154 size_t size;
155 struct GNUNET_TIME_Absolute expiration;
156 struct GNUNET_TIME_Relative next_put;
157
158 hello = GCH_get_mine ();
159 size = (NULL != hello) ? GNUNET_HELLO_size (hello) : 0;
160 if (0 == size)
161 {
162 expiration = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
163 announce_delay);
164 announce_delay = GNUNET_TIME_STD_BACKOFF (announce_delay);
165 }
166 else
167 {
168 expiration = GNUNET_HELLO_get_last_expiration (hello);
169 announce_delay = GNUNET_TIME_UNIT_SECONDS;
170 }
171
172 /* Call again in id_announce_time, unless HELLO expires first,
173 * but wait at least 1s. */
174 next_put
175 = GNUNET_TIME_absolute_get_remaining (expiration);
176 next_put
177 = GNUNET_TIME_relative_min (next_put,
178 id_announce_time);
179 next_put
180 = GNUNET_TIME_relative_max (next_put,
181 GNUNET_TIME_UNIT_SECONDS);
182 announce_id_task
183 = GNUNET_SCHEDULER_add_delayed (next_put,
184 &announce_id,
185 cls);
186 GNUNET_STATISTICS_update (stats,
187 "# DHT announce",
188 1,
189 GNUNET_NO);
190 memset (&phash,
191 0,
192 sizeof (phash));
193 GNUNET_memcpy (&phash,
194 &my_full_id,
195 sizeof (my_full_id));
196 LOG (GNUNET_ERROR_TYPE_DEBUG,
197 "Announcing my HELLO (%u bytes) in the DHT\n",
198 size);
199 GNUNET_DHT_put (dht_handle, /* DHT handle */
200 &phash, /* Key to use */
201 dht_replication_level, /* Replication level */
202 GNUNET_DHT_RO_RECORD_ROUTE
203 | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, /* DHT options */
204 GNUNET_BLOCK_TYPE_DHT_HELLO, /* Block type */
205 size, /* Size of the data */
206 (const char *) hello, /* Data itself */
207 expiration, /* Data expiration */
208 NULL, /* Continuation */
209 NULL); /* Continuation closure */
210}
211
212
213/**
214 * Function called by the HELLO subsystem whenever OUR hello
215 * changes. Re-triggers the DHT PUT immediately.
216 */
217void
218GCD_hello_update ()
219{
220 if (NULL == announce_id_task)
221 return; /* too early */
222 GNUNET_SCHEDULER_cancel (announce_id_task);
223 announce_id_task
224 = GNUNET_SCHEDULER_add_delayed (CHANGE_DELAY,
225 &announce_id,
226 NULL);
227}
228
229
230/**
231 * Initialize the DHT subsystem.
232 *
233 * @param c Configuration.
234 */
235void
236GCD_init (const struct GNUNET_CONFIGURATION_Handle *c)
237{
238 if (GNUNET_OK !=
239 GNUNET_CONFIGURATION_get_value_number (c,
240 "CADET",
241 "DHT_REPLICATION_LEVEL",
242 &dht_replication_level))
243 {
244 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
245 "CADET",
246 "DHT_REPLICATION_LEVEL",
247 "USING DEFAULT");
248 dht_replication_level = 3;
249 }
250
251 if (GNUNET_OK !=
252 GNUNET_CONFIGURATION_get_value_time (c,
253 "CADET",
254 "ID_ANNOUNCE_TIME",
255 &id_announce_time))
256 {
257 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
258 "CADET",
259 "ID_ANNOUNCE_TIME",
260 "MISSING");
261 GNUNET_SCHEDULER_shutdown ();
262 return;
263 }
264
265 dht_handle = GNUNET_DHT_connect (c,
266 64);
267 GNUNET_break (NULL != dht_handle);
268 announce_delay = GNUNET_TIME_UNIT_SECONDS;
269 announce_id_task = GNUNET_SCHEDULER_add_delayed (STARTUP_DELAY,
270 &announce_id,
271 NULL);
272}
273
274
275/**
276 * Shut down the DHT subsystem.
277 */
278void
279GCD_shutdown (void)
280{
281 if (NULL != dht_handle)
282 {
283 GNUNET_DHT_disconnect (dht_handle);
284 dht_handle = NULL;
285 }
286 if (NULL != announce_id_task)
287 {
288 GNUNET_SCHEDULER_cancel (announce_id_task);
289 announce_id_task = NULL;
290 }
291}
292
293
294/**
295 * Search DHT for paths to @a peeR_id
296 *
297 * @param peer_id peer to search for
298 * @return handle to abort search
299 */
300struct GCD_search_handle *
301GCD_search (const struct GNUNET_PeerIdentity *peer_id)
302{
303 struct GNUNET_HashCode phash;
304 struct GCD_search_handle *h;
305
306 GNUNET_STATISTICS_update (stats,
307 "# DHT search",
308 1,
309 GNUNET_NO);
310 memset (&phash,
311 0,
312 sizeof (phash));
313 GNUNET_memcpy (&phash,
314 peer_id,
315 sizeof (*peer_id));
316
317 h = GNUNET_new (struct GCD_search_handle);
318 h->dhtget = GNUNET_DHT_get_start (dht_handle, /* handle */
319 GNUNET_BLOCK_TYPE_DHT_HELLO, /* type */
320 &phash, /* key to search */
321 dht_replication_level, /* replication level */
322 GNUNET_DHT_RO_RECORD_ROUTE |
323 GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
324 NULL, /* xquery */
325 0, /* xquery bits */
326 &dht_get_id_handler,
327 h);
328 LOG (GNUNET_ERROR_TYPE_DEBUG,
329 "Starting DHT GET for peer %s (%p)\n",
330 GNUNET_i2s (peer_id),
331 h);
332 return h;
333}
334
335
336/**
337 * Stop DHT search started with #GCD_search().
338 *
339 * @param h handle to search to stop
340 */
341void
342GCD_search_stop (struct GCD_search_handle *h)
343{
344 LOG (GNUNET_ERROR_TYPE_DEBUG,
345 "Stopping DHT GET %p\n",
346 h);
347 GNUNET_DHT_get_stop (h->dhtget);
348 GNUNET_free (h);
349}
350
351/* end of gnunet-service-cadet_dht.c */
diff --git a/src/cadet/gnunet-service-cadet-new_dht.h b/src/cadet/gnunet-service-cadet-new_dht.h
deleted file mode 100644
index 5d7ab29a0..000000000
--- a/src/cadet/gnunet-service-cadet-new_dht.h
+++ /dev/null
@@ -1,100 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2013, 2017 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 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 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file cadet/gnunet-service-cadet_dht.h
23 * @brief cadet service; dealing with DHT requests and results
24 * @author Bartlomiej Polot
25 * @author Christian Grothoff
26 *
27 * All functions in this file should use the prefix GCD (Gnunet Cadet Dht)
28 */
29#ifndef GNUNET_SERVICE_CADET_DHT_H
30#define GNUNET_SERVICE_CADET_DHT_H
31
32#ifdef __cplusplus
33extern "C"
34{
35#if 0 /* keep Emacsens' auto-indent happy */
36}
37#endif
38#endif
39
40#include "platform.h"
41#include "gnunet_util_lib.h"
42
43/**
44 * Handle for DHT search operation.
45 */
46struct GCD_search_handle;
47
48
49/**
50 * Initialize the DHT subsystem.
51 *
52 * @param c Configuration.
53 */
54void
55GCD_init (const struct GNUNET_CONFIGURATION_Handle *c);
56
57
58/**
59 * Shut down the DHT subsystem.
60 */
61void
62GCD_shutdown (void);
63
64
65/**
66 * Function called by the HELLO subsystem whenever OUR hello
67 * changes. Re-triggers the DHT PUT immediately.
68 */
69void
70GCD_hello_update (void);
71
72/**
73 * Search DHT for paths to @a peeR_id
74 *
75 * @param peer_id peer to search for
76 * @return handle to abort search
77 */
78struct GCD_search_handle *
79GCD_search (const struct GNUNET_PeerIdentity *peer_id);
80
81
82/**
83 * Stop DHT search started with #GCD_search().
84 *
85 * @param h handle to search to stop
86 */
87void
88GCD_search_stop (struct GCD_search_handle *h);
89
90
91#if 0 /* keep Emacsens' auto-indent happy */
92{
93#endif
94#ifdef __cplusplus
95}
96#endif
97
98/* ifndef GNUNET_CADET_SERVICE_DHT_H */
99#endif
100/* end of gnunet-service-cadet_dht.h */
diff --git a/src/cadet/gnunet-service-cadet-new_hello.c b/src/cadet/gnunet-service-cadet-new_hello.c
deleted file mode 100644
index a24325ada..000000000
--- a/src/cadet/gnunet-service-cadet-new_hello.c
+++ /dev/null
@@ -1,152 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2014, 2017 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 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 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20/**
21 * @file cadet/gnunet-service-cadet-new_hello.c
22 * @brief spread knowledge about how to contact other peers from PEERINFO
23 * @author Bartlomiej Polot
24 * @author Christian Grothoff
25 *
26 * TODO:
27 * - is most of this necessary/helpful?
28 * - should we not simply restrict this to OUR hello?
29 */
30#include "platform.h"
31#include "gnunet_util_lib.h"
32
33#include "gnunet_statistics_service.h"
34#include "gnunet_peerinfo_service.h"
35#include "cadet_protocol.h"
36#include "gnunet-service-cadet-new.h"
37#include "gnunet-service-cadet-new_dht.h"
38#include "gnunet-service-cadet-new_hello.h"
39#include "gnunet-service-cadet-new_peer.h"
40
41#define LOG(level, ...) GNUNET_log_from(level,"cadet-hll",__VA_ARGS__)
42
43/**
44 * Hello message of local peer.
45 */
46static struct GNUNET_HELLO_Message *mine;
47
48/**
49 * Handle to peerinfo service.
50 */
51static struct GNUNET_PEERINFO_Handle *peerinfo;
52
53/**
54 * Iterator context.
55 */
56static struct GNUNET_PEERINFO_NotifyContext *nc;
57
58
59/**
60 * Process each hello message received from peerinfo.
61 *
62 * @param cls Closure (unused).
63 * @param peer Identity of the peer.
64 * @param hello Hello of the peer.
65 * @param err_msg Error message.
66 */
67static void
68got_hello (void *cls,
69 const struct GNUNET_PeerIdentity *id,
70 const struct GNUNET_HELLO_Message *hello,
71 const char *err_msg)
72{
73 struct CadetPeer *peer;
74
75 if ( (NULL == id) ||
76 (NULL == hello) )
77 return;
78 if (0 == memcmp (id,
79 &my_full_id,
80 sizeof (struct GNUNET_PeerIdentity)))
81 {
82 GNUNET_free_non_null (mine);
83 mine = (struct GNUNET_HELLO_Message *) GNUNET_copy_message (&hello->header);
84 GCD_hello_update ();
85 return;
86 }
87
88 LOG (GNUNET_ERROR_TYPE_DEBUG,
89 "Hello for %s (%d bytes), expires on %s\n",
90 GNUNET_i2s (id),
91 GNUNET_HELLO_size (hello),
92 GNUNET_STRINGS_absolute_time_to_string (GNUNET_HELLO_get_last_expiration (hello)));
93 peer = GCP_get (id,
94 GNUNET_YES);
95 GCP_set_hello (peer,
96 hello);
97}
98
99
100/**
101 * Initialize the hello subsystem.
102 *
103 * @param c Configuration.
104 */
105void
106GCH_init (const struct GNUNET_CONFIGURATION_Handle *c)
107{
108 GNUNET_assert (NULL == nc);
109 peerinfo = GNUNET_PEERINFO_connect (c);
110 nc = GNUNET_PEERINFO_notify (c,
111 GNUNET_NO,
112 &got_hello,
113 NULL);
114}
115
116
117/**
118 * Shut down the hello subsystem.
119 */
120void
121GCH_shutdown ()
122{
123 if (NULL != nc)
124 {
125 GNUNET_PEERINFO_notify_cancel (nc);
126 nc = NULL;
127 }
128 if (NULL != peerinfo)
129 {
130 GNUNET_PEERINFO_disconnect (peerinfo);
131 peerinfo = NULL;
132 }
133 if (NULL != mine)
134 {
135 GNUNET_free (mine);
136 mine = NULL;
137 }
138}
139
140
141/**
142 * Get own hello message.
143 *
144 * @return Own hello message.
145 */
146const struct GNUNET_HELLO_Message *
147GCH_get_mine (void)
148{
149 return mine;
150}
151
152/* end of gnunet-service-cadet-new_hello.c */
diff --git a/src/cadet/gnunet-service-cadet-new_hello.h b/src/cadet/gnunet-service-cadet-new_hello.h
deleted file mode 100644
index 4291ae985..000000000
--- a/src/cadet/gnunet-service-cadet-new_hello.h
+++ /dev/null
@@ -1,80 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2014, 2017 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 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 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file cadet/gnunet-service-cadet_hello.h
23 * @brief cadet service; dealing with hello messages
24 * @author Bartlomiej Polot
25 * @author Christian Grothoff
26 *
27 * All functions in this file should use the prefix GCH (Gnunet Cadet Hello)
28 */
29
30#ifndef GNUNET_SERVICE_CADET_HELLO_H
31#define GNUNET_SERVICE_CADET_HELLO_H
32
33#ifdef __cplusplus
34extern "C"
35{
36#if 0 /* keep Emacsens' auto-indent happy */
37}
38#endif
39#endif
40
41#include "platform.h"
42#include "gnunet_util_lib.h"
43#include "gnunet_hello_lib.h"
44
45
46/**
47 * Initialize the hello subsystem.
48 *
49 * @param c Configuration.
50 */
51void
52GCH_init (const struct GNUNET_CONFIGURATION_Handle *c);
53
54
55/**
56 * Shut down the hello subsystem.
57 */
58void
59GCH_shutdown (void);
60
61
62/**
63 * Get own hello message.
64 *
65 * @return Own hello message.
66 */
67const struct GNUNET_HELLO_Message *
68GCH_get_mine (void);
69
70
71#if 0 /* keep Emacsens' auto-indent happy */
72{
73#endif
74#ifdef __cplusplus
75}
76#endif
77
78/* ifndef GNUNET_CADET_SERVICE_HELLO_H */
79#endif
80/* end of gnunet-cadet-service_hello.h */
diff --git a/src/cadet/gnunet-service-cadet-new_peer.c b/src/cadet/gnunet-service-cadet-new_peer.c
deleted file mode 100644
index fe40d76b6..000000000
--- a/src/cadet/gnunet-service-cadet-new_peer.c
+++ /dev/null
@@ -1,1282 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2001-2017 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 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 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file cadet/gnunet-service-cadet-new_peer.c
23 * @brief Information we track per peer.
24 * @author Bartlomiej Polot
25 * @author Christian Grothoff
26 *
27 * TODO:
28 * - optimize stopping/restarting DHT search to situations
29 * where we actually need it (i.e. not if we have a direct connection,
30 * or if we already have plenty of good short ones, or maybe even
31 * to take a break if we have some connections and have searched a lot (?))
32 * - optimize MQM ready scans (O(n) -> O(1))
33 */
34#include "platform.h"
35#include "gnunet_util_lib.h"
36#include "gnunet_hello_lib.h"
37#include "gnunet_signatures.h"
38#include "gnunet_transport_service.h"
39#include "gnunet_ats_service.h"
40#include "gnunet_core_service.h"
41#include "gnunet_statistics_service.h"
42#include "cadet_protocol.h"
43#include "gnunet-service-cadet-new.h"
44#include "gnunet-service-cadet-new_connection.h"
45#include "gnunet-service-cadet-new_dht.h"
46#include "gnunet-service-cadet-new_peer.h"
47#include "gnunet-service-cadet-new_paths.h"
48#include "gnunet-service-cadet-new_tunnels.h"
49
50
51#define LOG(level, ...) GNUNET_log_from(level,"cadet-per",__VA_ARGS__)
52
53
54/**
55 * How long do we wait until tearing down an idle peer?
56 */
57#define IDLE_PEER_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 5)
58
59/**
60 * How long do we keep paths around if we no longer care about the peer?
61 */
62#define IDLE_PATH_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2)
63
64
65
66
67/**
68 * Data structure used to track whom we have to notify about changes
69 * to our message queue.
70 */
71struct GCP_MessageQueueManager
72{
73
74 /**
75 * Kept in a DLL.
76 */
77 struct GCP_MessageQueueManager *next;
78
79 /**
80 * Kept in a DLL.
81 */
82 struct GCP_MessageQueueManager *prev;
83
84 /**
85 * Function to call with updated message queue object.
86 */
87 GCP_MessageQueueNotificationCallback cb;
88
89 /**
90 * Closure for @e cb.
91 */
92 void *cb_cls;
93
94 /**
95 * The peer this is for.
96 */
97 struct CadetPeer *cp;
98
99 /**
100 * Envelope this manager would like to transmit once it is its turn.
101 */
102 struct GNUNET_MQ_Envelope *env;
103
104};
105
106
107/**
108 * Struct containing all information regarding a given peer
109 */
110struct CadetPeer
111{
112 /**
113 * ID of the peer
114 */
115 struct GNUNET_PeerIdentity pid;
116
117 /**
118 * Last time we heard from this peer
119 */
120 struct GNUNET_TIME_Absolute last_contact;
121
122 /**
123 * Array of DLLs of paths traversing the peer, organized by the
124 * offset of the peer on the larger path.
125 */
126 struct CadetPeerPathEntry **path_heads;
127
128 /**
129 * Array of DLL of paths traversing the peer, organized by the
130 * offset of the peer on the larger path.
131 */
132 struct CadetPeerPathEntry **path_tails;
133
134 /**
135 * Notifications to call when @e core_mq changes.
136 */
137 struct GCP_MessageQueueManager *mqm_head;
138
139 /**
140 * Notifications to call when @e core_mq changes.
141 */
142 struct GCP_MessageQueueManager *mqm_tail;
143
144 /**
145 * MIN-heap of paths owned by this peer (they also end at this
146 * peer). Ordered by desirability.
147 */
148 struct GNUNET_CONTAINER_Heap *path_heap;
149
150 /**
151 * Handle to stop the DHT search for paths to this peer
152 */
153 struct GCD_search_handle *search_h;
154
155 /**
156 * Task to stop the DHT search for paths to this peer
157 */
158 struct GNUNET_SCHEDULER_Task *search_delayedXXX;
159
160 /**
161 * Task to destroy this entry.
162 */
163 struct GNUNET_SCHEDULER_Task *destroy_task;
164
165 /**
166 * Tunnel to this peer, if any.
167 */
168 struct CadetTunnel *t;
169
170 /**
171 * Connections that go through this peer; indexed by tid.
172 */
173 struct GNUNET_CONTAINER_MultiShortmap *connections;
174
175 /**
176 * Handle for core transmissions.
177 */
178 struct GNUNET_MQ_Handle *core_mq;
179
180 /**
181 * Hello message of the peer.
182 */
183 struct GNUNET_HELLO_Message *hello;
184
185 /**
186 * Handle to us offering the HELLO to the transport.
187 */
188 struct GNUNET_TRANSPORT_OfferHelloHandle *hello_offer;
189
190 /**
191 * Handle to our ATS request asking ATS to suggest an address
192 * to TRANSPORT for this peer (to establish a direct link).
193 */
194 struct GNUNET_ATS_ConnectivitySuggestHandle *connectivity_suggestion;
195
196 /**
197 * How many messages are in the queue to this peer.
198 */
199 unsigned int queue_n;
200
201 /**
202 * How many paths do we have to this peer (in all @e path_heads DLLs combined).
203 */
204 unsigned int num_paths;
205
206 /**
207 * Number of message queue managers of this peer that have a message in waiting.
208 *
209 * Used to quickly see if we need to bother scanning the @e msm_head DLL.
210 * TODO: could be replaced by another DLL that would then allow us to avoid
211 * the O(n)-scan of the DLL for ready entries!
212 */
213 unsigned int mqm_ready_counter;
214
215 /**
216 * Current length of the @e path_heads and @path_tails arrays.
217 * The arrays should be grown as needed.
218 */
219 unsigned int path_dll_length;
220
221};
222
223
224/**
225 * Get the static string for a peer ID.
226 *
227 * @param cp Peer.
228 * @return Static string for it's ID.
229 */
230const char *
231GCP_2s (const struct CadetPeer *cp)
232{
233 static char buf[32];
234
235 GNUNET_snprintf (buf,
236 sizeof (buf),
237 "P(%s)",
238 GNUNET_i2s (&cp->pid));
239 return buf;
240}
241
242
243/**
244 * This peer is no longer be needed, clean it up now.
245 *
246 * @param cls peer to clean up
247 */
248static void
249destroy_peer (void *cls)
250{
251 struct CadetPeer *cp = cls;
252
253 LOG (GNUNET_ERROR_TYPE_DEBUG,
254 "Destroying state about peer %s\n",
255 GCP_2s (cp));
256 cp->destroy_task = NULL;
257 GNUNET_assert (NULL == cp->t);
258 GNUNET_assert (NULL == cp->core_mq);
259 for (unsigned int i=0;i<cp->path_dll_length;i++)
260 GNUNET_assert (NULL == cp->path_heads[i]);
261 GNUNET_assert (0 == GNUNET_CONTAINER_multishortmap_size (cp->connections));
262 GNUNET_assert (GNUNET_YES ==
263 GNUNET_CONTAINER_multipeermap_remove (peers,
264 &cp->pid,
265 cp));
266 GNUNET_free_non_null (cp->path_heads);
267 GNUNET_free_non_null (cp->path_tails);
268 cp->path_dll_length = 0;
269 if (NULL != cp->search_h)
270 {
271 GCD_search_stop (cp->search_h);
272 cp->search_h = NULL;
273 }
274 /* FIXME: clean up search_delayedXXX! */
275
276 if (NULL != cp->hello_offer)
277 {
278 GNUNET_TRANSPORT_offer_hello_cancel (cp->hello_offer);
279 cp->hello_offer = NULL;
280 }
281 if (NULL != cp->connectivity_suggestion)
282 {
283 GNUNET_ATS_connectivity_suggest_cancel (cp->connectivity_suggestion);
284 cp->connectivity_suggestion = NULL;
285 }
286 GNUNET_CONTAINER_multishortmap_destroy (cp->connections);
287 if (NULL != cp->path_heap)
288 {
289 GNUNET_CONTAINER_heap_destroy (cp->path_heap);
290 cp->path_heap = NULL;
291 }
292 GNUNET_free_non_null (cp->hello);
293 /* Peer should not be freed if paths exist; if there are no paths,
294 there ought to be no connections, and without connections, no
295 notifications. Thus we can assert that mqm_head is empty at this
296 point. */
297 GNUNET_assert (NULL == cp->mqm_head);
298 GNUNET_free (cp);
299}
300
301
302/**
303 * This peer is now on more "active" duty, activate processes related to it.
304 *
305 * @param cp the more-active peer
306 */
307static void
308consider_peer_activate (struct CadetPeer *cp)
309{
310 uint32_t strength;
311
312 LOG (GNUNET_ERROR_TYPE_DEBUG,
313 "Updating peer %s activation state (%u connections)%s%s\n",
314 GCP_2s (cp),
315 GNUNET_CONTAINER_multishortmap_size (cp->connections),
316 (NULL == cp->t) ? "" : " with tunnel",
317 (NULL == cp->core_mq) ? "" : " with CORE link");
318 if (NULL != cp->destroy_task)
319 {
320 /* It's active, do not destory! */
321 GNUNET_SCHEDULER_cancel (cp->destroy_task);
322 cp->destroy_task = NULL;
323 }
324 if ( (0 == GNUNET_CONTAINER_multishortmap_size (cp->connections)) &&
325 (NULL == cp->t) )
326 {
327 /* We're just on a path or directly connected; don't bother too much */
328 if (NULL != cp->connectivity_suggestion)
329 {
330 GNUNET_ATS_connectivity_suggest_cancel (cp->connectivity_suggestion);
331 cp->connectivity_suggestion = NULL;
332 }
333 if (NULL != cp->search_h)
334 {
335 GCD_search_stop (cp->search_h);
336 cp->search_h = NULL;
337 }
338 return;
339 }
340 if (NULL == cp->core_mq)
341 {
342 /* Lacks direct connection, try to create one by querying the DHT */
343 if ( (NULL == cp->search_h) &&
344 (DESIRED_CONNECTIONS_PER_TUNNEL > cp->num_paths) )
345 cp->search_h
346 = GCD_search (&cp->pid);
347 }
348 else
349 {
350 /* Have direct connection, stop DHT search if active */
351 if (NULL != cp->search_h)
352 {
353 GCD_search_stop (cp->search_h);
354 cp->search_h = NULL;
355 }
356 }
357
358 /* If we have a tunnel, our urge for connections is much bigger */
359 strength = (NULL != cp->t) ? 32 : 1;
360 if (NULL != cp->connectivity_suggestion)
361 GNUNET_ATS_connectivity_suggest_cancel (cp->connectivity_suggestion);
362 cp->connectivity_suggestion
363 = GNUNET_ATS_connectivity_suggest (ats_ch,
364 &cp->pid,
365 strength);
366}
367
368
369/**
370 * This peer may no longer be needed, consider cleaning it up.
371 *
372 * @param cp peer to clean up
373 */
374static void
375consider_peer_destroy (struct CadetPeer *cp);
376
377
378/**
379 * We really no longere care about a peer, stop hogging memory with paths to it.
380 * Afterwards, see if there is more to be cleaned up about this peer.
381 *
382 * @param cls a `struct CadetPeer`.
383 */
384static void
385drop_paths (void *cls)
386{
387 struct CadetPeer *cp = cls;
388 struct CadetPeerPath *path;
389
390 cp->destroy_task = NULL;
391 while (NULL != (path = GNUNET_CONTAINER_heap_remove_root (cp->path_heap)))
392 GCPP_release (path);
393 consider_peer_destroy (cp);
394}
395
396
397/**
398 * This peer may no longer be needed, consider cleaning it up.
399 *
400 * @param cp peer to clean up
401 */
402static void
403consider_peer_destroy (struct CadetPeer *cp)
404{
405 struct GNUNET_TIME_Relative exp;
406
407 if (NULL != cp->destroy_task)
408 {
409 GNUNET_SCHEDULER_cancel (cp->destroy_task);
410 cp->destroy_task = NULL;
411 }
412 if (NULL != cp->t)
413 return; /* still relevant! */
414 if (NULL != cp->core_mq)
415 return; /* still relevant! */
416 if (0 != GNUNET_CONTAINER_multishortmap_size (cp->connections))
417 return; /* still relevant! */
418 if (0 < GNUNET_CONTAINER_heap_get_size (cp->path_heap))
419 {
420 cp->destroy_task = GNUNET_SCHEDULER_add_delayed (IDLE_PATH_TIMEOUT,
421 &drop_paths,
422 cp);
423 return;
424 }
425 for (unsigned int i=0;i<cp->path_dll_length;i++)
426 if (NULL != cp->path_heads[i])
427 return; /* still relevant! */
428 if (NULL != cp->hello)
429 {
430 /* relevant only until HELLO expires */
431 exp = GNUNET_TIME_absolute_get_remaining (GNUNET_HELLO_get_last_expiration (cp->hello));
432 cp->destroy_task = GNUNET_SCHEDULER_add_delayed (exp,
433 &destroy_peer,
434 cp);
435 return;
436 }
437 cp->destroy_task = GNUNET_SCHEDULER_add_delayed (IDLE_PEER_TIMEOUT,
438 &destroy_peer,
439 cp);
440}
441
442
443/**
444 * Set the message queue to @a mq for peer @a cp and notify watchers.
445 *
446 * @param cp peer to modify
447 * @param mq message queue to set (can be NULL)
448 */
449void
450GCP_set_mq (struct CadetPeer *cp,
451 struct GNUNET_MQ_Handle *mq)
452{
453 LOG (GNUNET_ERROR_TYPE_DEBUG,
454 "Message queue for peer %s is now %p\n",
455 GCP_2s (cp),
456 mq);
457 cp->core_mq = mq;
458 for (struct GCP_MessageQueueManager *mqm = cp->mqm_head;
459 NULL != mqm;
460 mqm = mqm->next)
461 {
462 if (NULL == mq)
463 {
464 if (NULL != mqm->env)
465 {
466 GNUNET_MQ_discard (mqm->env);
467 mqm->env = NULL;
468 mqm->cb (mqm->cb_cls,
469 GNUNET_SYSERR);
470 }
471 else
472 {
473 mqm->cb (mqm->cb_cls,
474 GNUNET_NO);
475 }
476 }
477 else
478 {
479 GNUNET_assert (NULL == mqm->env);
480 mqm->cb (mqm->cb_cls,
481 GNUNET_YES);
482 }
483 }
484 if ( (NULL != mq) ||
485 (NULL != cp->t) )
486 consider_peer_activate (cp);
487 else
488 consider_peer_destroy (cp);
489
490 if ( (NULL != mq) &&
491 (NULL != cp->t) )
492 {
493 /* have a new, direct path to the target, notify tunnel */
494 struct CadetPeerPath *path;
495
496 path = GCPP_get_path_from_route (1,
497 &cp->pid);
498 GCT_consider_path (cp->t,
499 path,
500 0);
501 }
502}
503
504
505/**
506 * Transmit current envelope from this @a mqm.
507 *
508 * @param mqm mqm to transmit message for now
509 */
510static void
511mqm_execute (struct GCP_MessageQueueManager *mqm)
512{
513 struct CadetPeer *cp = mqm->cp;
514
515 LOG (GNUNET_ERROR_TYPE_DEBUG,
516 "Sending to peer %s from MQM %p\n",
517 GCP_2s (cp),
518 mqm);
519 /* Move entry to the end of the DLL, to be fair. */
520 if (mqm != cp->mqm_tail)
521 {
522 GNUNET_CONTAINER_DLL_remove (cp->mqm_head,
523 cp->mqm_tail,
524 mqm);
525 GNUNET_CONTAINER_DLL_insert_tail (cp->mqm_head,
526 cp->mqm_tail,
527 mqm);
528 }
529 GNUNET_MQ_send (cp->core_mq,
530 mqm->env);
531 mqm->env = NULL;
532 cp->mqm_ready_counter--;
533 mqm->cb (mqm->cb_cls,
534 GNUNET_YES);
535}
536
537
538/**
539 * Function called when CORE took one of the messages from
540 * a message queue manager and transmitted it.
541 *
542 * @param cls the `struct CadetPeeer` where we made progress
543 */
544static void
545mqm_send_done (void *cls)
546{
547 struct CadetPeer *cp = cls;
548
549 LOG (GNUNET_ERROR_TYPE_DEBUG,
550 "Sending to peer %s completed\n",
551 GCP_2s (cp));
552 if (0 == cp->mqm_ready_counter)
553 return; /* nothing to do */
554 for (struct GCP_MessageQueueManager *mqm = cp->mqm_head;
555 NULL != mqm;
556 mqm = mqm->next)
557 {
558 if (NULL == mqm->env)
559 continue;
560 mqm_execute (mqm);
561 return;
562 }
563}
564
565
566/**
567 * Send the message in @a env to @a cp.
568 *
569 * @param mqm the message queue manager to use for transmission
570 * @param env envelope with the message to send; must NOT
571 * yet have a #GNUNET_MQ_notify_sent() callback attached to it
572 */
573void
574GCP_send (struct GCP_MessageQueueManager *mqm,
575 struct GNUNET_MQ_Envelope *env)
576{
577 struct CadetPeer *cp = mqm->cp;
578
579 LOG (GNUNET_ERROR_TYPE_DEBUG,
580 "Queueing message to peer %s in MQM %p\n",
581 GCP_2s (cp),
582 mqm);
583 GNUNET_assert (NULL != cp->core_mq);
584 GNUNET_assert (NULL == mqm->env);
585 GNUNET_MQ_notify_sent (env,
586 &mqm_send_done,
587 cp);
588 mqm->env = env;
589 cp->mqm_ready_counter++;
590 if (0 != GNUNET_MQ_get_length (cp->core_mq))
591 return;
592 mqm_execute (mqm);
593}
594
595
596/**
597 * Function called to destroy a peer now.
598 *
599 * @param cls NULL
600 * @param pid identity of the peer (unused)
601 * @param value the `struct CadetPeer` to clean up
602 * @return #GNUNET_OK (continue to iterate)
603 */
604static int
605destroy_iterator_cb (void *cls,
606 const struct GNUNET_PeerIdentity *pid,
607 void *value)
608{
609 struct CadetPeer *cp = value;
610
611 if (NULL != cp->destroy_task)
612 {
613 GNUNET_SCHEDULER_cancel (cp->destroy_task);
614 cp->destroy_task = NULL;
615 }
616 destroy_peer (cp);
617 return GNUNET_OK;
618}
619
620
621/**
622 * Clean up all entries about all peers.
623 * Must only be called after all tunnels, CORE-connections and
624 * connections are down.
625 */
626void
627GCP_destroy_all_peers ()
628{
629 LOG (GNUNET_ERROR_TYPE_DEBUG,
630 "Destroying all peers now\n");
631 GNUNET_CONTAINER_multipeermap_iterate (peers,
632 &destroy_iterator_cb,
633 NULL);
634}
635
636
637/**
638 * Drop all paths owned by this peer, and do not
639 * allow new ones to be added: We are shutting down.
640 *
641 * @param cp peer to drop paths to
642 */
643void
644GCP_drop_owned_paths (struct CadetPeer *cp)
645{
646 struct CadetPeerPath *path;
647
648 LOG (GNUNET_ERROR_TYPE_DEBUG,
649 "Destroying all paths to %s\n",
650 GCP_2s (cp));
651 while (NULL != (path =
652 GNUNET_CONTAINER_heap_remove_root (cp->path_heap)))
653 GCPP_release (path);
654 GNUNET_CONTAINER_heap_destroy (cp->path_heap);
655 cp->path_heap = NULL;
656}
657
658
659/**
660 * Add an entry to the DLL of all of the paths that this peer is on.
661 *
662 * @param cp peer to modify
663 * @param entry an entry on a path
664 * @param off offset of this peer on the path
665 */
666void
667GCP_path_entry_add (struct CadetPeer *cp,
668 struct CadetPeerPathEntry *entry,
669 unsigned int off)
670{
671 GNUNET_assert (cp == GCPP_get_peer_at_offset (entry->path,
672 off));
673 LOG (GNUNET_ERROR_TYPE_DEBUG,
674 "Discovered that peer %s is on path %s at offset %u\n",
675 GCP_2s (cp),
676 GCPP_2s (entry->path),
677 off);
678 if (off >= cp->path_dll_length)
679 {
680 unsigned int len = cp->path_dll_length;
681
682 GNUNET_array_grow (cp->path_heads,
683 len,
684 off + 4);
685 GNUNET_array_grow (cp->path_tails,
686 cp->path_dll_length,
687 off + 4);
688 }
689 GNUNET_CONTAINER_DLL_insert (cp->path_heads[off],
690 cp->path_tails[off],
691 entry);
692 cp->num_paths++;
693
694 /* If we have a tunnel to this peer, tell the tunnel that there is a
695 new path available. */
696 if (NULL != cp->t)
697 GCT_consider_path (cp->t,
698 entry->path,
699 off);
700
701 if ( (NULL != cp->search_h) &&
702 (DESIRED_CONNECTIONS_PER_TUNNEL <= cp->num_paths) )
703 {
704 /* Now I have enough paths, stop search */
705 GCD_search_stop (cp->search_h);
706 cp->search_h = NULL;
707 }
708}
709
710
711/**
712 * Remove an entry from the DLL of all of the paths that this peer is on.
713 *
714 * @param cp peer to modify
715 * @param entry an entry on a path
716 * @param off offset of this peer on the path
717 */
718void
719GCP_path_entry_remove (struct CadetPeer *cp,
720 struct CadetPeerPathEntry *entry,
721 unsigned int off)
722{
723 LOG (GNUNET_ERROR_TYPE_DEBUG,
724 "Removing knowledge about peer %s beging on path %s at offset %u\n",
725 GCP_2s (cp),
726 GCPP_2s (entry->path),
727 off);
728 GNUNET_CONTAINER_DLL_remove (cp->path_heads[off],
729 cp->path_tails[off],
730 entry);
731 GNUNET_assert (0 < cp->num_paths);
732 cp->num_paths--;
733 if ( (NULL == cp->core_mq) &&
734 (NULL != cp->t) &&
735 (NULL == cp->search_h) &&
736 (DESIRED_CONNECTIONS_PER_TUNNEL > cp->num_paths) )
737 cp->search_h
738 = GCD_search (&cp->pid);
739}
740
741
742/**
743 * Try adding a @a path to this @a peer. If the peer already
744 * has plenty of paths, return NULL.
745 *
746 * @param cp peer to which the @a path leads to
747 * @param path a path looking for an owner; may not be fully initialized yet!
748 * @param off offset of @a cp in @a path
749 * @param force force attaching the path
750 * @return NULL if this peer does not care to become a new owner,
751 * otherwise the node in the peer's path heap for the @a path.
752 */
753struct GNUNET_CONTAINER_HeapNode *
754GCP_attach_path (struct CadetPeer *cp,
755 struct CadetPeerPath *path,
756 unsigned int off,
757 int force)
758{
759 GNUNET_CONTAINER_HeapCostType desirability;
760 struct CadetPeerPath *root;
761 GNUNET_CONTAINER_HeapCostType root_desirability;
762 struct GNUNET_CONTAINER_HeapNode *hn;
763
764 GNUNET_assert (cp == GCPP_get_peer_at_offset (path,
765 off));
766 if (NULL == cp->path_heap)
767 {
768 /* #GCP_drop_owned_paths() was already called, we cannot take new ones! */
769 GNUNET_assert (GNUNET_NO == force);
770 return NULL;
771 }
772 desirability = GCPP_get_desirability (path);
773 if (GNUNET_NO == force)
774 {
775 /* FIXME: desirability is not yet initialized; tricky! */
776 if (GNUNET_NO ==
777 GNUNET_CONTAINER_heap_peek2 (cp->path_heap,
778 (void **) &root,
779 &root_desirability))
780 {
781 root = NULL;
782 root_desirability = 0;
783 }
784
785 if ( (DESIRED_CONNECTIONS_PER_TUNNEL > cp->num_paths) &&
786 (desirability < root_desirability) )
787 {
788 LOG (GNUNET_ERROR_TYPE_DEBUG,
789 "Decided to not attach path %p to peer %s due to undesirability\n",
790 GCPP_2s (path),
791 GCP_2s (cp));
792 return NULL;
793 }
794 }
795
796 LOG (GNUNET_ERROR_TYPE_DEBUG,
797 "Attaching path %s to peer %s (%s)\n",
798 GCPP_2s (path),
799 GCP_2s (cp),
800 (GNUNET_NO == force) ? "desirable" : "forced");
801
802 /* Yes, we'd like to add this path, add to our heap */
803 hn = GNUNET_CONTAINER_heap_insert (cp->path_heap,
804 path,
805 desirability);
806
807 /* Consider maybe dropping other paths because of the new one */
808 if (GNUNET_CONTAINER_heap_get_size (cp->path_heap) >=
809 2 * DESIRED_CONNECTIONS_PER_TUNNEL)
810 {
811 /* Now we have way too many, drop least desirable UNLESS it is in use!
812 (Note that this intentionally keeps highly desireable, but currently
813 unused paths around in the hope that we might be able to switch, even
814 if the number of paths exceeds the threshold.) */
815 root = GNUNET_CONTAINER_heap_peek (cp->path_heap);
816 if ( (path != root) &&
817 (NULL ==
818 GCPP_get_connection (root,
819 cp,
820 GCPP_get_length (root) - 1)) )
821 {
822 /* Got plenty of paths to this destination, and this is a low-quality
823 one that we don't care, allow it to die. */
824 GNUNET_assert (root ==
825 GNUNET_CONTAINER_heap_remove_root (cp->path_heap));
826 GCPP_release (root);
827 }
828 }
829 return hn;
830}
831
832
833/**
834 * This peer can no longer own @a path as the path
835 * has been extended and a peer further down the line
836 * is now the new owner.
837 *
838 * @param cp old owner of the @a path
839 * @param path path where the ownership is lost
840 * @param hn note in @a cp's path heap that must be deleted
841 */
842void
843GCP_detach_path (struct CadetPeer *cp,
844 struct CadetPeerPath *path,
845 struct GNUNET_CONTAINER_HeapNode *hn)
846{
847 LOG (GNUNET_ERROR_TYPE_DEBUG,
848 "Detatching path %s from peer %s\n",
849 GCPP_2s (path),
850 GCP_2s (cp));
851 GNUNET_assert (path ==
852 GNUNET_CONTAINER_heap_remove_node (hn));
853}
854
855
856/**
857 * Add a @a connection to this @a cp.
858 *
859 * @param cp peer via which the @a connection goes
860 * @param cc the connection to add
861 */
862void
863GCP_add_connection (struct CadetPeer *cp,
864 struct CadetConnection *cc)
865{
866 LOG (GNUNET_ERROR_TYPE_DEBUG,
867 "Adding connection %s to peer %s\n",
868 GCC_2s (cc),
869 GCP_2s (cp));
870 GNUNET_assert (GNUNET_OK ==
871 GNUNET_CONTAINER_multishortmap_put (cp->connections,
872 &GCC_get_id (cc)->connection_of_tunnel,
873 cc,
874 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
875}
876
877
878/**
879 * Remove a @a connection that went via this @a cp.
880 *
881 * @param cp peer via which the @a connection went
882 * @param cc the connection to remove
883 */
884void
885GCP_remove_connection (struct CadetPeer *cp,
886 struct CadetConnection *cc)
887{
888 LOG (GNUNET_ERROR_TYPE_DEBUG,
889 "Removing connection %s from peer %s\n",
890 GCC_2s (cc),
891 GCP_2s (cp));
892 GNUNET_assert (GNUNET_YES ==
893 GNUNET_CONTAINER_multishortmap_remove (cp->connections,
894 &GCC_get_id (cc)->connection_of_tunnel,
895 cc));
896}
897
898
899/**
900 * Retrieve the CadetPeer stucture associated with the
901 * peer. Optionally create one and insert it in the appropriate
902 * structures if the peer is not known yet.
903 *
904 * @param peer_id Full identity of the peer.
905 * @param create #GNUNET_YES if a new peer should be created if unknown.
906 * #GNUNET_NO to return NULL if peer is unknown.
907 * @return Existing or newly created peer structure.
908 * NULL if unknown and not requested @a create
909 */
910struct CadetPeer *
911GCP_get (const struct GNUNET_PeerIdentity *peer_id,
912 int create)
913{
914 struct CadetPeer *cp;
915
916 cp = GNUNET_CONTAINER_multipeermap_get (peers,
917 peer_id);
918 if (NULL != cp)
919 return cp;
920 if (GNUNET_NO == create)
921 return NULL;
922 cp = GNUNET_new (struct CadetPeer);
923 cp->pid = *peer_id;
924 cp->connections = GNUNET_CONTAINER_multishortmap_create (32,
925 GNUNET_YES);
926 cp->path_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
927 GNUNET_assert (GNUNET_YES ==
928 GNUNET_CONTAINER_multipeermap_put (peers,
929 &cp->pid,
930 cp,
931 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
932 LOG (GNUNET_ERROR_TYPE_DEBUG,
933 "Creating peer %s\n",
934 GCP_2s (cp));
935 return cp;
936}
937
938
939/**
940 * Obtain the peer identity for a `struct CadetPeer`.
941 *
942 * @param cp our peer handle
943 * @return the peer identity
944 */
945const struct GNUNET_PeerIdentity *
946GCP_get_id (struct CadetPeer *cp)
947{
948 return &cp->pid;
949}
950
951
952/**
953 * Iterate over all known peers.
954 *
955 * @param iter Iterator.
956 * @param cls Closure for @c iter.
957 */
958void
959GCP_iterate_all (GNUNET_CONTAINER_PeerMapIterator iter,
960 void *cls)
961{
962 GNUNET_CONTAINER_multipeermap_iterate (peers,
963 iter,
964 cls);
965}
966
967
968/**
969 * Count the number of known paths toward the peer.
970 *
971 * @param cp Peer to get path info.
972 * @return Number of known paths.
973 */
974unsigned int
975GCP_count_paths (const struct CadetPeer *cp)
976{
977 return cp->num_paths;
978}
979
980
981/**
982 * Iterate over the paths to a peer.
983 *
984 * @param cp Peer to get path info.
985 * @param callback Function to call for every path.
986 * @param callback_cls Closure for @a callback.
987 * @return Number of iterated paths.
988 */
989unsigned int
990GCP_iterate_paths (struct CadetPeer *cp,
991 GCP_PathIterator callback,
992 void *callback_cls)
993{
994 unsigned int ret = 0;
995
996 LOG (GNUNET_ERROR_TYPE_DEBUG,
997 "Iterating over paths to peer %s%s\n",
998 GCP_2s (cp),
999 (NULL == cp->core_mq) ? "" : " including direct link");
1000 if (NULL != cp->core_mq)
1001 {
1002 struct CadetPeerPath *path;
1003
1004 path = GCPP_get_path_from_route (1,
1005 &cp->pid);
1006 ret++;
1007 if (GNUNET_NO ==
1008 callback (callback_cls,
1009 path,
1010 1))
1011 return ret;
1012 }
1013 for (unsigned int i=0;i<cp->path_dll_length;i++)
1014 {
1015 for (struct CadetPeerPathEntry *pe = cp->path_heads[i];
1016 NULL != pe;
1017 pe = pe->next)
1018 {
1019 ret++;
1020 if (GNUNET_NO ==
1021 callback (callback_cls,
1022 pe->path,
1023 i))
1024 return ret;
1025 }
1026 }
1027 return ret;
1028}
1029
1030
1031/**
1032 * Iterate over the paths to @a cp where
1033 * @a cp is at distance @a dist from us.
1034 *
1035 * @param cp Peer to get path info.
1036 * @param dist desired distance of @a cp to us on the path
1037 * @param callback Function to call for every path.
1038 * @param callback_cls Closure for @a callback.
1039 * @return Number of iterated paths.
1040 */
1041unsigned int
1042GCP_iterate_paths_at (struct CadetPeer *cp,
1043 unsigned int dist,
1044 GCP_PathIterator callback,
1045 void *callback_cls)
1046{
1047 unsigned int ret = 0;
1048
1049 if (dist >= cp->path_dll_length)
1050 {
1051 LOG (GNUNET_ERROR_TYPE_DEBUG,
1052 "Asked to look for paths at distance %u, but maximum for me is < %u\n",
1053 dist,
1054 cp->path_dll_length);
1055 return 0;
1056 }
1057 for (struct CadetPeerPathEntry *pe = cp->path_heads[dist];
1058 NULL != pe;
1059 pe = pe->next)
1060 {
1061 if (GNUNET_NO ==
1062 callback (callback_cls,
1063 pe->path,
1064 dist))
1065 return ret;
1066 ret++;
1067 }
1068 return ret;
1069}
1070
1071
1072/**
1073 * Get the tunnel towards a peer.
1074 *
1075 * @param cp Peer to get from.
1076 * @param create #GNUNET_YES to create a tunnel if we do not have one
1077 * @return Tunnel towards peer.
1078 */
1079struct CadetTunnel *
1080GCP_get_tunnel (struct CadetPeer *cp,
1081 int create)
1082{
1083 if (NULL == cp)
1084 return NULL;
1085 if ( (NULL != cp->t) ||
1086 (GNUNET_NO == create) )
1087 return cp->t;
1088 cp->t = GCT_create_tunnel (cp);
1089 consider_peer_activate (cp);
1090 return cp->t;
1091}
1092
1093
1094/**
1095 * Hello offer was passed to the transport service. Mark it
1096 * as done.
1097 *
1098 * @param cls the `struct CadetPeer` where the offer completed
1099 */
1100static void
1101hello_offer_done (void *cls)
1102{
1103 struct CadetPeer *cp = cls;
1104
1105 cp->hello_offer = NULL;
1106}
1107
1108
1109/**
1110 * We got a HELLO for a @a peer, remember it, and possibly
1111 * trigger adequate actions (like trying to connect).
1112 *
1113 * @param cp the peer we got a HELLO for
1114 * @param hello the HELLO to remember
1115 */
1116void
1117GCP_set_hello (struct CadetPeer *cp,
1118 const struct GNUNET_HELLO_Message *hello)
1119{
1120 struct GNUNET_HELLO_Message *mrg;
1121
1122 LOG (GNUNET_ERROR_TYPE_DEBUG,
1123 "Got %u byte HELLO for peer %s\n",
1124 (unsigned int) GNUNET_HELLO_size (hello),
1125 GCP_2s (cp));
1126 if (NULL != cp->hello_offer)
1127 {
1128 GNUNET_TRANSPORT_offer_hello_cancel (cp->hello_offer);
1129 cp->hello_offer = NULL;
1130 }
1131 if (NULL != cp->hello)
1132 {
1133 mrg = GNUNET_HELLO_merge (hello,
1134 cp->hello);
1135 GNUNET_free (cp->hello);
1136 cp->hello = mrg;
1137 }
1138 else
1139 {
1140 cp->hello = GNUNET_memdup (hello,
1141 GNUNET_HELLO_size (hello));
1142 }
1143 cp->hello_offer
1144 = GNUNET_TRANSPORT_offer_hello (cfg,
1145 GNUNET_HELLO_get_header (cp->hello) ,
1146 &hello_offer_done,
1147 cp);
1148 /* New HELLO means cp's destruction time may change... */
1149 consider_peer_destroy (cp);
1150}
1151
1152
1153/**
1154 * The tunnel to the given peer no longer exists, remove it from our
1155 * data structures, and possibly clean up the peer itself.
1156 *
1157 * @param cp the peer affected
1158 * @param t the dead tunnel
1159 */
1160void
1161GCP_drop_tunnel (struct CadetPeer *cp,
1162 struct CadetTunnel *t)
1163{
1164 LOG (GNUNET_ERROR_TYPE_DEBUG,
1165 "Dropping tunnel %s to peer %s\n",
1166 GCT_2s (t),
1167 GCP_2s (cp));
1168 GNUNET_assert (cp->t == t);
1169 cp->t = NULL;
1170 consider_peer_destroy (cp);
1171}
1172
1173
1174/**
1175 * Test if @a cp has a core-level connection
1176 *
1177 * @param cp peer to test
1178 * @return #GNUNET_YES if @a cp has a core-level connection
1179 */
1180int
1181GCP_has_core_connection (struct CadetPeer *cp)
1182{
1183 return (NULL != cp->core_mq) ? GNUNET_YES : GNUNET_NO;
1184}
1185
1186
1187/**
1188 * Start message queue change notifications.
1189 *
1190 * @param cp peer to notify for
1191 * @param cb function to call if mq becomes available or unavailable
1192 * @param cb_cls closure for @a cb
1193 * @return handle to cancel request
1194 */
1195struct GCP_MessageQueueManager *
1196GCP_request_mq (struct CadetPeer *cp,
1197 GCP_MessageQueueNotificationCallback cb,
1198 void *cb_cls)
1199{
1200 struct GCP_MessageQueueManager *mqm;
1201
1202 mqm = GNUNET_new (struct GCP_MessageQueueManager);
1203 mqm->cb = cb;
1204 mqm->cb_cls = cb_cls;
1205 mqm->cp = cp;
1206 GNUNET_CONTAINER_DLL_insert (cp->mqm_head,
1207 cp->mqm_tail,
1208 mqm);
1209 LOG (GNUNET_ERROR_TYPE_DEBUG,
1210 "Creating MQM %p for peer %s\n",
1211 mqm,
1212 GCP_2s (cp));
1213 if (NULL != cp->core_mq)
1214 cb (cb_cls,
1215 GNUNET_YES);
1216 return mqm;
1217}
1218
1219
1220/**
1221 * Stops message queue change notifications.
1222 *
1223 * @param mqm handle matching request to cancel
1224 * @param last_env final message to transmit, or NULL
1225 */
1226void
1227GCP_request_mq_cancel (struct GCP_MessageQueueManager *mqm,
1228 struct GNUNET_MQ_Envelope *last_env)
1229{
1230 struct CadetPeer *cp = mqm->cp;
1231
1232 LOG (GNUNET_ERROR_TYPE_DEBUG,
1233 "Destroying MQM %p for peer %s%s\n",
1234 mqm,
1235 GCP_2s (cp),
1236 (NULL == last_env) ? "" : " with last ditch transmission");
1237 if (NULL != mqm->env)
1238 GNUNET_MQ_discard (mqm->env);
1239 if (NULL != last_env)
1240 {
1241 if (NULL != cp->core_mq)
1242 GNUNET_MQ_send (cp->core_mq,
1243 last_env);
1244 else
1245 GNUNET_MQ_discard (last_env);
1246 }
1247 GNUNET_CONTAINER_DLL_remove (cp->mqm_head,
1248 cp->mqm_tail,
1249 mqm);
1250 GNUNET_free (mqm);
1251}
1252
1253
1254/**
1255 * Send the message in @a env to @a cp, overriding queueing logic.
1256 * This function should only be used to send error messages outside
1257 * of flow and congestion control, similar to ICMP. Note that
1258 * the envelope may be silently discarded as well.
1259 *
1260 * @param cp peer to send the message to
1261 * @param env envelope with the message to send
1262 */
1263void
1264GCP_send_ooo (struct CadetPeer *cp,
1265 struct GNUNET_MQ_Envelope *env)
1266{
1267 LOG (GNUNET_ERROR_TYPE_DEBUG,
1268 "Sending message to %s out of management\n",
1269 GCP_2s (cp));
1270 if (NULL == cp->core_mq)
1271 {
1272 GNUNET_MQ_discard (env);
1273 return;
1274 }
1275 GNUNET_MQ_send (cp->core_mq,
1276 env);
1277}
1278
1279
1280
1281
1282/* end of gnunet-service-cadet-new_peer.c */
diff --git a/src/cadet/gnunet-service-cadet-new_peer.h b/src/cadet/gnunet-service-cadet-new_peer.h
deleted file mode 100644
index aaaef15b8..000000000
--- a/src/cadet/gnunet-service-cadet-new_peer.h
+++ /dev/null
@@ -1,380 +0,0 @@
1
2/*
3 This file is part of GNUnet.
4 Copyright (C) 2001-2017 GNUnet e.V.
5
6 GNUnet is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published
8 by the Free Software Foundation; either version 3, or (at your
9 option) any later version.
10
11 GNUnet is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNUnet; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
20*/
21
22/**
23 * @file cadet/gnunet-service-cadet-new_peer.h
24 * @brief Information we track per peer.
25 * @author Bartlomiej Polot
26 * @author Christian Grothoff
27 */
28#ifndef GNUNET_SERVICE_CADET_PEER_H
29#define GNUNET_SERVICE_CADET_PEER_H
30
31#include "gnunet-service-cadet-new.h"
32#include "gnunet_hello_lib.h"
33
34
35/**
36 * Get the static string for a peer ID.
37 *
38 * @param peer Peer.
39 *
40 * @return Static string for it's ID.
41 */
42const char *
43GCP_2s (const struct CadetPeer *peer);
44
45
46/**
47 * Retrieve the CadetPeer stucture associated with the
48 * peer. Optionally create one and insert it in the appropriate
49 * structures if the peer is not known yet.
50 *
51 * @param peer_id Full identity of the peer.
52 * @param create #GNUNET_YES if a new peer should be created if unknown.
53 * #GNUNET_NO to return NULL if peer is unknown.
54 * @return Existing or newly created peer structure.
55 * NULL if unknown and not requested @a create
56 */
57struct CadetPeer *
58GCP_get (const struct GNUNET_PeerIdentity *peer_id,
59 int create);
60
61
62/**
63 * Obtain the peer identity for a `struct CadetPeer`.
64 *
65 * @param cp our peer handle
66 * @return the peer identity
67 */
68const struct GNUNET_PeerIdentity *
69GCP_get_id (struct CadetPeer *cp);
70
71
72/**
73 * Iterate over all known peers.
74 *
75 * @param iter Iterator.
76 * @param cls Closure for @c iter.
77 */
78void
79GCP_iterate_all (GNUNET_CONTAINER_PeerMapIterator iter,
80 void *cls);
81
82
83/**
84 * Count the number of known paths toward the peer.
85 *
86 * @param cp Peer to get path info.
87 * @return Number of known paths.
88 */
89unsigned int
90GCP_count_paths (const struct CadetPeer *cp);
91
92
93/**
94 * Drop all paths owned by this peer, and do not
95 * allow new ones to be added: We are shutting down.
96 *
97 * @param cp peer to drop paths to
98 */
99void
100GCP_drop_owned_paths (struct CadetPeer *cp);
101
102
103/**
104 * Peer path iterator.
105 *
106 * @param cls Closure.
107 * @param path Path itself
108 * @param off offset of the target peer in @a path
109 * @return #GNUNET_YES if should keep iterating.
110 * #GNUNET_NO otherwise.
111 */
112typedef int
113(*GCP_PathIterator) (void *cls,
114 struct CadetPeerPath *path,
115 unsigned int off);
116
117
118/**
119 * Iterate over the paths to a peer.
120 *
121 * @param cp Peer to get path info.
122 * @param callback Function to call for every path.
123 * @param callback_cls Closure for @a callback.
124 * @return Number of iterated paths.
125 */
126unsigned int
127GCP_iterate_paths (struct CadetPeer *cp,
128 GCP_PathIterator callback,
129 void *callback_cls);
130
131
132/**
133 * Iterate over the paths to @a peer where
134 * @a peer is at distance @a dist from us.
135 *
136 * @param cp Peer to get path info.
137 * @param dist desired distance of @a peer to us on the path
138 * @param callback Function to call for every path.
139 * @param callback_cls Closure for @a callback.
140 * @return Number of iterated paths.
141 */
142unsigned int
143GCP_iterate_paths_at (struct CadetPeer *cp,
144 unsigned int dist,
145 GCP_PathIterator callback,
146 void *callback_cls);
147
148
149/**
150 * Remove an entry from the DLL of all of the paths that this peer is on.
151 *
152 * @param cp peer to modify
153 * @param entry an entry on a path
154 * @param off offset of this peer on the path
155 */
156void
157GCP_path_entry_remove (struct CadetPeer *cp,
158 struct CadetPeerPathEntry *entry,
159 unsigned int off);
160
161
162/**
163 * Add an entry to the DLL of all of the paths that this peer is on.
164 *
165 * @param cp peer to modify
166 * @param entry an entry on a path
167 * @param off offset of this peer on the path
168 */
169void
170GCP_path_entry_add (struct CadetPeer *cp,
171 struct CadetPeerPathEntry *entry,
172 unsigned int off);
173
174
175/**
176 * Get the tunnel towards a peer.
177 *
178 * @param cp Peer to get from.
179 * @param create #GNUNET_YES to create a tunnel if we do not have one
180 * @return Tunnel towards peer.
181 */
182struct CadetTunnel *
183GCP_get_tunnel (struct CadetPeer *cp,
184 int create);
185
186
187/**
188 * The tunnel to the given peer no longer exists, remove it from our
189 * data structures, and possibly clean up the peer itself.
190 *
191 * @param cp the peer affected
192 * @param t the dead tunnel
193 */
194void
195GCP_drop_tunnel (struct CadetPeer *cp,
196 struct CadetTunnel *t);
197
198
199/**
200 * Try adding a @a path to this @a cp. If the peer already
201 * has plenty of paths, return NULL.
202 *
203 * @param cp peer to which the @a path leads to
204 * @param path a path looking for an owner; may not be fully initialized yet!
205 * @param off offset of @a cp in @a path
206 * @param force for attaching the path
207 * @return NULL if this peer does not care to become a new owner,
208 * otherwise the node in the peer's path heap for the @a path.
209 */
210struct GNUNET_CONTAINER_HeapNode *
211GCP_attach_path (struct CadetPeer *cp,
212 struct CadetPeerPath *path,
213 unsigned int off,
214 int force);
215
216
217/**
218 * This peer can no longer own @a path as the path
219 * has been extended and a peer further down the line
220 * is now the new owner.
221 *
222 * @param cp old owner of the @a path
223 * @param path path where the ownership is lost
224 * @param hn note in @a cp's path heap that must be deleted
225 */
226void
227GCP_detach_path (struct CadetPeer *cp,
228 struct CadetPeerPath *path,
229 struct GNUNET_CONTAINER_HeapNode *hn);
230
231
232/**
233 * Add a @a connection to this @a cp.
234 *
235 * @param cp peer via which the @a connection goes
236 * @param cc the connection to add
237 */
238void
239GCP_add_connection (struct CadetPeer *cp,
240 struct CadetConnection *cc);
241
242
243/**
244 * Remove a @a connection that went via this @a cp.
245 *
246 * @param cp peer via which the @a connection went
247 * @param cc the connection to remove
248 */
249void
250GCP_remove_connection (struct CadetPeer *cp,
251 struct CadetConnection *cc);
252
253
254/**
255 * We got a HELLO for a @a cp, remember it, and possibly
256 * trigger adequate actions (like trying to connect).
257 *
258 * @param cp the peer we got a HELLO for
259 * @param hello the HELLO to remember
260 */
261void
262GCP_set_hello (struct CadetPeer *cp,
263 const struct GNUNET_HELLO_Message *hello);
264
265
266/**
267 * Clean up all entries about all peers.
268 * Must only be called after all tunnels, CORE-connections and
269 * connections are down.
270 */
271void
272GCP_destroy_all_peers (void);
273
274
275/**
276 * Data structure used to track whom we have to notify about changes
277 * in our ability to transmit to a given peer.
278 *
279 * All queue managers will be given equal chance for sending messages
280 * to @a cp. This construct this guarantees fairness for access to @a
281 * cp among the different message queues. Each connection or route
282 * will have its respective message queue managers for each direction.
283 */
284struct GCP_MessageQueueManager;
285
286
287/**
288 * Function to call with updated message queue object.
289 *
290 * @param cls closure
291 * @param available #GNUNET_YES if sending is now possible,
292 * #GNUNET_NO if sending is no longer possible
293 * #GNUNET_SYSERR if sending is no longer possible
294 * and the last envelope was discarded
295 */
296typedef void
297(*GCP_MessageQueueNotificationCallback)(void *cls,
298 int available);
299
300
301/**
302 * Start message queue change notifications. Will create a new slot
303 * to manage the message queue to the given @a cp.
304 *
305 * @param cp peer to notify for
306 * @param cb function to call if mq becomes available or unavailable
307 * @param cb_cls closure for @a cb
308 * @return handle to cancel request
309 */
310struct GCP_MessageQueueManager *
311GCP_request_mq (struct CadetPeer *cp,
312 GCP_MessageQueueNotificationCallback cb,
313 void *cb_cls);
314
315
316/**
317 * Test if @a cp has a core-level connection
318 *
319 * @param cp peer to test
320 * @return #GNUNET_YES if @a cp has a core-level connection
321 */
322int
323GCP_has_core_connection (struct CadetPeer *cp);
324
325
326/**
327 * Send the message in @a env via a @a mqm. Must only be called at
328 * most once after the respective
329 * #GCP_MessageQueueNotificationCallback was called with `available`
330 * set to #GNUNET_YES, and not after the callback was called with
331 * `available` set to #GNUNET_NO or #GNUNET_SYSERR.
332 *
333 * @param mqm message queue manager for the transmission
334 * @param env envelope with the message to send; must NOT
335 * yet have a #GNUNET_MQ_notify_sent() callback attached to it
336 */
337void
338GCP_send (struct GCP_MessageQueueManager *mqm,
339 struct GNUNET_MQ_Envelope *env);
340
341
342/**
343 * Send the message in @a env to @a cp, overriding queueing logic.
344 * This function should only be used to send error messages outside
345 * of flow and congestion control, similar to ICMP. Note that
346 * the envelope may be silently discarded as well.
347 *
348 * @param cp peer to send the message to
349 * @param env envelope with the message to send
350 */
351void
352GCP_send_ooo (struct CadetPeer *cp,
353 struct GNUNET_MQ_Envelope *env);
354
355
356/**
357 * Stops message queue change notifications and sends a last message.
358 * In practice, this is implemented by sending that @a last_env
359 * message immediately (if any), ignoring queue order.
360 *
361 * @param mqm handle matching request to cancel
362 * @param last_env final message to transmit, or NULL
363 */
364void
365GCP_request_mq_cancel (struct GCP_MessageQueueManager *mqm,
366 struct GNUNET_MQ_Envelope *last_env);
367
368
369/**
370 * Set the message queue to @a mq for peer @a cp and notify watchers.
371 *
372 * @param cp peer to modify
373 * @param mq message queue to set (can be NULL)
374 */
375void
376GCP_set_mq (struct CadetPeer *cp,
377 struct GNUNET_MQ_Handle *mq);
378
379
380#endif
diff --git a/src/cadet/gnunet-service-cadet.c b/src/cadet/gnunet-service-cadet.c
index 3a07f0ee5..af4cebfaa 100644
--- a/src/cadet/gnunet-service-cadet.c
+++ b/src/cadet/gnunet-service-cadet.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2001-2013 GNUnet e.V. 3 Copyright (C) 2001-2013, 2017 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -22,37 +22,82 @@
22 * @file cadet/gnunet-service-cadet.c 22 * @file cadet/gnunet-service-cadet.c
23 * @brief GNUnet CADET service with encryption 23 * @brief GNUnet CADET service with encryption
24 * @author Bartlomiej Polot 24 * @author Bartlomiej Polot
25 * 25 * @author Christian Grothoff
26 * FIXME in progress:
27 * - rekey - reliability interaction
28 * - channel retransmit timing
29 *
30 * TODO:
31 * - relay corking down to core
32 * - set ttl relative to path length
33 * TODO END
34 * 26 *
35 * Dictionary: 27 * Dictionary:
36 * - peer: other cadet instance. If there is direct connection it's a neighbor. 28 * - peer: other cadet instance. If there is direct connection it's a neighbor.
37 * - tunnel: encrypted connection to a peer, neighbor or not.
38 * - channel: connection between two clients, on the same or different peers.
39 * have properties like reliability.
40 * - path: series of directly connected peer from one peer to another. 29 * - path: series of directly connected peer from one peer to another.
41 * - connection: path which is being used in a tunnel. 30 * - connection: path which is being used in a tunnel.
31 * - tunnel: encrypted connection to a peer, neighbor or not.
32 * - channel: logical link between two clients, on the same or different peers.
33 * have properties like reliability.
42 */ 34 */
43 35
44#include "platform.h" 36#include "platform.h"
45#include "gnunet_util_lib.h" 37#include "gnunet_util_lib.h"
46#include "cadet.h" 38#include "cadet.h"
47#include "gnunet_statistics_service.h" 39#include "gnunet_statistics_service.h"
48 40#include "gnunet-service-cadet.h"
49#include "gnunet-service-cadet_local.h"
50#include "gnunet-service-cadet_channel.h" 41#include "gnunet-service-cadet_channel.h"
51#include "gnunet-service-cadet_connection.h" 42#include "gnunet-service-cadet_connection.h"
52#include "gnunet-service-cadet_tunnel.h" 43#include "gnunet-service-cadet_core.h"
53#include "gnunet-service-cadet_dht.h" 44#include "gnunet-service-cadet_dht.h"
54#include "gnunet-service-cadet_peer.h"
55#include "gnunet-service-cadet_hello.h" 45#include "gnunet-service-cadet_hello.h"
46#include "gnunet-service-cadet_tunnels.h"
47#include "gnunet-service-cadet_peer.h"
48#include "gnunet-service-cadet_paths.h"
49
50#define LOG(level, ...) GNUNET_log (level,__VA_ARGS__)
51
52
53/**
54 * Struct containing information about a client of the service
55 */
56struct CadetClient
57{
58 /**
59 * Linked list next
60 */
61 struct CadetClient *next;
62
63 /**
64 * Linked list prev
65 */
66 struct CadetClient *prev;
67
68 /**
69 * Tunnels that belong to this client, indexed by local id,
70 * value is a `struct CadetChannel`.
71 */
72 struct GNUNET_CONTAINER_MultiHashMap32 *channels;
73
74 /**
75 * Handle to communicate with the client
76 */
77 struct GNUNET_MQ_Handle *mq;
78
79 /**
80 * Client handle.
81 */
82 struct GNUNET_SERVICE_Client *client;
83
84 /**
85 * Ports that this client has declared interest in.
86 * Indexed by port, contains `struct OpenPort`
87 */
88 struct GNUNET_CONTAINER_MultiHashMap *ports;
89
90 /**
91 * Channel ID to use for the next incoming channel for this client.
92 * Wraps around (in theory).
93 */
94 struct GNUNET_CADET_ClientChannelNumber next_ccn;
95
96 /**
97 * ID of the client, mainly for debug messages. Purely internal to this file.
98 */
99 unsigned int id;
100};
56 101
57 102
58/******************************************************************************/ 103/******************************************************************************/
@@ -62,37 +107,318 @@
62/****************************** Global variables ******************************/ 107/****************************** Global variables ******************************/
63 108
64/** 109/**
110 * Handle to our configuration.
111 */
112const struct GNUNET_CONFIGURATION_Handle *cfg;
113
114/**
65 * Handle to the statistics service. 115 * Handle to the statistics service.
66 */ 116 */
67struct GNUNET_STATISTICS_Handle *stats; 117struct GNUNET_STATISTICS_Handle *stats;
68 118
69/** 119/**
70 * Local peer own ID (memory efficient handle). 120 * Handle to communicate with ATS.
71 */ 121 */
72GNUNET_PEER_Id myid; 122struct GNUNET_ATS_ConnectivityHandle *ats_ch;
73 123
74/** 124/**
75 * Local peer own ID (full value). 125 * Local peer own ID.
76 */ 126 */
77struct GNUNET_PeerIdentity my_full_id; 127struct GNUNET_PeerIdentity my_full_id;
78 128
129/**
130 * Own private key.
131 */
132struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key;
79 133
80/** 134/**
81 * Signal that shutdown is happening: prevent recover measures. 135 * Signal that shutdown is happening: prevent recovery measures.
82 */ 136 */
83int shutting_down; 137int shutting_down;
84 138
85/*************************** Static global variables **************************/ 139/**
140 * DLL with all the clients, head.
141 */
142static struct CadetClient *clients_head;
86 143
87/** 144/**
88 * Own private key. 145 * DLL with all the clients, tail.
89 */ 146 */
90static struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key; 147static struct CadetClient *clients_tail;
91 148
149/**
150 * Next ID to assign to a client.
151 */
152static unsigned int next_client_id;
153
154/**
155 * All ports clients of this peer have opened. Maps from
156 * a hashed port to a `struct OpenPort`.
157 */
158struct GNUNET_CONTAINER_MultiHashMap *open_ports;
159
160/**
161 * Map from ports to channels where the ports were closed at the
162 * time we got the inbound connection.
163 * Indexed by h_port, contains `struct CadetChannel`.
164 */
165struct GNUNET_CONTAINER_MultiHashMap *loose_channels;
166
167/**
168 * Map from PIDs to `struct CadetPeer` entries.
169 */
170struct GNUNET_CONTAINER_MultiPeerMap *peers;
171
172/**
173 * Map from `struct GNUNET_CADET_ConnectionTunnelIdentifier`
174 * hash codes to `struct CadetConnection` objects.
175 */
176struct GNUNET_CONTAINER_MultiShortmap *connections;
177
178/**
179 * How many messages are needed to trigger an AXOLOTL ratchet advance.
180 */
181unsigned long long ratchet_messages;
182
183/**
184 * How long until we trigger a ratched advance due to time.
185 */
186struct GNUNET_TIME_Relative ratchet_time;
187
188/**
189 * How frequently do we send KEEPALIVE messages on idle connections?
190 */
191struct GNUNET_TIME_Relative keepalive_period;
192
193/**
194 * Set to non-zero values to create random drops to test retransmissions.
195 */
196unsigned long long drop_percent;
197
198
199/**
200 * Send a message to a client.
201 *
202 * @param c client to get the message
203 * @param env envelope with the message
204 */
205void
206GSC_send_to_client (struct CadetClient *c,
207 struct GNUNET_MQ_Envelope *env)
208{
209 GNUNET_MQ_send (c->mq,
210 env);
211}
212
213
214/**
215 * Return identifier for a client as a string.
216 *
217 * @param c client to identify
218 * @return string for debugging
219 */
220const char *
221GSC_2s (struct CadetClient *c)
222{
223 static char buf[32];
224
225 GNUNET_snprintf (buf,
226 sizeof (buf),
227 "Client(%u)",
228 c->id);
229 return buf;
230}
231
232
233/**
234 * Lookup channel of client @a c by @a ccn.
235 *
236 * @param c client to look in
237 * @param ccn channel ID to look up
238 * @return NULL if no such channel exists
239 */
240static struct CadetChannel *
241lookup_channel (struct CadetClient *c,
242 struct GNUNET_CADET_ClientChannelNumber ccn)
243{
244 return GNUNET_CONTAINER_multihashmap32_get (c->channels,
245 ntohl (ccn.channel_of_client));
246}
247
248
249/**
250 * Obtain the next LID to use for incoming connections to
251 * the given client.
252 *
253 * @param c client handle
254 */
255static struct GNUNET_CADET_ClientChannelNumber
256client_get_next_ccn (struct CadetClient *c)
257{
258 struct GNUNET_CADET_ClientChannelNumber ccn = c->next_ccn;
259
260 /* increment until we have a free one... */
261 while (NULL !=
262 lookup_channel (c,
263 ccn))
264 {
265 ccn.channel_of_client
266 = htonl (1 + (ntohl (ccn.channel_of_client)));
267 if (ntohl (ccn.channel_of_client) >=
268 GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
269 ccn.channel_of_client = htonl (0);
270 }
271 c->next_ccn.channel_of_client
272 = htonl (1 + (ntohl (ccn.channel_of_client)));
273 return ccn;
274}
275
276
277/**
278 * Bind incoming channel to this client, and notify client about
279 * incoming connection. Caller is responsible for notifying the other
280 * peer about our acceptance of the channel.
281 *
282 * @param c client to bind to
283 * @param ch channel to be bound
284 * @param dest peer that establishes the connection
285 * @param port port number
286 * @param options options
287 * @return local channel number assigned to the new client
288 */
289struct GNUNET_CADET_ClientChannelNumber
290GSC_bind (struct CadetClient *c,
291 struct CadetChannel *ch,
292 struct CadetPeer *dest,
293 const struct GNUNET_HashCode *port,
294 uint32_t options)
295{
296 struct GNUNET_MQ_Envelope *env;
297 struct GNUNET_CADET_LocalChannelCreateMessage *cm;
298 struct GNUNET_CADET_ClientChannelNumber ccn;
299
300 ccn = client_get_next_ccn (c);
301 GNUNET_assert (GNUNET_YES ==
302 GNUNET_CONTAINER_multihashmap32_put (c->channels,
303 ntohl (ccn.channel_of_client),
304 ch,
305 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
306 LOG (GNUNET_ERROR_TYPE_DEBUG,
307 "Accepting incoming %s from %s on open port %s (%u), assigning ccn %X\n",
308 GCCH_2s (ch),
309 GCP_2s (dest),
310 GNUNET_h2s (port),
311 (uint32_t) ntohl (options),
312 (uint32_t) ntohl (ccn.channel_of_client));
313 /* notify local client about incoming connection! */
314 env = GNUNET_MQ_msg (cm,
315 GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE);
316 cm->ccn = ccn;
317 cm->port = *port;
318 cm->opt = htonl (options);
319 cm->peer = *GCP_get_id (dest);
320 GSC_send_to_client (c,
321 env);
322 return ccn;
323}
324
325
326/**
327 * Callback invoked on all peers to destroy all tunnels
328 * that may still exist.
329 *
330 * @param cls NULL
331 * @param pid identify of a peer
332 * @param value a `struct CadetPeer` that may still have a tunnel
333 * @return #GNUNET_OK (iterate over all entries)
334 */
335static int
336destroy_tunnels_now (void *cls,
337 const struct GNUNET_PeerIdentity *pid,
338 void *value)
339{
340 struct CadetPeer *cp = value;
341 struct CadetTunnel *t = GCP_get_tunnel (cp,
342 GNUNET_NO);
343
344 if (NULL != t)
345 GCT_destroy_tunnel_now (t);
346 return GNUNET_OK;
347}
348
349
350/**
351 * Callback invoked on all peers to destroy all tunnels
352 * that may still exist.
353 *
354 * @param cls NULL
355 * @param pid identify of a peer
356 * @param value a `struct CadetPeer` that may still have a tunnel
357 * @return #GNUNET_OK (iterate over all entries)
358 */
359static int
360destroy_paths_now (void *cls,
361 const struct GNUNET_PeerIdentity *pid,
362 void *value)
363{
364 struct CadetPeer *cp = value;
365
366 GCP_drop_owned_paths (cp);
367 return GNUNET_OK;
368}
369
370
371/**
372 * Shutdown everything once the clients have disconnected.
373 */
374static void
375shutdown_rest ()
376{
377 if (NULL != stats)
378 {
379 GNUNET_STATISTICS_destroy (stats,
380 GNUNET_NO);
381 stats = NULL;
382 }
383 if (NULL != open_ports)
384 {
385 GNUNET_CONTAINER_multihashmap_destroy (open_ports);
386 open_ports = NULL;
387 }
388 if (NULL != loose_channels)
389 {
390 GNUNET_CONTAINER_multihashmap_destroy (loose_channels);
391 loose_channels = NULL;
392 }
393 /* Destroy tunnels. Note that all channels must be destroyed first! */
394 GCP_iterate_all (&destroy_tunnels_now,
395 NULL);
396 /* All tunnels, channels, connections and CORE must be down before this point. */
397 GCP_iterate_all (&destroy_paths_now,
398 NULL);
399 /* All paths, tunnels, channels, connections and CORE must be down before this point. */
400 GCP_destroy_all_peers ();
401 if (NULL != peers)
402 {
403 GNUNET_CONTAINER_multipeermap_destroy (peers);
404 peers = NULL;
405 }
406 if (NULL != connections)
407 {
408 GNUNET_CONTAINER_multishortmap_destroy (connections);
409 connections = NULL;
410 }
411 if (NULL != ats_ch)
412 {
413 GNUNET_ATS_connectivity_done (ats_ch);
414 ats_ch = NULL;
415 }
416 GCD_shutdown ();
417 GCH_shutdown ();
418 GNUNET_free_non_null (my_private_key);
419 my_private_key = NULL;
420}
92 421
93/******************************************************************************/
94/************************ MAIN FUNCTIONS ****************************/
95/******************************************************************************/
96 422
97/** 423/**
98 * Task run during shutdown. 424 * Task run during shutdown.
@@ -102,83 +428,1087 @@ static struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key;
102static void 428static void
103shutdown_task (void *cls) 429shutdown_task (void *cls)
104{ 430{
105 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shutting down\n"); 431 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
106 432 "Shutting down\n");
107 shutting_down = GNUNET_YES; 433 shutting_down = GNUNET_YES;
434 GCO_shutdown ();
435 if (NULL == clients_head)
436 shutdown_rest ();
437}
108 438
109 GML_shutdown ();
110 GCH_shutdown ();
111 GCC_shutdown ();
112 GCT_shutdown ();
113 GCD_shutdown ();
114 GCP_shutdown ();
115 439
116 GNUNET_STATISTICS_destroy (stats, GNUNET_NO); 440/**
117 stats = NULL; 441 * We had a remote connection @a value to port @a h_port before
118 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shut down\n"); 442 * client @a cls opened port @a port. Bind them now.
443 *
444 * @param cls the `struct CadetClient`
445 * @param h_port the hashed port
446 * @param value the `struct CadetChannel`
447 * @return #GNUNET_YES (iterate over all such channels)
448 */
449static int
450bind_loose_channel (void *cls,
451 const struct GNUNET_HashCode *port,
452 void *value)
453{
454 struct OpenPort *op = cls;
455 struct CadetChannel *ch = value;
456
457 GCCH_bind (ch,
458 op->c,
459 &op->port);
460 GNUNET_assert (GNUNET_YES ==
461 GNUNET_CONTAINER_multihashmap_remove (loose_channels,
462 &op->h_port,
463 ch));
464 return GNUNET_YES;
119} 465}
120 466
121 467
122/** 468/**
123 * Process cadet requests. 469 * Handle port open request. Creates a mapping from the
470 * port to the respective client and checks whether we have
471 * loose channels trying to bind to the port. If so, those
472 * are bound.
124 * 473 *
125 * @param cls closure 474 * @param cls Identification of the client.
126 * @param server the initialized server 475 * @param pmsg The actual message.
127 * @param c configuration to use
128 */ 476 */
129static void 477static void
130run (void *cls, struct GNUNET_SERVER_Handle *server, 478handle_port_open (void *cls,
131 const struct GNUNET_CONFIGURATION_Handle *c) 479 const struct GNUNET_CADET_PortMessage *pmsg)
132{ 480{
133 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "starting to run\n"); 481 struct CadetClient *c = cls;
482 struct OpenPort *op;
134 483
135 stats = GNUNET_STATISTICS_create ("cadet", c); 484 LOG (GNUNET_ERROR_TYPE_DEBUG,
485 "Open port %s requested by %s\n",
486 GNUNET_h2s (&pmsg->port),
487 GSC_2s (c));
488 if (NULL == c->ports)
489 c->ports = GNUNET_CONTAINER_multihashmap_create (4,
490 GNUNET_NO);
491 op = GNUNET_new (struct OpenPort);
492 op->c = c;
493 op->port = pmsg->port;
494 GCCH_hash_port (&op->h_port,
495 &pmsg->port,
496 &my_full_id);
497 if (GNUNET_OK !=
498 GNUNET_CONTAINER_multihashmap_put (c->ports,
499 &op->port,
500 op,
501 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
502 {
503 GNUNET_break (0);
504 GNUNET_SERVICE_client_drop (c->client);
505 return;
506 }
507 (void) GNUNET_CONTAINER_multihashmap_put (open_ports,
508 &op->h_port,
509 op,
510 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
511 GNUNET_CONTAINER_multihashmap_get_multiple (loose_channels,
512 &op->h_port,
513 &bind_loose_channel,
514 op);
515 GNUNET_SERVICE_client_continue (c->client);
516}
136 517
137 /* Scheduled the task to clean up when shutdown is called */
138 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
139 NULL);
140 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "reading key\n");
141 my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (c);
142 GNUNET_assert (NULL != my_private_key);
143 GNUNET_CRYPTO_eddsa_key_get_public (my_private_key, &my_full_id.public_key);
144 myid = GNUNET_PEER_intern (&my_full_id);
145 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
146 "STARTING SERVICE (cadet) for peer [%s]\n",
147 GNUNET_i2s (&my_full_id));
148 518
149 GML_init (server); /* Local clients */ 519/**
150 GCH_init (c); /* Hellos */ 520 * Handler for port close requests. Marks this port as closed
151 GCC_init (c); /* Connections */ 521 * (unless of course we have another client with the same port
152 GCP_init (c); /* Peers */ 522 * open). Note that existing channels accepted on the port are
153 GCD_init (c); /* DHT */ 523 * not affected.
154 GCT_init (c, my_private_key); /* Tunnels */ 524 *
525 * @param cls Identification of the client.
526 * @param pmsg The actual message.
527 */
528static void
529handle_port_close (void *cls,
530 const struct GNUNET_CADET_PortMessage *pmsg)
531{
532 struct CadetClient *c = cls;
533 struct OpenPort *op;
155 534
156 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cadet service running\n"); 535 LOG (GNUNET_ERROR_TYPE_DEBUG,
536 "Closing port %s as requested by %s\n",
537 GNUNET_h2s (&pmsg->port),
538 GSC_2s (c));
539 op = GNUNET_CONTAINER_multihashmap_get (c->ports,
540 &pmsg->port);
541 if (NULL == op)
542 {
543 GNUNET_break (0);
544 GNUNET_SERVICE_client_drop (c->client);
545 return;
546 }
547 GNUNET_assert (GNUNET_YES ==
548 GNUNET_CONTAINER_multihashmap_remove (c->ports,
549 &op->port,
550 op));
551 GNUNET_assert (GNUNET_YES ==
552 GNUNET_CONTAINER_multihashmap_remove (open_ports,
553 &op->h_port,
554 op));
555 GNUNET_free (op);
556 GNUNET_SERVICE_client_continue (c->client);
157} 557}
158 558
159 559
160/** 560/**
161 * The main function for the cadet service. 561 * Handler for requests for us creating a new channel to another peer and port.
162 * 562 *
163 * @param argc number of arguments from the command line 563 * @param cls Identification of the client.
164 * @param argv command line arguments 564 * @param tcm The actual message.
165 * @return 0 ok, 1 on error
166 */ 565 */
167int 566static void
168main (int argc, char *const *argv) 567handle_channel_create (void *cls,
568 const struct GNUNET_CADET_LocalChannelCreateMessage *tcm)
169{ 569{
170 int r; 570 struct CadetClient *c = cls;
571 struct CadetChannel *ch;
171 572
172 shutting_down = GNUNET_NO; 573 if (ntohl (tcm->ccn.channel_of_client) < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
173 r = GNUNET_SERVICE_run (argc, argv, "cadet", GNUNET_SERVICE_OPTION_NONE, &run, 574 {
174 NULL); 575 /* Channel ID not in allowed range. */
175 GNUNET_free (my_private_key); 576 GNUNET_break (0);
577 GNUNET_SERVICE_client_drop (c->client);
578 return;
579 }
580 ch = lookup_channel (c,
581 tcm->ccn);
582 if (NULL != ch)
583 {
584 /* Channel ID already in use. Not allowed. */
585 GNUNET_break (0);
586 GNUNET_SERVICE_client_drop (c->client);
587 return;
588 }
589 LOG (GNUNET_ERROR_TYPE_DEBUG,
590 "New channel to %s at port %s requested by %s\n",
591 GNUNET_i2s (&tcm->peer),
592 GNUNET_h2s (&tcm->port),
593 GSC_2s (c));
176 594
177 if (GNUNET_OK != r) 595 /* Create channel */
596 ch = GCCH_channel_local_new (c,
597 tcm->ccn,
598 GCP_get (&tcm->peer,
599 GNUNET_YES),
600 &tcm->port,
601 ntohl (tcm->opt));
602 if (NULL == ch)
178 { 603 {
179 FPRINTF (stderr, "GNUNET_SERVICE_run for CADET has failed!\n"); 604 GNUNET_break (0);
180 return 1; 605 GNUNET_SERVICE_client_drop (c->client);
606 return;
181 } 607 }
608 GNUNET_assert (GNUNET_YES ==
609 GNUNET_CONTAINER_multihashmap32_put (c->channels,
610 ntohl (tcm->ccn.channel_of_client),
611 ch,
612 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
182 613
183 return 0; 614 GNUNET_SERVICE_client_continue (c->client);
184} 615}
616
617
618/**
619 * Handler for requests of destroying an existing channel.
620 *
621 * @param cls client identification of the client
622 * @param msg the actual message
623 */
624static void
625handle_channel_destroy (void *cls,
626 const struct GNUNET_CADET_LocalChannelDestroyMessage *msg)
627{
628 struct CadetClient *c = cls;
629 struct CadetChannel *ch;
630
631 ch = lookup_channel (c,
632 msg->ccn);
633 if (NULL == ch)
634 {
635 /* Client attempted to destroy unknown channel.
636 Can happen if the other side went down at the same time.*/
637 LOG (GNUNET_ERROR_TYPE_DEBUG,
638 "%s tried to destroy unknown channel %X\n",
639 GSC_2s(c),
640 (uint32_t) ntohl (msg->ccn.channel_of_client));
641 return;
642 }
643 LOG (GNUNET_ERROR_TYPE_DEBUG,
644 "%s is destroying %s\n",
645 GSC_2s(c),
646 GCCH_2s (ch));
647 GNUNET_assert (GNUNET_YES ==
648 GNUNET_CONTAINER_multihashmap32_remove (c->channels,
649 ntohl (msg->ccn.channel_of_client),
650 ch));
651 GCCH_channel_local_destroy (ch,
652 c,
653 msg->ccn);
654 GNUNET_SERVICE_client_continue (c->client);
655}
656
657
658/**
659 * Check for client traffic data message is well-formed.
660 *
661 * @param cls identification of the client
662 * @param msg the actual message
663 * @return #GNUNET_OK if @a msg is OK, #GNUNET_SYSERR if not
664 */
665static int
666check_local_data (void *cls,
667 const struct GNUNET_CADET_LocalData *msg)
668{
669 size_t payload_size;
670 size_t payload_claimed_size;
671 const char *buf;
672 struct GNUNET_MessageHeader pa;
673
674 /* FIXME: what is the format we shall allow for @a msg?
675 ONE payload item or multiple? Seems current cadet_api
676 at least in theory allows more than one. Next-gen
677 cadet_api will likely no more, so we could then
678 simplify this mess again. */
679 /* Sanity check for message size */
680 payload_size = ntohs (msg->header.size) - sizeof (*msg);
681 buf = (const char *) &msg[1];
682 while (payload_size >= sizeof (struct GNUNET_MessageHeader))
683 {
684 /* need to memcpy() for alignment */
685 GNUNET_memcpy (&pa,
686 buf,
687 sizeof (pa));
688 payload_claimed_size = ntohs (pa.size);
689 if ( (payload_size < payload_claimed_size) ||
690 (payload_claimed_size < sizeof (struct GNUNET_MessageHeader)) ||
691 (GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE < payload_claimed_size) )
692 {
693 GNUNET_break (0);
694 LOG (GNUNET_ERROR_TYPE_DEBUG,
695 "Local data of %u total size had sub-message %u at %u with %u bytes\n",
696 ntohs (msg->header.size),
697 ntohs (pa.type),
698 (unsigned int) (buf - (const char *) &msg[1]),
699 (unsigned int) payload_claimed_size);
700 return GNUNET_SYSERR;
701 }
702 payload_size -= payload_claimed_size;
703 buf += payload_claimed_size;
704 }
705 if (0 != payload_size)
706 {
707 GNUNET_break_op (0);
708 return GNUNET_SYSERR;
709 }
710 return GNUNET_OK;
711}
712
713
714/**
715 * Handler for client payload traffic to be send on a channel to
716 * another peer.
717 *
718 * @param cls identification of the client
719 * @param msg the actual message
720 */
721static void
722handle_local_data (void *cls,
723 const struct GNUNET_CADET_LocalData *msg)
724{
725 struct CadetClient *c = cls;
726 struct CadetChannel *ch;
727 size_t payload_size;
728 const char *buf;
729
730 ch = lookup_channel (c,
731 msg->ccn);
732 if (NULL == ch)
733 {
734 /* Channel does not exist (anymore) */
735 LOG (GNUNET_ERROR_TYPE_WARNING,
736 "Dropping payload for channel %u from client (channel unknown, other endpoint may have disconnected)\n",
737 (unsigned int) ntohl (msg->ccn.channel_of_client));
738 GNUNET_SERVICE_client_continue (c->client);
739 return;
740 }
741 payload_size = ntohs (msg->header.size) - sizeof (*msg);
742 GNUNET_STATISTICS_update (stats,
743 "# payload received from clients",
744 payload_size,
745 GNUNET_NO);
746 buf = (const char *) &msg[1];
747 LOG (GNUNET_ERROR_TYPE_DEBUG,
748 "Received %u bytes payload from %s for %s\n",
749 (unsigned int) payload_size,
750 GSC_2s (c),
751 GCCH_2s (ch));
752 if (GNUNET_OK !=
753 GCCH_handle_local_data (ch,
754 msg->ccn,
755 buf,
756 payload_size))
757 {
758 GNUNET_SERVICE_client_drop (c->client);
759 return;
760 }
761 GNUNET_SERVICE_client_continue (c->client);
762}
763
764
765/**
766 * Handler for client's ACKs for payload traffic.
767 *
768 * @param cls identification of the client.
769 * @param msg The actual message.
770 */
771static void
772handle_local_ack (void *cls,
773 const struct GNUNET_CADET_LocalAck *msg)
774{
775 struct CadetClient *c = cls;
776 struct CadetChannel *ch;
777
778 ch = lookup_channel (c,
779 msg->ccn);
780 if (NULL == ch)
781 {
782 /* Channel does not exist (anymore) */
783 LOG (GNUNET_ERROR_TYPE_WARNING,
784 "Ignoring local ACK for channel %u from client (channel unknown, other endpoint may have disconnected)\n",
785 (unsigned int) ntohl (msg->ccn.channel_of_client));
786 GNUNET_SERVICE_client_continue (c->client);
787 return;
788 }
789 LOG (GNUNET_ERROR_TYPE_DEBUG,
790 "Got a local ACK from %s for %s\n",
791 GSC_2s(c),
792 GCCH_2s (ch));
793 GCCH_handle_local_ack (ch,
794 msg->ccn);
795 GNUNET_SERVICE_client_continue (c->client);
796}
797
798
799/**
800 * Iterator over all peers to send a monitoring client info about each peer.
801 *
802 * @param cls Closure ().
803 * @param peer Peer ID (tunnel remote peer).
804 * @param value Peer info.
805 * @return #GNUNET_YES, to keep iterating.
806 */
807static int
808get_all_peers_iterator (void *cls,
809 const struct GNUNET_PeerIdentity *peer,
810 void *value)
811{
812 struct CadetClient *c = cls;
813 struct CadetPeer *p = value;
814 struct GNUNET_MQ_Envelope *env;
815 struct GNUNET_CADET_LocalInfoPeer *msg;
816
817 env = GNUNET_MQ_msg (msg,
818 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS);
819 msg->destination = *peer;
820 msg->paths = htons (GCP_count_paths (p));
821 msg->tunnel = htons (NULL != GCP_get_tunnel (p,
822 GNUNET_NO));
823 GNUNET_MQ_send (c->mq,
824 env);
825 return GNUNET_YES;
826}
827
828
829/**
830 * Handler for client's INFO PEERS request.
831 *
832 * @param cls Identification of the client.
833 * @param message The actual message.
834 */
835static void
836handle_get_peers (void *cls,
837 const struct GNUNET_MessageHeader *message)
838{
839 struct CadetClient *c = cls;
840 struct GNUNET_MQ_Envelope *env;
841 struct GNUNET_MessageHeader *reply;
842
843 GCP_iterate_all (&get_all_peers_iterator,
844 c);
845 env = GNUNET_MQ_msg (reply,
846 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS);
847 GNUNET_MQ_send (c->mq,
848 env);
849 GNUNET_SERVICE_client_continue (c->client);
850}
851
852
853/**
854 * Iterator over all paths of a peer to build an InfoPeer message.
855 * Message contains blocks of peers, first not included.
856 *
857 * @param cls message queue for transmission
858 * @param path Path itself
859 * @param off offset of the peer on @a path
860 * @return #GNUNET_YES if should keep iterating.
861 * #GNUNET_NO otherwise.
862 */
863static int
864path_info_iterator (void *cls,
865 struct CadetPeerPath *path,
866 unsigned int off)
867{
868 struct GNUNET_MQ_Handle *mq = cls;
869 struct GNUNET_MQ_Envelope *env;
870 struct GNUNET_MessageHeader *resp;
871 struct GNUNET_PeerIdentity *id;
872 uint16_t path_size;
873 unsigned int i;
874 unsigned int path_length;
875
876 path_length = GCPP_get_length (path);
877 path_size = sizeof (struct GNUNET_PeerIdentity) * (path_length - 1);
878 if (sizeof (*resp) + path_size > UINT16_MAX)
879 {
880 LOG (GNUNET_ERROR_TYPE_WARNING,
881 "Path of %u entries is too long for info message\n",
882 path_length);
883 return GNUNET_YES;
884 }
885 env = GNUNET_MQ_msg_extra (resp,
886 path_size,
887 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER);
888 id = (struct GNUNET_PeerIdentity *) &resp[1];
889
890 /* Don't copy first peer. First peer is always the local one. Last
891 * peer is always the destination (leave as 0, EOL).
892 */
893 for (i = 0; i < off; i++)
894 id[i] = *GCP_get_id (GCPP_get_peer_at_offset (path,
895 i + 1));
896 GNUNET_MQ_send (mq,
897 env);
898 return GNUNET_YES;
899}
900
901
902/**
903 * Handler for client's SHOW_PEER request.
904 *
905 * @param cls Identification of the client.
906 * @param msg The actual message.
907 */
908static void
909handle_show_peer (void *cls,
910 const struct GNUNET_CADET_LocalInfo *msg)
911{
912 struct CadetClient *c = cls;
913 struct CadetPeer *p;
914 struct GNUNET_MQ_Envelope *env;
915 struct GNUNET_MessageHeader *resp;
916
917 p = GCP_get (&msg->peer,
918 GNUNET_NO);
919 if (NULL != p)
920 GCP_iterate_paths (p,
921 &path_info_iterator,
922 c->mq);
923 /* Send message with 0/0 to indicate the end */
924 env = GNUNET_MQ_msg (resp,
925 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER_END);
926 GNUNET_MQ_send (c->mq,
927 env);
928 GNUNET_SERVICE_client_continue (c->client);
929}
930
931
932/**
933 * Iterator over all tunnels to send a monitoring client info about each tunnel.
934 *
935 * @param cls Closure ().
936 * @param peer Peer ID (tunnel remote peer).
937 * @param value a `struct CadetPeer`
938 * @return #GNUNET_YES, to keep iterating.
939 */
940static int
941get_all_tunnels_iterator (void *cls,
942 const struct GNUNET_PeerIdentity *peer,
943 void *value)
944{
945 struct CadetClient *c = cls;
946 struct CadetPeer *p = value;
947 struct GNUNET_MQ_Envelope *env;
948 struct GNUNET_CADET_LocalInfoTunnel *msg;
949 struct CadetTunnel *t;
950
951 t = GCP_get_tunnel (p,
952 GNUNET_NO);
953 if (NULL == t)
954 return GNUNET_YES;
955 env = GNUNET_MQ_msg (msg,
956 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS);
957 msg->destination = *peer;
958 msg->channels = htonl (GCT_count_channels (t));
959 msg->connections = htonl (GCT_count_any_connections (t));
960 msg->cstate = htons (0);
961 msg->estate = htons ((uint16_t) GCT_get_estate (t));
962 GNUNET_MQ_send (c->mq,
963 env);
964 return GNUNET_YES;
965}
966
967
968/**
969 * Handler for client's #GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS request.
970 *
971 * @param cls client Identification of the client.
972 * @param message The actual message.
973 */
974static void
975handle_info_tunnels (void *cls,
976 const struct GNUNET_MessageHeader *message)
977{
978 struct CadetClient *c = cls;
979 struct GNUNET_MQ_Envelope *env;
980 struct GNUNET_MessageHeader *reply;
981
982 GCP_iterate_all (&get_all_tunnels_iterator,
983 c);
984 env = GNUNET_MQ_msg (reply,
985 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS);
986 GNUNET_MQ_send (c->mq,
987 env);
988 GNUNET_SERVICE_client_continue (c->client);
989}
990
991
992/**
993 * Update the message with information about the connection.
994 *
995 * @param cls a `struct GNUNET_CADET_LocalInfoTunnel` message to update
996 * @param ct a connection about which we should store information in @a cls
997 */
998static void
999iter_connection (void *cls,
1000 struct CadetTConnection *ct)
1001{
1002 struct GNUNET_CADET_LocalInfoTunnel *msg = cls;
1003 struct CadetConnection *cc = ct->cc;
1004 struct GNUNET_CADET_ConnectionTunnelIdentifier *h;
1005
1006 h = (struct GNUNET_CADET_ConnectionTunnelIdentifier *) &msg[1];
1007 h[msg->connections++] = *(GCC_get_id (cc));
1008}
1009
1010
1011/**
1012 * Update the message with information about the channel.
1013 *
1014 * @param cls a `struct GNUNET_CADET_LocalInfoTunnel` message to update
1015 * @param ch a channel about which we should store information in @a cls
1016 */
1017static void
1018iter_channel (void *cls,
1019 struct CadetChannel *ch)
1020{
1021 struct GNUNET_CADET_LocalInfoTunnel *msg = cls;
1022 struct GNUNET_CADET_ConnectionTunnelIdentifier *h = (struct GNUNET_CADET_ConnectionTunnelIdentifier *) &msg[1];
1023 struct GNUNET_CADET_ChannelTunnelNumber *chn
1024 = (struct GNUNET_CADET_ChannelTunnelNumber *) &h[msg->connections];
1025
1026 chn[msg->channels++] = GCCH_get_id (ch);
1027}
1028
1029
1030/**
1031 * Handler for client's #GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL request.
1032 *
1033 * @param cls Identification of the client.
1034 * @param msg The actual message.
1035 */
1036static void
1037handle_info_tunnel (void *cls,
1038 const struct GNUNET_CADET_LocalInfo *msg)
1039{
1040 struct CadetClient *c = cls;
1041 struct GNUNET_MQ_Envelope *env;
1042 struct GNUNET_CADET_LocalInfoTunnel *resp;
1043 struct CadetTunnel *t;
1044 struct CadetPeer *p;
1045 unsigned int ch_n;
1046 unsigned int c_n;
1047
1048 p = GCP_get (&msg->peer,
1049 GNUNET_NO);
1050 t = GCP_get_tunnel (p,
1051 GNUNET_NO);
1052 if (NULL == t)
1053 {
1054 /* We don't know the tunnel */
1055 struct GNUNET_MQ_Envelope *env;
1056 struct GNUNET_CADET_LocalInfoTunnel *warn;
1057
1058 LOG (GNUNET_ERROR_TYPE_INFO,
1059 "Tunnel to %s unknown\n",
1060 GNUNET_i2s_full (&msg->peer));
1061 env = GNUNET_MQ_msg (warn,
1062 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL);
1063 warn->destination = msg->peer;
1064 GNUNET_MQ_send (c->mq,
1065 env);
1066 GNUNET_SERVICE_client_continue (c->client);
1067 return;
1068 }
1069
1070 /* Initialize context */
1071 ch_n = GCT_count_channels (t);
1072 c_n = GCT_count_any_connections (t);
1073 env = GNUNET_MQ_msg_extra (resp,
1074 c_n * sizeof (struct GNUNET_CADET_ConnectionTunnelIdentifier) +
1075 ch_n * sizeof (struct GNUNET_CADET_ChannelTunnelNumber),
1076 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL);
1077 resp->destination = msg->peer;
1078 /* Do not reorder! #iter_channel needs counters in HBO! */
1079 GCT_iterate_connections (t,
1080 &iter_connection,
1081 resp);
1082 GCT_iterate_channels (t,
1083 &iter_channel,
1084 resp);
1085 resp->connections = htonl (resp->connections);
1086 resp->channels = htonl (resp->channels);
1087 resp->cstate = htons (0);
1088 resp->estate = htons (GCT_get_estate (t));
1089 GNUNET_MQ_send (c->mq,
1090 env);
1091 GNUNET_SERVICE_client_continue (c->client);
1092}
1093
1094
1095/**
1096 * Iterator over all peers to dump info for each peer.
1097 *
1098 * @param cls Closure (unused).
1099 * @param peer Peer ID (tunnel remote peer).
1100 * @param value Peer info.
1101 *
1102 * @return #GNUNET_YES, to keep iterating.
1103 */
1104static int
1105show_peer_iterator (void *cls,
1106 const struct GNUNET_PeerIdentity *peer,
1107 void *value)
1108{
1109 struct CadetPeer *p = value;
1110 struct CadetTunnel *t;
1111
1112 t = GCP_get_tunnel (p,
1113 GNUNET_NO);
1114 if (NULL != t)
1115 GCT_debug (t,
1116 GNUNET_ERROR_TYPE_ERROR);
1117 LOG (GNUNET_ERROR_TYPE_ERROR, "\n");
1118 return GNUNET_YES;
1119}
1120
1121
1122/**
1123 * Handler for client's INFO_DUMP request.
1124 *
1125 * @param cls Identification of the client.
1126 * @param message The actual message.
1127 */
1128static void
1129handle_info_dump (void *cls,
1130 const struct GNUNET_MessageHeader *message)
1131{
1132 struct CadetClient *c = cls;
1133
1134 LOG (GNUNET_ERROR_TYPE_INFO,
1135 "Received dump info request from client %u\n",
1136 c->id);
1137
1138 LOG (GNUNET_ERROR_TYPE_ERROR,
1139 "*************************** DUMP START ***************************\n");
1140 for (struct CadetClient *ci = clients_head;
1141 NULL != ci;
1142 ci = ci->next)
1143 {
1144 LOG (GNUNET_ERROR_TYPE_ERROR,
1145 "Client %u (%p), handle: %p, ports: %u, channels: %u\n",
1146 ci->id,
1147 ci,
1148 ci->client,
1149 (NULL != c->ports)
1150 ? GNUNET_CONTAINER_multihashmap_size (ci->ports)
1151 : 0,
1152 GNUNET_CONTAINER_multihashmap32_size (ci->channels));
1153 }
1154 LOG (GNUNET_ERROR_TYPE_ERROR, "***************************\n");
1155 GCP_iterate_all (&show_peer_iterator,
1156 NULL);
1157
1158 LOG (GNUNET_ERROR_TYPE_ERROR,
1159 "**************************** DUMP END ****************************\n");
1160
1161 GNUNET_SERVICE_client_continue (c->client);
1162}
1163
1164
1165
1166/**
1167 * Callback called when a client connects to the service.
1168 *
1169 * @param cls closure for the service
1170 * @param client the new client that connected to the service
1171 * @param mq the message queue used to send messages to the client
1172 * @return @a c
1173 */
1174static void *
1175client_connect_cb (void *cls,
1176 struct GNUNET_SERVICE_Client *client,
1177 struct GNUNET_MQ_Handle *mq)
1178{
1179 struct CadetClient *c;
1180
1181 c = GNUNET_new (struct CadetClient);
1182 c->client = client;
1183 c->mq = mq;
1184 c->id = next_client_id++; /* overflow not important: just for debug */
1185 c->channels
1186 = GNUNET_CONTAINER_multihashmap32_create (32);
1187 GNUNET_CONTAINER_DLL_insert (clients_head,
1188 clients_tail,
1189 c);
1190 GNUNET_STATISTICS_update (stats,
1191 "# clients",
1192 +1,
1193 GNUNET_NO);
1194 LOG (GNUNET_ERROR_TYPE_DEBUG,
1195 "%s connected\n",
1196 GSC_2s (c));
1197 return c;
1198}
1199
1200
1201/**
1202 * A channel was destroyed by the other peer. Tell our client.
1203 *
1204 * @param c client that lost a channel
1205 * @param ccn channel identification number for the client
1206 * @param ch the channel object
1207 */
1208void
1209GSC_handle_remote_channel_destroy (struct CadetClient *c,
1210 struct GNUNET_CADET_ClientChannelNumber ccn,
1211 struct CadetChannel *ch)
1212{
1213 struct GNUNET_MQ_Envelope *env;
1214 struct GNUNET_CADET_LocalChannelDestroyMessage *tdm;
1215
1216 env = GNUNET_MQ_msg (tdm,
1217 GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY);
1218 tdm->ccn = ccn;
1219 GSC_send_to_client (c,
1220 env);
1221 GNUNET_assert (GNUNET_YES ==
1222 GNUNET_CONTAINER_multihashmap32_remove (c->channels,
1223 ntohl (ccn.channel_of_client),
1224 ch));
1225}
1226
1227
1228/**
1229 * A client that created a loose channel that was not bound to a port
1230 * disconnected, drop it from the #loose_channels list.
1231 *
1232 * @param h_port the hashed port the channel was trying to bind to
1233 * @param ch the channel that was lost
1234 */
1235void
1236GSC_drop_loose_channel (const struct GNUNET_HashCode *h_port,
1237 struct CadetChannel *ch)
1238{
1239 GNUNET_assert (GNUNET_YES ==
1240 GNUNET_CONTAINER_multihashmap_remove (loose_channels,
1241 h_port,
1242 ch));
1243}
1244
1245
1246/**
1247 * Iterator for deleting each channel whose client endpoint disconnected.
1248 *
1249 * @param cls Closure (client that has disconnected).
1250 * @param key The local channel id in host byte order
1251 * @param value The value stored at the key (channel to destroy).
1252 * @return #GNUNET_OK, keep iterating.
1253 */
1254static int
1255channel_destroy_iterator (void *cls,
1256 uint32_t key,
1257 void *value)
1258{
1259 struct CadetClient *c = cls;
1260 struct GNUNET_CADET_ClientChannelNumber ccn;
1261 struct CadetChannel *ch = value;
1262
1263 LOG (GNUNET_ERROR_TYPE_DEBUG,
1264 "Destroying %s, due to %s disconnecting.\n",
1265 GCCH_2s (ch),
1266 GSC_2s (c));
1267 ccn.channel_of_client = htonl (key);
1268 GCCH_channel_local_destroy (ch,
1269 c,
1270 ccn);
1271 GNUNET_assert (GNUNET_YES ==
1272 GNUNET_CONTAINER_multihashmap32_remove (c->channels,
1273 key,
1274 ch));
1275 return GNUNET_OK;
1276}
1277
1278
1279/**
1280 * Remove client's ports from the global hashmap on disconnect.
1281 *
1282 * @param cls the `struct CadetClient`
1283 * @param port the port.
1284 * @param value the `struct OpenPort` to remove
1285 * @return #GNUNET_OK, keep iterating.
1286 */
1287static int
1288client_release_ports (void *cls,
1289 const struct GNUNET_HashCode *port,
1290 void *value)
1291{
1292 struct CadetClient *c = cls;
1293 struct OpenPort *op = value;
1294
1295 GNUNET_assert (c == op->c);
1296 LOG (GNUNET_ERROR_TYPE_DEBUG,
1297 "Closing port %s due to %s disconnect.\n",
1298 GNUNET_h2s (port),
1299 GSC_2s (c));
1300 GNUNET_assert (GNUNET_YES ==
1301 GNUNET_CONTAINER_multihashmap_remove (open_ports,
1302 &op->h_port,
1303 op));
1304 GNUNET_assert (GNUNET_YES ==
1305 GNUNET_CONTAINER_multihashmap_remove (c->ports,
1306 port,
1307 op));
1308 GNUNET_free (op);
1309 return GNUNET_OK;
1310}
1311
1312
1313/**
1314 * Callback called when a client disconnected from the service
1315 *
1316 * @param cls closure for the service
1317 * @param client the client that disconnected
1318 * @param internal_cls should be equal to @a c
1319 */
1320static void
1321client_disconnect_cb (void *cls,
1322 struct GNUNET_SERVICE_Client *client,
1323 void *internal_cls)
1324{
1325 struct CadetClient *c = internal_cls;
1326
1327 GNUNET_assert (c->client == client);
1328 LOG (GNUNET_ERROR_TYPE_DEBUG,
1329 "%s is disconnecting.\n",
1330 GSC_2s (c));
1331 if (NULL != c->channels)
1332 {
1333 GNUNET_CONTAINER_multihashmap32_iterate (c->channels,
1334 &channel_destroy_iterator,
1335 c);
1336 GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap32_size (c->channels));
1337 GNUNET_CONTAINER_multihashmap32_destroy (c->channels);
1338 }
1339 if (NULL != c->ports)
1340 {
1341 GNUNET_CONTAINER_multihashmap_iterate (c->ports,
1342 &client_release_ports,
1343 c);
1344 GNUNET_CONTAINER_multihashmap_destroy (c->ports);
1345 }
1346 GNUNET_CONTAINER_DLL_remove (clients_head,
1347 clients_tail,
1348 c);
1349 GNUNET_STATISTICS_update (stats,
1350 "# clients",
1351 -1,
1352 GNUNET_NO);
1353 GNUNET_free (c);
1354 if ( (NULL == clients_head) &&
1355 (GNUNET_YES == shutting_down) )
1356 shutdown_rest ();
1357}
1358
1359
1360/**
1361 * Setup CADET internals.
1362 *
1363 * @param cls closure
1364 * @param server the initialized server
1365 * @param c configuration to use
1366 */
1367static void
1368run (void *cls,
1369 const struct GNUNET_CONFIGURATION_Handle *c,
1370 struct GNUNET_SERVICE_Handle *service)
1371{
1372 cfg = c;
1373 if (GNUNET_OK !=
1374 GNUNET_CONFIGURATION_get_value_number (c,
1375 "CADET",
1376 "RATCHET_MESSAGES",
1377 &ratchet_messages))
1378 {
1379 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
1380 "CADET",
1381 "RATCHET_MESSAGES",
1382 "needs to be a number");
1383 ratchet_messages = 64;
1384 }
1385 if (GNUNET_OK !=
1386 GNUNET_CONFIGURATION_get_value_time (c,
1387 "CADET",
1388 "RATCHET_TIME",
1389 &ratchet_time))
1390 {
1391 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
1392 "CADET",
1393 "RATCHET_TIME",
1394 "need delay value");
1395 ratchet_time = GNUNET_TIME_UNIT_HOURS;
1396 }
1397 if (GNUNET_OK !=
1398 GNUNET_CONFIGURATION_get_value_time (c,
1399 "CADET",
1400 "REFRESH_CONNECTION_TIME",
1401 &keepalive_period))
1402 {
1403 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
1404 "CADET",
1405 "REFRESH_CONNECTION_TIME",
1406 "need delay value");
1407 keepalive_period = GNUNET_TIME_UNIT_MINUTES;
1408 }
1409 if (GNUNET_OK !=
1410 GNUNET_CONFIGURATION_get_value_number (c,
1411 "CADET",
1412 "DROP_PERCENT",
1413 &drop_percent))
1414 {
1415 drop_percent = 0;
1416 }
1417 else
1418 {
1419 LOG (GNUNET_ERROR_TYPE_WARNING, "**************************************\n");
1420 LOG (GNUNET_ERROR_TYPE_WARNING, "Cadet is running with DROP enabled.\n");
1421 LOG (GNUNET_ERROR_TYPE_WARNING, "This is NOT a good idea!\n");
1422 LOG (GNUNET_ERROR_TYPE_WARNING, "Remove DROP_PERCENT from config file.\n");
1423 LOG (GNUNET_ERROR_TYPE_WARNING, "**************************************\n");
1424 }
1425 my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (c);
1426 if (NULL == my_private_key)
1427 {
1428 GNUNET_break (0);
1429 GNUNET_SCHEDULER_shutdown ();
1430 return;
1431 }
1432 GNUNET_CRYPTO_eddsa_key_get_public (my_private_key,
1433 &my_full_id.public_key);
1434 stats = GNUNET_STATISTICS_create ("cadet",
1435 c);
1436 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
1437 NULL);
1438 ats_ch = GNUNET_ATS_connectivity_init (c);
1439 /* FIXME: optimize code to allow GNUNET_YES here! */
1440 open_ports = GNUNET_CONTAINER_multihashmap_create (16,
1441 GNUNET_NO);
1442 loose_channels = GNUNET_CONTAINER_multihashmap_create (16,
1443 GNUNET_NO);
1444 peers = GNUNET_CONTAINER_multipeermap_create (16,
1445 GNUNET_YES);
1446 connections = GNUNET_CONTAINER_multishortmap_create (256,
1447 GNUNET_YES);
1448 GCH_init (c);
1449 GCD_init (c);
1450 GCO_init (c);
1451 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1452 "CADET started for peer %s\n",
1453 GNUNET_i2s (&my_full_id));
1454
1455}
1456
1457
1458/**
1459 * Define "main" method using service macro.
1460 */
1461GNUNET_SERVICE_MAIN
1462("cadet",
1463 GNUNET_SERVICE_OPTION_NONE,
1464 &run,
1465 &client_connect_cb,
1466 &client_disconnect_cb,
1467 NULL,
1468 GNUNET_MQ_hd_fixed_size (port_open,
1469 GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_OPEN,
1470 struct GNUNET_CADET_PortMessage,
1471 NULL),
1472 GNUNET_MQ_hd_fixed_size (port_close,
1473 GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE,
1474 struct GNUNET_CADET_PortMessage,
1475 NULL),
1476 GNUNET_MQ_hd_fixed_size (channel_create,
1477 GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE,
1478 struct GNUNET_CADET_LocalChannelCreateMessage,
1479 NULL),
1480 GNUNET_MQ_hd_fixed_size (channel_destroy,
1481 GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY,
1482 struct GNUNET_CADET_LocalChannelDestroyMessage,
1483 NULL),
1484 GNUNET_MQ_hd_var_size (local_data,
1485 GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA,
1486 struct GNUNET_CADET_LocalData,
1487 NULL),
1488 GNUNET_MQ_hd_fixed_size (local_ack,
1489 GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK,
1490 struct GNUNET_CADET_LocalAck,
1491 NULL),
1492 GNUNET_MQ_hd_fixed_size (get_peers,
1493 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS,
1494 struct GNUNET_MessageHeader,
1495 NULL),
1496 GNUNET_MQ_hd_fixed_size (show_peer,
1497 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER,
1498 struct GNUNET_CADET_LocalInfo,
1499 NULL),
1500 GNUNET_MQ_hd_fixed_size (info_tunnels,
1501 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS,
1502 struct GNUNET_MessageHeader,
1503 NULL),
1504 GNUNET_MQ_hd_fixed_size (info_tunnel,
1505 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL,
1506 struct GNUNET_CADET_LocalInfo,
1507 NULL),
1508 GNUNET_MQ_hd_fixed_size (info_dump,
1509 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_DUMP,
1510 struct GNUNET_MessageHeader,
1511 NULL),
1512 GNUNET_MQ_handler_end ());
1513
1514/* end of gnunet-service-cadet-new.c */
diff --git a/src/cadet/gnunet-service-cadet-new.h b/src/cadet/gnunet-service-cadet.h
index 4a76c578b..162867823 100644
--- a/src/cadet/gnunet-service-cadet-new.h
+++ b/src/cadet/gnunet-service-cadet.h
@@ -20,7 +20,7 @@
20*/ 20*/
21 21
22/** 22/**
23 * @file cadet/gnunet-service-cadet-new.h 23 * @file cadet/gnunet-service-cadet.h
24 * @brief Information we track per peer. 24 * @brief Information we track per peer.
25 * @author Bartlomiej Polot 25 * @author Bartlomiej Polot
26 * @author Christian Grothoff 26 * @author Christian Grothoff
@@ -29,7 +29,6 @@
29#define GNUNET_SERVICE_CADET_H 29#define GNUNET_SERVICE_CADET_H
30 30
31#include "gnunet_util_lib.h" 31#include "gnunet_util_lib.h"
32#define NEW_CADET 1
33#include "cadet_protocol.h" 32#include "cadet_protocol.h"
34 33
35/** 34/**
@@ -146,6 +145,30 @@ struct CadetTConnection
146 145
147 146
148/** 147/**
148 * Port opened by a client.
149 */
150struct OpenPort
151{
152
153 /**
154 * Client that opened the port.
155 */
156 struct CadetClient *c;
157
158 /**
159 * Port number.
160 */
161 struct GNUNET_HashCode port;
162
163 /**
164 * Port hashed with our PID (matches incoming OPEN messages).
165 */
166 struct GNUNET_HashCode h_port;
167
168};
169
170
171/**
149 * Active path through the network (used by a tunnel). There may 172 * Active path through the network (used by a tunnel). There may
150 * be at most one connection per path. 173 * be at most one connection per path.
151 */ 174 */
@@ -193,7 +216,8 @@ extern struct GNUNET_PeerIdentity my_full_id;
193extern struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key; 216extern struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key;
194 217
195/** 218/**
196 * All ports clients of this peer have opened. 219 * All ports clients of this peer have opened. Maps from
220 * a hashed port to a `struct OpenPort`.
197 */ 221 */
198extern struct GNUNET_CONTAINER_MultiHashMap *open_ports; 222extern struct GNUNET_CONTAINER_MultiHashMap *open_ports;
199 223
@@ -206,7 +230,7 @@ extern struct GNUNET_CONTAINER_MultiShortmap *connections;
206/** 230/**
207 * Map from ports to channels where the ports were closed at the 231 * Map from ports to channels where the ports were closed at the
208 * time we got the inbound connection. 232 * time we got the inbound connection.
209 * Indexed by port, contains `struct CadetChannel`. 233 * Indexed by h_port, contains `struct CadetChannel`.
210 */ 234 */
211extern struct GNUNET_CONTAINER_MultiHashMap *loose_channels; 235extern struct GNUNET_CONTAINER_MultiHashMap *loose_channels;
212 236
@@ -226,10 +250,20 @@ extern unsigned long long ratchet_messages;
226extern struct GNUNET_TIME_Relative ratchet_time; 250extern struct GNUNET_TIME_Relative ratchet_time;
227 251
228/** 252/**
253 * How frequently do we send KEEPALIVE messages on idle connections?
254 */
255extern struct GNUNET_TIME_Relative keepalive_period;
256
257/**
229 * Signal that shutdown is happening: prevent recovery measures. 258 * Signal that shutdown is happening: prevent recovery measures.
230 */ 259 */
231extern int shutting_down; 260extern int shutting_down;
232 261
262/**
263 * Set to non-zero values to create random drops to test retransmissions.
264 */
265extern unsigned long long drop_percent;
266
233 267
234/** 268/**
235 * Send a message to a client. 269 * Send a message to a client.
@@ -254,6 +288,17 @@ GSC_handle_remote_channel_destroy (struct CadetClient *c,
254 struct GNUNET_CADET_ClientChannelNumber ccn, 288 struct GNUNET_CADET_ClientChannelNumber ccn,
255 struct CadetChannel *ch); 289 struct CadetChannel *ch);
256 290
291/**
292 * A client that created a loose channel that was not bound to a port
293 * disconnected, drop it from the #loose_channels list.
294 *
295 * @param h_port the hashed port the channel was trying to bind to
296 * @param ch the channel that was lost
297 */
298void
299GSC_drop_loose_channel (const struct GNUNET_HashCode *h_port,
300 struct CadetChannel *ch);
301
257 302
258/** 303/**
259 * Bind incoming channel to this client, and notify client 304 * Bind incoming channel to this client, and notify client
diff --git a/src/cadet/gnunet-service-cadet_channel.c b/src/cadet/gnunet-service-cadet_channel.c
index 7b7c6e57c..739b68228 100644
--- a/src/cadet/gnunet-service-cadet_channel.c
+++ b/src/cadet/gnunet-service-cadet_channel.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2013 GNUnet e.V. 3 Copyright (C) 2001-2017 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -17,31 +17,63 @@
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA. 18 Boston, MA 02110-1301, USA.
19*/ 19*/
20 20/**
21 21 * @file cadet/gnunet-service-cadet_channel.c
22 * @brief logical links between CADET clients
23 * @author Bartlomiej Polot
24 * @author Christian Grothoff
25 *
26 * TODO:
27 * - Congestion/flow control:
28 * + estimate max bandwidth using bursts and use to for CONGESTION CONTROL!
29 * (and figure out how/where to use this!)
30 * + figure out flow control without ACKs (unreliable traffic!)
31 * - revisit handling of 'unbuffered' traffic!
32 * (need to push down through tunnel into connection selection)
33 * - revisit handling of 'buffered' traffic: 4 is a rather small buffer; maybe
34 * reserve more bits in 'options' to allow for buffer size control?
35 */
22#include "platform.h" 36#include "platform.h"
23#include "gnunet_util_lib.h" 37#include "cadet.h"
24
25#include "gnunet_statistics_service.h" 38#include "gnunet_statistics_service.h"
39#include "gnunet-service-cadet_channel.h"
40#include "gnunet-service-cadet_connection.h"
41#include "gnunet-service-cadet_tunnels.h"
42#include "gnunet-service-cadet_paths.h"
26 43
27#include "cadet.h" 44#define LOG(level,...) GNUNET_log_from (level,"cadet-chn",__VA_ARGS__)
28#include "cadet_protocol.h"
29 45
30#include "gnunet-service-cadet_channel.h" 46/**
31#include "gnunet-service-cadet_local.h" 47 * How long do we initially wait before retransmitting?
32#include "gnunet-service-cadet_tunnel.h" 48 */
33#include "gnunet-service-cadet_peer.h" 49#define CADET_INITIAL_RETRANSMIT_TIME GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 250)
34 50
35#define LOG(level, ...) GNUNET_log_from(level,"cadet-chn",__VA_ARGS__) 51/**
36#define LOG2(level, ...) GNUNET_log_from_nocheck(level,"cadet-chn",__VA_ARGS__) 52 * How long do we wait before dropping state about incoming
53 * connection to closed port?
54 */
55#define TIMEOUT_CLOSED_PORT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 30)
37 56
38#define CADET_RETRANSMIT_TIME GNUNET_TIME_relative_multiply(\ 57/**
39 GNUNET_TIME_UNIT_MILLISECONDS, 250) 58 * How long do we wait at least before retransmitting ever?
40#define CADET_RETRANSMIT_MARGIN 4 59 */
60#define MIN_RTT_DELAY GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 75)
61
62/**
63 * Maximum message ID into the future we accept for out-of-order messages.
64 * If the message is more than this into the future, we drop it. This is
65 * important both to detect values that are actually in the past, as well
66 * as to limit adversarially triggerable memory consumption.
67 *
68 * Note that right now we have "max_pending_messages = 4" hard-coded in
69 * the logic below, so a value of 4 would suffice here. But we plan to
70 * allow larger windows in the future...
71 */
72#define MAX_OUT_OF_ORDER_DISTANCE 1024
41 73
42 74
43/** 75/**
44 * All the states a connection can be in. 76 * All the states a channel can be in.
45 */ 77 */
46enum CadetChannelState 78enum CadetChannelState
47{ 79{
@@ -51,9 +83,15 @@ enum CadetChannelState
51 CADET_CHANNEL_NEW, 83 CADET_CHANNEL_NEW,
52 84
53 /** 85 /**
54 * Connection create message sent, waiting for ACK. 86 * Channel is to a port that is not open, we're waiting for the
87 * port to be opened.
88 */
89 CADET_CHANNEL_LOOSE,
90
91 /**
92 * CHANNEL_OPEN message sent, waiting for CHANNEL_OPEN_ACK.
55 */ 93 */
56 CADET_CHANNEL_SENT, 94 CADET_CHANNEL_OPEN_SENT,
57 95
58 /** 96 /**
59 * Connection confirmed, ready to carry traffic. 97 * Connection confirmed, ready to carry traffic.
@@ -63,138 +101,144 @@ enum CadetChannelState
63 101
64 102
65/** 103/**
66 * Info holder for channel messages in queues. 104 * Info needed to retry a message in case it gets lost.
105 * Note that we DO use this structure also for unreliable
106 * messages.
67 */ 107 */
68struct CadetChannelQueue 108struct CadetReliableMessage
69{ 109{
70 /** 110 /**
71 * Tunnel Queue. 111 * Double linked list, FIFO style
72 */ 112 */
73 struct CadetTunnelQueue *tq; 113 struct CadetReliableMessage *next;
74 114
75 /** 115 /**
76 * Message type (DATA/DATA_ACK) 116 * Double linked list, FIFO style
77 */ 117 */
78 uint16_t type; 118 struct CadetReliableMessage *prev;
79 119
80 /** 120 /**
81 * Message copy (for DATAs, to start retransmission timer) 121 * Which channel is this message in?
82 */ 122 */
83 struct CadetReliableMessage *copy; 123 struct CadetChannel *ch;
84 124
85 /** 125 /**
86 * Reliability (for DATA_ACKs, to access rel->ack_q) 126 * Entry in the tunnels queue for this message, NULL if it has left
127 * the tunnel. Used to cancel transmission in case we receive an
128 * ACK in time.
87 */ 129 */
88 struct CadetChannelReliability *rel; 130 struct CadetTunnelQueueEntry *qe;
89};
90
91 131
92/**
93 * Info needed to retry a message in case it gets lost.
94 */
95struct CadetReliableMessage
96{
97 /** 132 /**
98 * Double linked list, FIFO style 133 * Data message we are trying to send.
99 */ 134 */
100 struct CadetReliableMessage *next; 135 struct GNUNET_CADET_ChannelAppDataMessage *data_message;
101 struct CadetReliableMessage *prev;
102 136
103 /** 137 /**
104 * Type of message (payload, channel management). 138 * How soon should we retry if we fail to get an ACK?
139 * Messages in the queue are sorted by this value.
105 */ 140 */
106 int16_t type; 141 struct GNUNET_TIME_Absolute next_retry;
107 142
108 /** 143 /**
109 * Tunnel Reliability queue this message is in. 144 * How long do we wait for an ACK after transmission?
145 * Use for the back-off calculation.
110 */ 146 */
111 struct CadetChannelReliability *rel; 147 struct GNUNET_TIME_Relative retry_delay;
112 148
113 /** 149 /**
114 * ID of the message (ACK needed to free) 150 * Time when we first successfully transmitted the message
151 * (that is, set @e num_transmissions to 1).
115 */ 152 */
116 uint32_t mid; 153 struct GNUNET_TIME_Absolute first_transmission_time;
117 154
118 /** 155 /**
119 * Tunnel Queue. 156 * Identifier of the connection that this message took when it
157 * was first transmitted. Only useful if @e num_transmissions is 1.
120 */ 158 */
121 struct CadetChannelQueue *chq; 159 struct GNUNET_CADET_ConnectionTunnelIdentifier connection_taken;
122 160
123 /** 161 /**
124 * When was this message issued (to calculate ACK delay) 162 * How often was this message transmitted? #GNUNET_SYSERR if there
163 * was an error transmitting the message, #GNUNET_NO if it was not
164 * yet transmitted ever, otherwise the number of (re) transmissions.
125 */ 165 */
126 struct GNUNET_TIME_Absolute timestamp; 166 int num_transmissions;
127 167
128 /* struct GNUNET_CADET_ChannelAppDataMessage with payload */
129}; 168};
130 169
131 170
132/** 171/**
133 * Info about the traffic state for a client in a channel. 172 * List of received out-of-order data messages.
134 */ 173 */
135struct CadetChannelReliability 174struct CadetOutOfOrderMessage
136{ 175{
137 /** 176 /**
138 * Channel this is about. 177 * Double linked list, FIFO style
139 */ 178 */
140 struct CadetChannel *ch; 179 struct CadetOutOfOrderMessage *next;
141 180
142 /** 181 /**
143 * DLL of messages sent and not yet ACK'd. 182 * Double linked list, FIFO style
144 */ 183 */
145 struct CadetReliableMessage *head_sent; 184 struct CadetOutOfOrderMessage *prev;
146 struct CadetReliableMessage *tail_sent;
147 185
148 /** 186 /**
149 * DLL of messages received out of order. 187 * ID of the message (messages up to this point needed
188 * before we give this one to the client).
150 */ 189 */
151 struct CadetReliableMessage *head_recv; 190 struct ChannelMessageIdentifier mid;
152 struct CadetReliableMessage *tail_recv;
153 191
154 /** 192 /**
155 * Messages received. 193 * The envelope with the payload of the out-of-order message
156 */ 194 */
157 unsigned int n_recv; 195 struct GNUNET_MQ_Envelope *env;
158 196
159 /** 197};
160 * Next MID to use for outgoing traffic.
161 */
162 uint32_t mid_send;
163 198
164 /**
165 * Next MID expected for incoming traffic.
166 */
167 uint32_t mid_recv;
168 199
200/**
201 * Client endpoint of a `struct CadetChannel`. A channel may be a
202 * loopback channel, in which case it has two of these endpoints.
203 * Note that flow control also is required in both directions.
204 */
205struct CadetChannelClient
206{
169 /** 207 /**
170 * Handle for queued unique data CREATE, DATA_ACK. 208 * Client handle. Not by itself sufficient to designate
209 * the client endpoint, as the same client handle may
210 * be used for both the owner and the destination, and
211 * we thus also need the channel ID to identify the client.
171 */ 212 */
172 struct CadetChannelQueue *uniq; 213 struct CadetClient *c;
173 214
174 /** 215 /**
175 * Can we send data to the client? 216 * Head of DLL of messages received out of order or while client was unready.
176 */ 217 */
177 int client_ready; 218 struct CadetOutOfOrderMessage *head_recv;
178 219
179 /** 220 /**
180 * Can the client send data to us? 221 * Tail DLL of messages received out of order or while client was unready.
181 */ 222 */
182 int client_allowed; 223 struct CadetOutOfOrderMessage *tail_recv;
183 224
184 /** 225 /**
185 * Task to resend/poll in case no ACK is received. 226 * Local tunnel number for this client.
227 * (if owner >= #GNUNET_CADET_LOCAL_CHANNEL_ID_CLI,
228 * otherwise < #GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
186 */ 229 */
187 struct GNUNET_SCHEDULER_Task * retry_task; 230 struct GNUNET_CADET_ClientChannelNumber ccn;
188 231
189 /** 232 /**
190 * Counter for exponential backoff. 233 * Number of entries currently in @a head_recv DLL.
191 */ 234 */
192 struct GNUNET_TIME_Relative retry_timer; 235 unsigned int num_recv;
193 236
194 /** 237 /**
195 * How long does it usually take to get an ACK. 238 * Can we send data to the client?
196 */ 239 */
197 struct GNUNET_TIME_Relative expected_delay; 240 int client_ready;
241
198}; 242};
199 243
200 244
@@ -209,41 +253,44 @@ struct CadetChannel
209 struct CadetTunnel *t; 253 struct CadetTunnel *t;
210 254
211 /** 255 /**
212 * Destination port of the channel. 256 * Client owner of the tunnel, if any.
257 * (Used if this channel represends the initiating end of the tunnel.)
213 */ 258 */
214 struct GNUNET_HashCode port; 259 struct CadetChannelClient *owner;
215 260
216 /** 261 /**
217 * Global channel number ( < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI) 262 * Client destination of the tunnel, if any.
263 * (Used if this channel represents the listening end of the tunnel.)
218 */ 264 */
219 struct GNUNET_CADET_ChannelTunnelNumber gid; 265 struct CadetChannelClient *dest;
220 266
221 /** 267 /**
222 * Local tunnel number for root (owner) client. 268 * Last entry in the tunnel's queue relating to control messages
223 * ( >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI or 0 ) 269 * (#GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN or
270 * #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK). Used to cancel
271 * transmission in case we receive updated information.
224 */ 272 */
225 struct GNUNET_CADET_ClientChannelNumber lid_root; 273 struct CadetTunnelQueueEntry *last_control_qe;
226 274
227 /** 275 /**
228 * Local tunnel number for local destination clients (incoming number) 276 * Head of DLL of messages sent and not yet ACK'd.
229 * ( >= GNUNET_CADET_LOCAL_CHANNEL_ID_SERV or 0).
230 */ 277 */
231 struct GNUNET_CADET_ClientChannelNumber lid_dest; 278 struct CadetReliableMessage *head_sent;
232 279
233 /** 280 /**
234 * Channel state. 281 * Tail of DLL of messages sent and not yet ACK'd.
235 */ 282 */
236 enum CadetChannelState state; 283 struct CadetReliableMessage *tail_sent;
237 284
238 /** 285 /**
239 * Is the tunnel bufferless (minimum latency)? 286 * Task to resend/poll in case no ACK is received.
240 */ 287 */
241 int nobuffer; 288 struct GNUNET_SCHEDULER_Task *retry_control_task;
242 289
243 /** 290 /**
244 * Is the tunnel reliable? 291 * Task to resend/poll in case no ACK is received.
245 */ 292 */
246 int reliable; 293 struct GNUNET_SCHEDULER_Task *retry_data_task;
247 294
248 /** 295 /**
249 * Last time the channel was used 296 * Last time the channel was used
@@ -251,21 +298,34 @@ struct CadetChannel
251 struct GNUNET_TIME_Absolute timestamp; 298 struct GNUNET_TIME_Absolute timestamp;
252 299
253 /** 300 /**
254 * Client owner of the tunnel, if any 301 * Destination port of the channel.
255 */ 302 */
256 struct CadetClient *root; 303 struct GNUNET_HashCode port;
257 304
258 /** 305 /**
259 * Client destination of the tunnel, if any. 306 * Hash'ed port of the channel with initiator and destination PID.
260 */ 307 */
261 struct CadetClient *dest; 308 struct GNUNET_HashCode h_port;
262 309
263 /** 310 /**
264 * Flag to signal the destruction of the channel. 311 * Counter for exponential backoff.
265 * If this is set to #GNUNET_YES the channel will be destroyed
266 * when the queue is empty.
267 */ 312 */
268 int destroy; 313 struct GNUNET_TIME_Relative retry_time;
314
315 /**
316 * Bitfield of already-received messages past @e mid_recv.
317 */
318 uint64_t mid_futures;
319
320 /**
321 * Next MID expected for incoming traffic.
322 */
323 struct ChannelMessageIdentifier mid_recv;
324
325 /**
326 * Next MID to use for outgoing traffic.
327 */
328 struct ChannelMessageIdentifier mid_send;
269 329
270 /** 330 /**
271 * Total (reliable) messages pending ACK for this channel. 331 * Total (reliable) messages pending ACK for this channel.
@@ -273,2290 +333,1763 @@ struct CadetChannel
273 unsigned int pending_messages; 333 unsigned int pending_messages;
274 334
275 /** 335 /**
276 * Reliability data. 336 * Maximum (reliable) messages pending ACK for this channel
277 * Only present (non-NULL) at the owner of a tunnel. 337 * before we throttle the client.
278 */ 338 */
279 struct CadetChannelReliability *root_rel; 339 unsigned int max_pending_messages;
280 340
281 /** 341 /**
282 * Reliability data. 342 * Number identifying this channel in its tunnel.
283 * Only present (non-NULL) at the destination of a tunnel.
284 */ 343 */
285 struct CadetChannelReliability *dest_rel; 344 struct GNUNET_CADET_ChannelTunnelNumber ctn;
286 345
287}; 346 /**
347 * Channel state.
348 */
349 enum CadetChannelState state;
350
351 /**
352 * Count how many ACKs we skipped, used to prevent long
353 * sequences of ACK skipping.
354 */
355 unsigned int skip_ack_series;
288 356
357 /**
358 * Is the tunnel bufferless (minimum latency)?
359 */
360 int nobuffer;
289 361
290/******************************************************************************/ 362 /**
291/******************************* GLOBALS ***********************************/ 363 * Is the tunnel reliable?
292/******************************************************************************/ 364 */
365 int reliable;
293 366
294/** 367 /**
295 * Global handle to the statistics service. 368 * Is the tunnel out-of-order?
296 */ 369 */
297extern struct GNUNET_STATISTICS_Handle *stats; 370 int out_of_order;
298 371
299/** 372 /**
300 * Local peer own ID (memory efficient handle). 373 * Is this channel a loopback channel, where the destination is us again?
301 */ 374 */
302extern GNUNET_PEER_Id myid; 375 int is_loopback;
303 376
377 /**
378 * Flag to signal the destruction of the channel. If this is set to
379 * #GNUNET_YES the channel will be destroyed once the queue is
380 * empty.
381 */
382 int destroy;
304 383
305/******************************************************************************/ 384};
306/******************************** STATIC ***********************************/
307/******************************************************************************/
308 385
309 386
310/** 387/**
311 * Destroy a reliable message after it has been acknowledged, either by 388 * Get the static string for identification of the channel.
312 * direct mid ACK or bitfield. Updates the appropriate data structures and
313 * timers and frees all memory.
314 * 389 *
315 * @param copy Message that is no longer needed: remote peer got it. 390 * @param ch Channel.
316 * @param update_time Is the timing information relevant?
317 * If this message is ACK in a batch the timing information
318 * is skewed by the retransmission, count only for the
319 * retransmitted message.
320 * 391 *
321 * @return #GNUNET_YES if channel was destroyed as a result of the call, 392 * @return Static string with the channel IDs.
322 * #GNUNET_NO otherwise.
323 */ 393 */
324static int 394const char *
325rel_message_free (struct CadetReliableMessage *copy, int update_time); 395GCCH_2s (const struct CadetChannel *ch)
396{
397 static char buf[128];
398
399 GNUNET_snprintf (buf,
400 sizeof (buf),
401 "Channel %s:%s ctn:%X(%X/%X)",
402 (GNUNET_YES == ch->is_loopback)
403 ? "loopback"
404 : GNUNET_i2s (GCP_get_id (GCT_get_destination (ch->t))),
405 GNUNET_h2s (&ch->port),
406 ch->ctn,
407 (NULL == ch->owner) ? 0 : ntohl (ch->owner->ccn.channel_of_client),
408 (NULL == ch->dest) ? 0 : ntohl (ch->dest->ccn.channel_of_client));
409 return buf;
410}
326 411
327/**
328 * send a channel create message.
329 *
330 * @param ch Channel for which to send.
331 */
332static void
333send_create (struct CadetChannel *ch);
334 412
335/** 413/**
336 * Confirm we got a channel create, FWD ack. 414 * Hash the @a port and @a initiator and @a listener to
415 * calculate the "challenge" @a h_port we send to the other
416 * peer on #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN.
337 * 417 *
338 * @param ch The channel to confirm. 418 * @param[out] h_port set to the hash of @a port, @a initiator and @a listener
339 * @param fwd Should we send a FWD ACK? (going dest->root) 419 * @param port cadet port, as seen by CADET clients
420 * @param listener peer that is listining on @a port
340 */ 421 */
341static void 422void
342send_ack (struct CadetChannel *ch, int fwd); 423GCCH_hash_port (struct GNUNET_HashCode *h_port,
343 424 const struct GNUNET_HashCode *port,
425 const struct GNUNET_PeerIdentity *listener)
426{
427 struct GNUNET_HashContext *hc;
428
429 hc = GNUNET_CRYPTO_hash_context_start ();
430 GNUNET_CRYPTO_hash_context_read (hc,
431 port,
432 sizeof (*port));
433 GNUNET_CRYPTO_hash_context_read (hc,
434 listener,
435 sizeof (*listener));
436 GNUNET_CRYPTO_hash_context_finish (hc,
437 h_port);
438 LOG (GNUNET_ERROR_TYPE_DEBUG,
439 "Calculated port hash %s\n",
440 GNUNET_h2s (h_port));
441}
344 442
345 443
346/** 444/**
347 * Test if the channel is loopback: both root and dest are on the local peer. 445 * Get the channel's public ID.
348 * 446 *
349 * @param ch Channel to test. 447 * @param ch Channel.
350 * 448 *
351 * @return #GNUNET_YES if channel is loopback, #GNUNET_NO otherwise. 449 * @return ID used to identify the channel with the remote peer.
352 */ 450 */
353static int 451struct GNUNET_CADET_ChannelTunnelNumber
354is_loopback (const struct CadetChannel *ch) 452GCCH_get_id (const struct CadetChannel *ch)
355{ 453{
356 if (NULL != ch->t) 454 return ch->ctn;
357 return GCT_is_loopback (ch->t);
358
359 return (NULL != ch->root && NULL != ch->dest);
360} 455}
361 456
362 457
363/** 458/**
364 * Save a copy of the data message for later retransmission. 459 * Release memory associated with @a ccc
365 * 460 *
366 * @param msg Message to copy. 461 * @param ccc data structure to clean up
367 * @param mid Message ID.
368 * @param rel Reliability data for retransmission.
369 */ 462 */
370static struct CadetReliableMessage * 463static void
371copy_message (const struct GNUNET_CADET_ChannelAppDataMessage *msg, uint32_t mid, 464free_channel_client (struct CadetChannelClient *ccc)
372 struct CadetChannelReliability *rel)
373{ 465{
374 struct CadetReliableMessage *copy; 466 struct CadetOutOfOrderMessage *com;
375 uint16_t size;
376
377 size = ntohs (msg->header.size);
378 copy = GNUNET_malloc (sizeof (*copy) + size);
379 copy->mid = mid;
380 copy->rel = rel;
381 copy->type = GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA;
382 GNUNET_memcpy (&copy[1], msg, size);
383 467
384 return copy; 468 while (NULL != (com = ccc->head_recv))
469 {
470 GNUNET_CONTAINER_DLL_remove (ccc->head_recv,
471 ccc->tail_recv,
472 com);
473 ccc->num_recv--;
474 GNUNET_MQ_discard (com->env);
475 GNUNET_free (com);
476 }
477 GNUNET_free (ccc);
385} 478}
386 479
480
387/** 481/**
388 * We have received a message out of order, or the client is not ready. 482 * Destroy the given channel.
389 * Buffer it until we receive an ACK from the client or the missing
390 * message from the channel.
391 * 483 *
392 * @param msg Message to buffer (MUST be of type CADET_DATA). 484 * @param ch channel to destroy
393 * @param rel Reliability data to the corresponding direction.
394 */ 485 */
395static void 486static void
396add_buffered_data (const struct GNUNET_CADET_ChannelAppDataMessage *msg, 487channel_destroy (struct CadetChannel *ch)
397 struct CadetChannelReliability *rel)
398{ 488{
399 struct CadetReliableMessage *copy; 489 struct CadetReliableMessage *crm;
400 struct CadetReliableMessage *prev;
401 uint32_t mid;
402 490
403 mid = ntohl (msg->mid); 491 while (NULL != (crm = ch->head_sent))
404
405 LOG (GNUNET_ERROR_TYPE_DEBUG, "add_buffered_data MID %u (%u)\n",
406 mid, rel->n_recv);
407
408 rel->n_recv++;
409
410 // FIXME do something better than O(n), although n < 64...
411 // FIXME start from the end (most messages are the latest ones)
412 for (prev = rel->head_recv; NULL != prev; prev = prev->next)
413 { 492 {
414 LOG (GNUNET_ERROR_TYPE_DEBUG, " prev %u\n", prev->mid); 493 GNUNET_assert (ch == crm->ch);
415 if (prev->mid == mid) 494 if (NULL != crm->qe)
416 { 495 {
417 LOG (GNUNET_ERROR_TYPE_DEBUG, " already there!\n"); 496 GCT_send_cancel (crm->qe);
418 rel->n_recv--; 497 crm->qe = NULL;
419 return;
420 }
421 else if (GC_is_pid_bigger (prev->mid, mid))
422 {
423 LOG (GNUNET_ERROR_TYPE_DEBUG, " bingo!\n");
424 copy = copy_message (msg, mid, rel);
425 GNUNET_CONTAINER_DLL_insert_before (rel->head_recv, rel->tail_recv,
426 prev, copy);
427 return;
428 } 498 }
499 GNUNET_CONTAINER_DLL_remove (ch->head_sent,
500 ch->tail_sent,
501 crm);
502 GNUNET_free (crm->data_message);
503 GNUNET_free (crm);
429 } 504 }
430 copy = copy_message (msg, mid, rel); 505 if (NULL != ch->owner)
431 LOG (GNUNET_ERROR_TYPE_DEBUG, " insert at tail! (now: %u)\n", rel->n_recv); 506 {
432 GNUNET_CONTAINER_DLL_insert_tail (rel->head_recv, rel->tail_recv, copy); 507 free_channel_client (ch->owner);
433 LOG (GNUNET_ERROR_TYPE_DEBUG, "add_buffered_data END\n"); 508 ch->owner = NULL;
509 }
510 if (NULL != ch->dest)
511 {
512 free_channel_client (ch->dest);
513 ch->dest = NULL;
514 }
515 if (NULL != ch->last_control_qe)
516 {
517 GCT_send_cancel (ch->last_control_qe);
518 ch->last_control_qe = NULL;
519 }
520 if (NULL != ch->retry_data_task)
521 {
522 GNUNET_SCHEDULER_cancel (ch->retry_data_task);
523 ch->retry_data_task = NULL;
524 }
525 if (NULL != ch->retry_control_task)
526 {
527 GNUNET_SCHEDULER_cancel (ch->retry_control_task);
528 ch->retry_control_task = NULL;
529 }
530 if (GNUNET_NO == ch->is_loopback)
531 {
532 GCT_remove_channel (ch->t,
533 ch,
534 ch->ctn);
535 ch->t = NULL;
536 }
537 GNUNET_free (ch);
434} 538}
435 539
436 540
437/** 541/**
438 * Add a destination client to a channel, initializing all data structures 542 * Send a channel create message.
439 * in the channel and the client.
440 * 543 *
441 * @param ch Channel to which add the destination. 544 * @param cls Channel for which to send.
442 * @param c Client which to add to the channel.
443 */ 545 */
444static void 546static void
445add_destination (struct CadetChannel *ch, struct CadetClient *c) 547send_channel_open (void *cls);
446{
447 if (NULL != ch->dest)
448 {
449 GNUNET_break (0);
450 return;
451 }
452
453 /* Assign local id as destination */
454 ch->lid_dest = GML_get_next_ccn (c);
455
456 /* Store in client's hashmap */
457 GML_channel_add (c, ch->lid_dest, ch);
458
459 GNUNET_break (NULL == ch->dest_rel);
460 ch->dest_rel = GNUNET_new (struct CadetChannelReliability);
461 ch->dest_rel->ch = ch;
462 ch->dest_rel->expected_delay.rel_value_us = 0;
463 ch->dest_rel->retry_timer = CADET_RETRANSMIT_TIME;
464
465 ch->dest = c;
466}
467 548
468 549
469/** 550/**
470 * Set options in a channel, extracted from a bit flag field. 551 * Function called once the tunnel confirms that we sent the
552 * create message. Delays for a bit until we retry.
471 * 553 *
472 * @param ch Channel to set options to. 554 * @param cls our `struct CadetChannel`.
473 * @param options Bit array in host byte order. 555 * @param cid identifier of the connection within the tunnel, NULL
556 * if transmission failed
474 */ 557 */
475static void 558static void
476channel_set_options (struct CadetChannel *ch, uint32_t options) 559channel_open_sent_cb (void *cls,
560 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
477{ 561{
478 ch->nobuffer = (options & GNUNET_CADET_OPTION_NOBUFFER) != 0 ? 562 struct CadetChannel *ch = cls;
479 GNUNET_YES : GNUNET_NO; 563
480 ch->reliable = (options & GNUNET_CADET_OPTION_RELIABLE) != 0 ? 564 GNUNET_assert (NULL != ch->last_control_qe);
481 GNUNET_YES : GNUNET_NO; 565 ch->last_control_qe = NULL;
566 ch->retry_time = GNUNET_TIME_STD_BACKOFF (ch->retry_time);
567 LOG (GNUNET_ERROR_TYPE_DEBUG,
568 "Sent CADET_CHANNEL_OPEN on %s, retrying in %s\n",
569 GCCH_2s (ch),
570 GNUNET_STRINGS_relative_time_to_string (ch->retry_time,
571 GNUNET_YES));
572 ch->retry_control_task
573 = GNUNET_SCHEDULER_add_delayed (ch->retry_time,
574 &send_channel_open,
575 ch);
482} 576}
483 577
484 578
485/** 579/**
486 * Get a bit flag field with the options of a channel. 580 * Send a channel open message.
487 *
488 * @param ch Channel to get options from.
489 * 581 *
490 * @return Bit array in host byte order. 582 * @param cls Channel for which to send.
491 */ 583 */
492static uint32_t 584static void
493channel_get_options (struct CadetChannel *ch) 585send_channel_open (void *cls)
494{ 586{
587 struct CadetChannel *ch = cls;
588 struct GNUNET_CADET_ChannelOpenMessage msgcc;
495 uint32_t options; 589 uint32_t options;
496 590
591 ch->retry_control_task = NULL;
592 LOG (GNUNET_ERROR_TYPE_DEBUG,
593 "Sending CHANNEL_OPEN message for %s\n",
594 GCCH_2s (ch));
497 options = 0; 595 options = 0;
498 if (ch->nobuffer) 596 if (ch->nobuffer)
499 options |= GNUNET_CADET_OPTION_NOBUFFER; 597 options |= GNUNET_CADET_OPTION_NOBUFFER;
500 if (ch->reliable) 598 if (ch->reliable)
501 options |= GNUNET_CADET_OPTION_RELIABLE; 599 options |= GNUNET_CADET_OPTION_RELIABLE;
502 600 if (ch->out_of_order)
503 return options; 601 options |= GNUNET_CADET_OPTION_OUT_OF_ORDER;
602 msgcc.header.size = htons (sizeof (msgcc));
603 msgcc.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN);
604 msgcc.opt = htonl (options);
605 msgcc.h_port = ch->h_port;
606 msgcc.ctn = ch->ctn;
607 ch->state = CADET_CHANNEL_OPEN_SENT;
608 if (NULL != ch->last_control_qe)
609 GCT_send_cancel (ch->last_control_qe);
610 ch->last_control_qe = GCT_send (ch->t,
611 &msgcc.header,
612 &channel_open_sent_cb,
613 ch);
614 GNUNET_assert (NULL == ch->retry_control_task);
504} 615}
505 616
506 617
507/** 618/**
508 * Notify a client that the channel is no longer valid. 619 * Function called once and only once after a channel was bound
509 * 620 * to its tunnel via #GCT_add_channel() is ready for transmission.
510 * @param ch Channel that is destroyed. 621 * Note that this is only the case for channels that this peer
511 * @param local_only Should we avoid sending it to other peers? 622 * initiates, as for incoming channels we assume that they are
623 * ready for transmission immediately upon receiving the open
624 * message. Used to bootstrap the #GCT_send() process.
625 *
626 * @param ch the channel for which the tunnel is now ready
512 */ 627 */
513static void 628void
514send_destroy (struct CadetChannel *ch, int local_only) 629GCCH_tunnel_up (struct CadetChannel *ch)
515{ 630{
516 struct GNUNET_CADET_ChannelManageMessage msg; 631 GNUNET_assert (NULL == ch->retry_control_task);
517 632 LOG (GNUNET_ERROR_TYPE_DEBUG,
518 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY); 633 "Tunnel up, sending CHANNEL_OPEN on %s now\n",
519 msg.header.size = htons (sizeof (msg)); 634 GCCH_2s (ch));
520 msg.ctn = ch->gid; 635 ch->retry_control_task
521 636 = GNUNET_SCHEDULER_add_now (&send_channel_open,
522 /* If root is not NULL, notify. 637 ch);
523 * If it's NULL, check lid_root. When a local destroy comes in, root
524 * is set to NULL but lid_root is left untouched. In this case, do nothing,
525 * the client is the one who requested the channel to be destroyed.
526 */
527 if (NULL != ch->root)
528 GML_send_channel_destroy (ch->root, ch->lid_root);
529 else if (0 == ch->lid_root.channel_of_client && GNUNET_NO == local_only)
530 GCCH_send_prebuilt_message (&msg.header, ch, GNUNET_NO, NULL);
531
532 if (NULL != ch->dest)
533 GML_send_channel_destroy (ch->dest, ch->lid_dest);
534 else if (0 == ch->lid_dest.channel_of_client && GNUNET_NO == local_only)
535 GCCH_send_prebuilt_message (&msg.header, ch, GNUNET_YES, NULL);
536} 638}
537 639
538 640
539/** 641/**
540 * Notify the destination client that a new incoming channel was created. 642 * Create a new channel.
541 * 643 *
542 * @param ch Channel that was created. 644 * @param owner local client owning the channel
645 * @param ccn local number of this channel at the @a owner
646 * @param destination peer to which we should build the channel
647 * @param port desired port at @a destination
648 * @param options options for the channel
649 * @return handle to the new channel
543 */ 650 */
544static void 651struct CadetChannel *
545send_client_create (struct CadetChannel *ch) 652GCCH_channel_local_new (struct CadetClient *owner,
653 struct GNUNET_CADET_ClientChannelNumber ccn,
654 struct CadetPeer *destination,
655 const struct GNUNET_HashCode *port,
656 uint32_t options)
546{ 657{
547 uint32_t opt; 658 struct CadetChannel *ch;
548 659 struct CadetChannelClient *ccco;
549 if (NULL == ch->dest)
550 return;
551
552 opt = 0;
553 opt |= GNUNET_YES == ch->reliable ? GNUNET_CADET_OPTION_RELIABLE : 0;
554 opt |= GNUNET_YES == ch->nobuffer ? GNUNET_CADET_OPTION_NOBUFFER : 0;
555 GML_send_channel_create (ch->dest,
556 ch->lid_dest,
557 &ch->port,
558 opt,
559 GCT_get_destination (ch->t));
560
561}
562 660
661 ccco = GNUNET_new (struct CadetChannelClient);
662 ccco->c = owner;
663 ccco->ccn = ccn;
664 ccco->client_ready = GNUNET_YES;
563 665
564/** 666 ch = GNUNET_new (struct CadetChannel);
565 * Send data to a client. 667 ch->mid_recv.mid = htonl (1); /* The OPEN_ACK counts as message 0! */
566 * 668 ch->nobuffer = (0 != (options & GNUNET_CADET_OPTION_NOBUFFER));
567 * If the client is ready, send directly, otherwise buffer while listening 669 ch->reliable = (0 != (options & GNUNET_CADET_OPTION_RELIABLE));
568 * for a local ACK. 670 ch->out_of_order = (0 != (options & GNUNET_CADET_OPTION_OUT_OF_ORDER));
569 * 671 ch->max_pending_messages = (ch->nobuffer) ? 1 : 4; /* FIXME: 4!? Do not hardcode! */
570 * @param ch Channel 672 ch->owner = ccco;
571 * @param msg Message. 673 ch->port = *port;
572 * @param fwd Is this a fwd (root->dest) message? 674 GCCH_hash_port (&ch->h_port,
573 */ 675 port,
574static void 676 GCP_get_id (destination));
575send_client_data (struct CadetChannel *ch, 677 if (0 == memcmp (&my_full_id,
576 const struct GNUNET_CADET_ChannelAppDataMessage *msg, 678 GCP_get_id (destination),
577 int fwd) 679 sizeof (struct GNUNET_PeerIdentity)))
578{ 680 {
579 if (fwd) 681 struct OpenPort *op;
580 { 682
581 if (ch->dest_rel->client_ready) 683 ch->is_loopback = GNUNET_YES;
684 op = GNUNET_CONTAINER_multihashmap_get (open_ports,
685 &ch->h_port);
686 if (NULL == op)
582 { 687 {
583 GML_send_data (ch->dest, msg, ch->lid_dest); 688 /* port closed, wait for it to possibly open */
584 ch->dest_rel->client_ready = GNUNET_NO; 689 ch->state = CADET_CHANNEL_LOOSE;
585 ch->dest_rel->mid_recv++; 690 (void) GNUNET_CONTAINER_multihashmap_put (loose_channels,
691 &ch->h_port,
692 ch,
693 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
694 LOG (GNUNET_ERROR_TYPE_DEBUG,
695 "Created loose incoming loopback channel to port %s\n",
696 GNUNET_h2s (&ch->port));
586 } 697 }
587 else 698 else
588 add_buffered_data (msg, ch->dest_rel); 699 {
700 GCCH_bind (ch,
701 op->c,
702 &op->port);
703 }
589 } 704 }
590 else 705 else
591 { 706 {
592 if (ch->root_rel->client_ready) 707 ch->t = GCP_get_tunnel (destination,
593 { 708 GNUNET_YES);
594 GML_send_data (ch->root, msg, ch->lid_root); 709 ch->retry_time = CADET_INITIAL_RETRANSMIT_TIME;
595 ch->root_rel->client_ready = GNUNET_NO; 710 ch->ctn = GCT_add_channel (ch->t,
596 ch->root_rel->mid_recv++; 711 ch);
597 }
598 else
599 add_buffered_data (msg, ch->root_rel);
600 } 712 }
713 GNUNET_STATISTICS_update (stats,
714 "# channels",
715 1,
716 GNUNET_NO);
717 LOG (GNUNET_ERROR_TYPE_DEBUG,
718 "Created channel to port %s at peer %s for %s using %s\n",
719 GNUNET_h2s (port),
720 GCP_2s (destination),
721 GSC_2s (owner),
722 (GNUNET_YES == ch->is_loopback) ? "loopback" : GCT_2s (ch->t));
723 return ch;
601} 724}
602 725
603 726
604/** 727/**
605 * Send a buffered message to the client, for in order delivery or 728 * We had an incoming channel to a port that is closed.
606 * as result of client ACK. 729 * It has not been opened for a while, drop it.
607 * 730 *
608 * @param ch Channel on which to empty the message buffer. 731 * @param cls the channel to drop
609 * @param c Client to send to.
610 * @param fwd Is this to send FWD data?.
611 */ 732 */
612static void 733static void
613send_client_buffered_data (struct CadetChannel *ch, 734timeout_closed_cb (void *cls)
614 struct CadetClient *c,
615 int fwd)
616{ 735{
617 struct CadetReliableMessage *copy; 736 struct CadetChannel *ch = cls;
618 struct CadetChannelReliability *rel;
619
620 LOG (GNUNET_ERROR_TYPE_DEBUG, "send_buffered_data\n");
621 rel = fwd ? ch->dest_rel : ch->root_rel;
622 if (GNUNET_NO == rel->client_ready)
623 {
624 LOG (GNUNET_ERROR_TYPE_DEBUG, "client not ready\n");
625 return;
626 }
627 737
628 copy = rel->head_recv; 738 ch->retry_control_task = NULL;
629 /* We never buffer channel management messages */ 739 LOG (GNUNET_ERROR_TYPE_DEBUG,
630 if (NULL != copy) 740 "Closing incoming channel to port %s from peer %s due to timeout\n",
631 { 741 GNUNET_h2s (&ch->port),
632 if (copy->mid == rel->mid_recv || GNUNET_NO == ch->reliable) 742 GCP_2s (GCT_get_destination (ch->t)));
633 { 743 channel_destroy (ch);
634 struct GNUNET_CADET_ChannelAppDataMessage *msg = (struct GNUNET_CADET_ChannelAppDataMessage *) &copy[1];
635
636 LOG (GNUNET_ERROR_TYPE_DEBUG, " have %u! now expecting %u\n",
637 copy->mid, rel->mid_recv + 1);
638 send_client_data (ch, msg, fwd);
639 rel->n_recv--;
640 GNUNET_CONTAINER_DLL_remove (rel->head_recv, rel->tail_recv, copy);
641 LOG (GNUNET_ERROR_TYPE_DEBUG, " free copy recv MID %u (%p), %u left\n",
642 copy->mid, copy, rel->n_recv);
643 GNUNET_free (copy);
644 GCCH_send_data_ack (ch, fwd);
645 }
646 else
647 {
648 LOG (GNUNET_ERROR_TYPE_DEBUG, " reliable && don't have %u, next is %u\n",
649 rel->mid_recv, copy->mid);
650 if (GNUNET_YES == ch->destroy)
651 {
652 /* We don't have the next data piece and the remote peer has closed the
653 * channel. We won't receive it anymore, so just destroy the channel.
654 * FIXME: wait some time to allow other connections to
655 * deliver missing messages
656 */
657 send_destroy (ch, GNUNET_YES);
658 GCCH_destroy (ch);
659 }
660 }
661 }
662 LOG (GNUNET_ERROR_TYPE_DEBUG, "send_buffered_data END\n");
663} 744}
664 745
665 746
666/** 747/**
667 * Allow a client to send more data. 748 * Create a new channel based on a request coming in over the network.
668 *
669 * In case the client was already allowed to send data, do nothing.
670 * 749 *
671 * @param ch Channel. 750 * @param t tunnel to the remote peer
672 * @param fwd Is this a FWD ACK? (FWD ACKs are sent to root) 751 * @param ctn identifier of this channel in the tunnel
752 * @param h_port desired hash of local port
753 * @param options options for the channel
754 * @return handle to the new channel
673 */ 755 */
674static void 756struct CadetChannel *
675send_client_ack (struct CadetChannel *ch, int fwd) 757GCCH_channel_incoming_new (struct CadetTunnel *t,
758 struct GNUNET_CADET_ChannelTunnelNumber ctn,
759 const struct GNUNET_HashCode *h_port,
760 uint32_t options)
676{ 761{
677 struct CadetChannelReliability *rel = fwd ? ch->root_rel : ch->dest_rel; 762 struct CadetChannel *ch;
678 struct CadetClient *c = fwd ? ch->root : ch->dest; 763 struct OpenPort *op;
679
680 if (NULL == c)
681 {
682 GNUNET_break (GNUNET_NO != ch->destroy);
683 return;
684 }
685 LOG (GNUNET_ERROR_TYPE_DEBUG,
686 " sending %s ack to client on channel %s\n",
687 GC_f2s (fwd), GCCH_2s (ch));
688 764
689 if (NULL == rel) 765 ch = GNUNET_new (struct CadetChannel);
690 { 766 ch->h_port = *h_port;
691 GNUNET_break (0); 767 ch->t = t;
692 return; 768 ch->ctn = ctn;
769 ch->retry_time = CADET_INITIAL_RETRANSMIT_TIME;
770 ch->nobuffer = (0 != (options & GNUNET_CADET_OPTION_NOBUFFER));
771 ch->reliable = (0 != (options & GNUNET_CADET_OPTION_RELIABLE));
772 ch->out_of_order = (0 != (options & GNUNET_CADET_OPTION_OUT_OF_ORDER));
773 ch->max_pending_messages = (ch->nobuffer) ? 1 : 4; /* FIXME: 4!? Do not hardcode! */
774 GNUNET_STATISTICS_update (stats,
775 "# channels",
776 1,
777 GNUNET_NO);
778
779 op = GNUNET_CONTAINER_multihashmap_get (open_ports,
780 h_port);
781 if (NULL == op)
782 {
783 /* port closed, wait for it to possibly open */
784 ch->state = CADET_CHANNEL_LOOSE;
785 (void) GNUNET_CONTAINER_multihashmap_put (loose_channels,
786 &ch->h_port,
787 ch,
788 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
789 GNUNET_assert (NULL == ch->retry_control_task);
790 ch->retry_control_task
791 = GNUNET_SCHEDULER_add_delayed (TIMEOUT_CLOSED_PORT,
792 &timeout_closed_cb,
793 ch);
794 LOG (GNUNET_ERROR_TYPE_DEBUG,
795 "Created loose incoming channel to port %s from peer %s\n",
796 GNUNET_h2s (&ch->port),
797 GCP_2s (GCT_get_destination (ch->t)));
693 } 798 }
694 799 else
695 if (GNUNET_YES == rel->client_allowed)
696 { 800 {
697 LOG (GNUNET_ERROR_TYPE_DEBUG, " already allowed\n"); 801 GCCH_bind (ch,
698 return; 802 op->c,
803 &op->port);
699 } 804 }
700 rel->client_allowed = GNUNET_YES; 805 GNUNET_STATISTICS_update (stats,
701 806 "# channels",
702 GML_send_ack (c, fwd ? ch->lid_root : ch->lid_dest); 807 1,
808 GNUNET_NO);
809 return ch;
703} 810}
704 811
705 812
706/** 813/**
707 * Notify the root that the destination rejected the channel. 814 * Function called once the tunnel confirms that we sent the
815 * ACK message. Just remembers it was sent, we do not expect
816 * ACKs for ACKs ;-).
708 * 817 *
709 * @param ch Rejected channel. 818 * @param cls our `struct CadetChannel`.
819 * @param cid identifier of the connection within the tunnel, NULL
820 * if transmission failed
710 */ 821 */
711static void 822static void
712send_client_nack (struct CadetChannel *ch) 823send_ack_cb (void *cls,
824 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
713{ 825{
714 if (NULL == ch->root) 826 struct CadetChannel *ch = cls;
715 { 827
716 GNUNET_break (0); 828 GNUNET_assert (NULL != ch->last_control_qe);
717 return; 829 ch->last_control_qe = NULL;
718 }
719 GML_send_channel_nack (ch->root, ch->lid_root);
720} 830}
721 831
722 832
723/** 833/**
724 * We haven't received an ACK after a certain time: restransmit the message. 834 * Compute and send the current #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK to the other peer.
725 * 835 *
726 * @param cls Closure (CadetChannelReliability with the message to restransmit) 836 * @param ch channel to send the #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK for
727 */ 837 */
728static void 838static void
729channel_retransmit_message (void *cls) 839send_channel_data_ack (struct CadetChannel *ch)
730{ 840{
731 struct CadetChannelReliability *rel = cls; 841 struct GNUNET_CADET_ChannelDataAckMessage msg;
732 struct CadetReliableMessage *copy;
733 struct CadetChannel *ch;
734 struct GNUNET_CADET_ChannelAppDataMessage *payload;
735 int fwd;
736
737 rel->retry_task = NULL;
738 ch = rel->ch;
739 copy = rel->head_sent;
740 if (NULL == copy)
741 {
742 GNUNET_break (0); // FIXME tripped in rps testcase
743 return;
744 }
745
746 payload = (struct GNUNET_CADET_ChannelAppDataMessage *) &copy[1];
747 fwd = (rel == ch->root_rel);
748
749 /* Message not found in the queue that we are going to use. */
750 LOG (GNUNET_ERROR_TYPE_DEBUG, "RETRANSMIT MID %u\n", copy->mid);
751 842
752 GCCH_send_prebuilt_message (&payload->header, ch, fwd, copy); 843 if (GNUNET_NO == ch->reliable)
753 GNUNET_STATISTICS_update (stats, "# data retransmitted", 1, GNUNET_NO); 844 return; /* no ACKs */
845 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK);
846 msg.header.size = htons (sizeof (msg));
847 msg.ctn = ch->ctn;
848 msg.mid.mid = htonl (ntohl (ch->mid_recv.mid));
849 msg.futures = GNUNET_htonll (ch->mid_futures);
850 LOG (GNUNET_ERROR_TYPE_DEBUG,
851 "Sending DATA_ACK %u:%llX via %s\n",
852 (unsigned int) ntohl (msg.mid.mid),
853 (unsigned long long) ch->mid_futures,
854 GCCH_2s (ch));
855 if (NULL != ch->last_control_qe)
856 GCT_send_cancel (ch->last_control_qe);
857 ch->last_control_qe = GCT_send (ch->t,
858 &msg.header,
859 &send_ack_cb,
860 ch);
754} 861}
755 862
756 863
757/** 864/**
758 * We haven't received an Channel ACK after a certain time: resend the CREATE. 865 * Send our initial #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK to the client confirming that the
866 * connection is up.
759 * 867 *
760 * @param cls Closure (CadetChannelReliability of the channel to recreate) 868 * @param cls the `struct CadetChannel`
761 */ 869 */
762static void 870static void
763channel_recreate (void *cls) 871send_open_ack (void *cls)
764{ 872{
765 struct CadetChannelReliability *rel = cls; 873 struct CadetChannel *ch = cls;
874 struct GNUNET_CADET_ChannelOpenAckMessage msg;
766 875
767 rel->retry_task = NULL; 876 ch->retry_control_task = NULL;
768 LOG (GNUNET_ERROR_TYPE_DEBUG, "RE-CREATE\n"); 877 LOG (GNUNET_ERROR_TYPE_DEBUG,
769 GNUNET_STATISTICS_update (stats, 878 "Sending CHANNEL_OPEN_ACK on %s\n",
770 "# data retransmitted", 1, GNUNET_NO); 879 GCCH_2s (ch));
771 880 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK);
772 if (rel == rel->ch->root_rel) 881 msg.header.size = htons (sizeof (msg));
773 { 882 msg.reserved = htonl (0);
774 send_create (rel->ch); 883 msg.ctn = ch->ctn;
775 } 884 msg.port = ch->port;
776 else if (rel == rel->ch->dest_rel) 885 if (NULL != ch->last_control_qe)
777 { 886 GCT_send_cancel (ch->last_control_qe);
778 send_ack (rel->ch, GNUNET_YES); 887 ch->last_control_qe = GCT_send (ch->t,
779 } 888 &msg.header,
780 else 889 &send_ack_cb,
781 { 890 ch);
782 GNUNET_break (0);
783 }
784} 891}
785 892
786 893
787/** 894/**
788 * Message has been sent: start retransmission timer. 895 * We got a #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN message again for
896 * this channel. If the binding was successful, (re)transmit the
897 * #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK.
789 * 898 *
790 * @param cls Closure (queue structure). 899 * @param ch channel that got the duplicate open
791 * @param t Tunnel. 900 * @param cti identifier of the connection that delivered the message
792 * @param q Queue handler (no longer valid).
793 * @param type Type of message.
794 * @param size Size of the message.
795 */ 901 */
796static void 902void
797ch_message_sent (void *cls, 903GCCH_handle_duplicate_open (struct CadetChannel *ch,
798 struct CadetTunnel *t, 904 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti)
799 struct CadetTunnelQueue *q,
800 uint16_t type, size_t size)
801{ 905{
802 struct CadetChannelQueue *chq = cls; 906 if (NULL == ch->dest)
803 struct CadetReliableMessage *copy = chq->copy;
804 struct CadetChannelReliability *rel;
805
806 LOG (GNUNET_ERROR_TYPE_DEBUG, "channel_message_sent callback %s\n",
807 GC_m2s (chq->type));
808
809 switch (chq->type)
810 { 907 {
811 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA: 908 LOG (GNUNET_ERROR_TYPE_DEBUG,
812 LOG (GNUNET_ERROR_TYPE_DEBUG, "data MID %u sent\n", copy->mid); 909 "Ignoring duplicate CHANNEL_OPEN on %s: port is closed\n",
813 GNUNET_assert (chq == copy->chq); 910 GCCH_2s (ch));
814 copy->timestamp = GNUNET_TIME_absolute_get (); 911 return;
815 rel = copy->rel;
816 if (NULL == rel->retry_task)
817 {
818 LOG (GNUNET_ERROR_TYPE_DEBUG, " scheduling retry in %d * %s\n",
819 CADET_RETRANSMIT_MARGIN,
820 GNUNET_STRINGS_relative_time_to_string (rel->expected_delay,
821 GNUNET_YES));
822 if (0 != rel->expected_delay.rel_value_us)
823 {
824 rel->retry_timer =
825 GNUNET_TIME_relative_saturating_multiply (rel->expected_delay,
826 CADET_RETRANSMIT_MARGIN);
827 }
828 else
829 {
830 rel->retry_timer = CADET_RETRANSMIT_TIME;
831 }
832 LOG (GNUNET_ERROR_TYPE_DEBUG, " using delay %s\n",
833 GNUNET_STRINGS_relative_time_to_string (rel->retry_timer,
834 GNUNET_NO));
835 rel->retry_task =
836 GNUNET_SCHEDULER_add_delayed (rel->retry_timer,
837 &channel_retransmit_message, rel);
838 }
839 else
840 {
841 LOG (GNUNET_ERROR_TYPE_DEBUG, "retry running %p\n", rel->retry_task);
842 }
843 copy->chq = NULL;
844 break;
845
846
847 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK:
848 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN:
849 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK:
850 LOG (GNUNET_ERROR_TYPE_DEBUG, "sent %s\n", GC_m2s (chq->type));
851 rel = chq->rel;
852 GNUNET_assert (rel->uniq == chq);
853 rel->uniq = NULL;
854
855 if (CADET_CHANNEL_READY != rel->ch->state
856 && GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK != type
857 && GNUNET_NO == rel->ch->destroy)
858 {
859 GNUNET_assert (NULL == rel->retry_task);
860 LOG (GNUNET_ERROR_TYPE_DEBUG, "STD BACKOFF %s\n",
861 GNUNET_STRINGS_relative_time_to_string (rel->retry_timer,
862 GNUNET_NO));
863 rel->retry_timer = GNUNET_TIME_STD_BACKOFF (rel->retry_timer);
864 rel->retry_task = GNUNET_SCHEDULER_add_delayed (rel->retry_timer,
865 &channel_recreate, rel);
866 }
867 break;
868
869 default:
870 GNUNET_break (0);
871 } 912 }
872 913 if (NULL != ch->retry_control_task)
873 GNUNET_free (chq); 914 {
915 LOG (GNUNET_ERROR_TYPE_DEBUG,
916 "Ignoring duplicate CHANNEL_OPEN on %s: control message is pending\n",
917 GCCH_2s (ch));
918 return;
919 }
920 LOG (GNUNET_ERROR_TYPE_DEBUG,
921 "Retransmitting CHANNEL_OPEN_ACK on %s\n",
922 GCCH_2s (ch));
923 ch->retry_control_task
924 = GNUNET_SCHEDULER_add_now (&send_open_ack,
925 ch);
874} 926}
875 927
876 928
877/** 929/**
878 * send a channel create message. 930 * Send a #GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK to the client to solicit more messages.
879 * 931 *
880 * @param ch Channel for which to send. 932 * @param ch channel the ack is for
933 * @param to_owner #GNUNET_YES to send to owner,
934 * #GNUNET_NO to send to dest
881 */ 935 */
882static void 936static void
883send_create (struct CadetChannel *ch) 937send_ack_to_client (struct CadetChannel *ch,
938 int to_owner)
884{ 939{
885 struct GNUNET_CADET_ChannelOpenMessage msgcc; 940 struct GNUNET_MQ_Envelope *env;
941 struct GNUNET_CADET_LocalAck *ack;
942 struct CadetChannelClient *ccc;
886 943
887 msgcc.header.size = htons (sizeof (msgcc)); 944 ccc = (GNUNET_YES == to_owner) ? ch->owner : ch->dest;
888 msgcc.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN); 945 if (NULL == ccc)
889 msgcc.ctn = ch->gid; 946 {
890 msgcc.port = ch->port; 947 /* This can happen if we are just getting ACKs after
891 msgcc.opt = htonl (channel_get_options (ch)); 948 our local client already disconnected. */
892 949 GNUNET_assert (GNUNET_YES == ch->destroy);
893 GCCH_send_prebuilt_message (&msgcc.header, ch, GNUNET_YES, NULL); 950 return;
951 }
952 env = GNUNET_MQ_msg (ack,
953 GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK);
954 ack->ccn = ccc->ccn;
955 LOG (GNUNET_ERROR_TYPE_DEBUG,
956 "Sending CADET_LOCAL_ACK to %s (%s) at ccn %X (%u/%u pending)\n",
957 GSC_2s (ccc->c),
958 (GNUNET_YES == to_owner) ? "owner" : "dest",
959 ntohl (ack->ccn.channel_of_client),
960 ch->pending_messages,
961 ch->max_pending_messages);
962 GSC_send_to_client (ccc->c,
963 env);
894} 964}
895 965
896 966
897/** 967/**
898 * Confirm we got a channel create or FWD ack. 968 * A client is bound to the port that we have a channel
969 * open to. Send the acknowledgement for the connection
970 * request and establish the link with the client.
899 * 971 *
900 * @param ch The channel to confirm. 972 * @param ch open incoming channel
901 * @param fwd Should we send a FWD ACK? (going dest->root) 973 * @param c client listening on the respective @a port
974 * @param port the port @a is listening on
902 */ 975 */
903static void 976void
904send_ack (struct CadetChannel *ch, int fwd) 977GCCH_bind (struct CadetChannel *ch,
978 struct CadetClient *c,
979 const struct GNUNET_HashCode *port)
905{ 980{
906 struct GNUNET_CADET_ChannelManageMessage msg; 981 uint32_t options;
982 struct CadetChannelClient *cccd;
907 983
908 msg.header.size = htons (sizeof (msg));
909 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK);
910 LOG (GNUNET_ERROR_TYPE_DEBUG, 984 LOG (GNUNET_ERROR_TYPE_DEBUG,
911 " sending channel %s ack for channel %s\n", 985 "Binding %s from %s to port %s of %s\n",
912 GC_f2s (fwd), GCCH_2s (ch)); 986 GCCH_2s (ch),
913 987 GCT_2s (ch->t),
914 msg.ctn =ch->gid; 988 GNUNET_h2s (&ch->port),
915 GCCH_send_prebuilt_message (&msg.header, ch, !fwd, NULL); 989 GSC_2s (c));
990 if (NULL != ch->retry_control_task)
991 {
992 /* there might be a timeout task here */
993 GNUNET_SCHEDULER_cancel (ch->retry_control_task);
994 ch->retry_control_task = NULL;
995 }
996 options = 0;
997 if (ch->nobuffer)
998 options |= GNUNET_CADET_OPTION_NOBUFFER;
999 if (ch->reliable)
1000 options |= GNUNET_CADET_OPTION_RELIABLE;
1001 if (ch->out_of_order)
1002 options |= GNUNET_CADET_OPTION_OUT_OF_ORDER;
1003 cccd = GNUNET_new (struct CadetChannelClient);
1004 GNUNET_assert (NULL == ch->dest);
1005 ch->dest = cccd;
1006 ch->port = *port;
1007 cccd->c = c;
1008 cccd->client_ready = GNUNET_YES;
1009 cccd->ccn = GSC_bind (c,
1010 ch,
1011 (GNUNET_YES == ch->is_loopback)
1012 ? GCP_get (&my_full_id,
1013 GNUNET_YES)
1014 : GCT_get_destination (ch->t),
1015 port,
1016 options);
1017 GNUNET_assert (ntohl (cccd->ccn.channel_of_client) <
1018 GNUNET_CADET_LOCAL_CHANNEL_ID_CLI);
1019 ch->mid_recv.mid = htonl (1); /* The OPEN counts as message 0! */
1020 if (GNUNET_YES == ch->is_loopback)
1021 {
1022 ch->state = CADET_CHANNEL_OPEN_SENT;
1023 GCCH_handle_channel_open_ack (ch,
1024 NULL,
1025 port);
1026 }
1027 else
1028 {
1029 /* notify other peer that we accepted the connection */
1030 ch->state = CADET_CHANNEL_READY;
1031 ch->retry_control_task
1032 = GNUNET_SCHEDULER_add_now (&send_open_ack,
1033 ch);
1034 }
1035 /* give client it's initial supply of ACKs */
1036 GNUNET_assert (ntohl (cccd->ccn.channel_of_client) <
1037 GNUNET_CADET_LOCAL_CHANNEL_ID_CLI);
1038 for (unsigned int i=0;i<ch->max_pending_messages;i++)
1039 send_ack_to_client (ch,
1040 GNUNET_NO);
916} 1041}
917 1042
918 1043
919/** 1044/**
920 * Send a message and don't keep any info about it: we won't need to cancel it 1045 * One of our clients has disconnected, tell the other one that we
921 * or resend it. 1046 * are finished. Done asynchronously to avoid concurrent modification
1047 * issues if this is the same client.
922 * 1048 *
923 * @param msg Header of the message to fire away. 1049 * @param cls the `struct CadetChannel` where one of the ends is now dead
924 * @param ch Channel on which the message should go.
925 * @param force Is this a forced (undroppable) message?
926 */ 1050 */
927static void 1051static void
928fire_and_forget (const struct GNUNET_MessageHeader *msg, 1052signal_remote_destroy_cb (void *cls)
929 struct CadetChannel *ch,
930 int force)
931{ 1053{
932 GNUNET_break (NULL == 1054 struct CadetChannel *ch = cls;
933 GCT_send_prebuilt_message (msg, ch->t, NULL, 1055 struct CadetChannelClient *ccc;
934 force, NULL, NULL)); 1056
1057 /* Find which end is left... */
1058 ch->retry_control_task = NULL;
1059 ccc = (NULL != ch->owner) ? ch->owner : ch->dest;
1060 GSC_handle_remote_channel_destroy (ccc->c,
1061 ccc->ccn,
1062 ch);
1063 channel_destroy (ch);
935} 1064}
936 1065
937 1066
938/** 1067/**
939 * Notify that a channel create didn't succeed. 1068 * Destroy locally created channel. Called by the local client, so no
1069 * need to tell the client.
940 * 1070 *
941 * @param ch The channel to reject. 1071 * @param ch channel to destroy
1072 * @param c client that caused the destruction
1073 * @param ccn client number of the client @a c
942 */ 1074 */
943static void 1075void
944send_nack (struct CadetChannel *ch) 1076GCCH_channel_local_destroy (struct CadetChannel *ch,
1077 struct CadetClient *c,
1078 struct GNUNET_CADET_ClientChannelNumber ccn)
945{ 1079{
946 struct GNUNET_CADET_ChannelManageMessage msg;
947
948 msg.header.size = htons (sizeof (msg));
949 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_NACK_DEPRECATED);
950 LOG (GNUNET_ERROR_TYPE_DEBUG, 1080 LOG (GNUNET_ERROR_TYPE_DEBUG,
951 " sending channel NACK for channel %s\n", 1081 "%s asks for destruction of %s\n",
1082 GSC_2s (c),
952 GCCH_2s (ch)); 1083 GCCH_2s (ch));
1084 GNUNET_assert (NULL != c);
1085 if ( (NULL != ch->owner) &&
1086 (c == ch->owner->c) &&
1087 (ccn.channel_of_client == ch->owner->ccn.channel_of_client) )
1088 {
1089 free_channel_client (ch->owner);
1090 ch->owner = NULL;
1091 }
1092 else if ( (NULL != ch->dest) &&
1093 (c == ch->dest->c) &&
1094 (ccn.channel_of_client == ch->dest->ccn.channel_of_client) )
1095 {
1096 free_channel_client (ch->dest);
1097 ch->dest = NULL;
1098 }
1099 else
1100 {
1101 GNUNET_assert (0);
1102 }
953 1103
954 msg.ctn = ch->gid; 1104 if (GNUNET_YES == ch->destroy)
955 GCCH_send_prebuilt_message (&msg.header, ch, GNUNET_NO, NULL);
956}
957
958
959/**
960 * Destroy all reliable messages queued for a channel,
961 * during a channel destruction.
962 * Frees the reliability structure itself.
963 *
964 * @param rel Reliability data for a channel.
965 */
966static void
967channel_rel_free_all (struct CadetChannelReliability *rel)
968{
969 struct CadetReliableMessage *copy;
970 struct CadetReliableMessage *next;
971
972 if (NULL == rel)
973 return;
974
975 for (copy = rel->head_recv; NULL != copy; copy = next)
976 { 1105 {
977 next = copy->next; 1106 /* other end already destroyed, with the local client gone, no need
978 GNUNET_CONTAINER_DLL_remove (rel->head_recv, rel->tail_recv, copy); 1107 to finish transmissions, just destroy immediately. */
979 LOG (GNUNET_ERROR_TYPE_DEBUG, " COPYFREE ALL RECV %p\n", copy); 1108 channel_destroy (ch);
980 GNUNET_break (NULL == copy->chq); 1109 return;
981 GNUNET_free (copy);
982 } 1110 }
983 for (copy = rel->head_sent; NULL != copy; copy = next) 1111 if ( (NULL != ch->head_sent) &&
1112 ( (NULL != ch->owner) ||
1113 (NULL != ch->dest) ) )
984 { 1114 {
985 next = copy->next; 1115 /* Wait for other end to destroy us as well,
986 GNUNET_CONTAINER_DLL_remove (rel->head_sent, rel->tail_sent, copy); 1116 and otherwise allow send queue to be transmitted first */
987 LOG (GNUNET_ERROR_TYPE_DEBUG, " COPYFREE ALL SEND %p\n", copy); 1117 ch->destroy = GNUNET_YES;
988 if (NULL != copy->chq) 1118 return;
989 {
990 if (NULL != copy->chq->tq)
991 {
992 GCT_cancel (copy->chq->tq);
993 /* ch_message_sent will free copy->q */
994 }
995 else
996 {
997 GNUNET_free (copy->chq);
998 GNUNET_break (0);
999 }
1000 }
1001 GNUNET_free (copy);
1002 } 1119 }
1003 if (NULL != rel->uniq && NULL != rel->uniq->tq) 1120 if ( (GNUNET_YES == ch->is_loopback) &&
1121 ( (NULL != ch->owner) ||
1122 (NULL != ch->dest) ) )
1004 { 1123 {
1005 GCT_cancel (rel->uniq->tq); 1124 if (NULL != ch->retry_control_task)
1006 /* ch_message_sent is called freeing uniq */ 1125 GNUNET_SCHEDULER_cancel (ch->retry_control_task);
1126 ch->retry_control_task
1127 = GNUNET_SCHEDULER_add_now (&signal_remote_destroy_cb,
1128 ch);
1129 return;
1007 } 1130 }
1008 if (NULL != rel->retry_task) 1131 if (GNUNET_NO == ch->is_loopback)
1009 { 1132 {
1010 GNUNET_SCHEDULER_cancel (rel->retry_task); 1133 /* If the we ever sent the CHANNEL_CREATE, we need to send a destroy message. */
1011 rel->retry_task = NULL; 1134 switch (ch->state)
1135 {
1136 case CADET_CHANNEL_NEW:
1137 /* We gave up on a channel that we created as a client to a remote
1138 target, but that never went anywhere. Nothing to do here. */
1139 break;
1140 case CADET_CHANNEL_LOOSE:
1141 GSC_drop_loose_channel (&ch->h_port,
1142 ch);
1143 break;
1144 default:
1145 GCT_send_channel_destroy (ch->t,
1146 ch->ctn);
1147 }
1012 } 1148 }
1013 GNUNET_free (rel); 1149 /* Nothing left to do, just finish destruction */
1150 channel_destroy (ch);
1014} 1151}
1015 1152
1016 1153
1017/** 1154/**
1018 * Mark future messages as ACK'd. 1155 * We got an acknowledgement for the creation of the channel
1156 * (the port is open on the other side). Verify that the
1157 * other end really has the right port, and begin transmissions.
1019 * 1158 *
1020 * @param rel Reliability data. 1159 * @param ch channel to destroy
1021 * @param msg DataACK message with a bitfield of future ACK'd messages. 1160 * @param cti identifier of the connection that delivered the message
1022 * 1161 * @param port port number (needed to verify receiver knows the port)
1023 * @return How many messages have been freed.
1024 */ 1162 */
1025static unsigned int 1163void
1026channel_rel_free_sent (struct CadetChannelReliability *rel, 1164GCCH_handle_channel_open_ack (struct CadetChannel *ch,
1027 const struct GNUNET_CADET_ChannelDataAckMessage *msg) 1165 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti,
1166 const struct GNUNET_HashCode *port)
1028{ 1167{
1029 struct CadetReliableMessage *copy; 1168 switch (ch->state)
1030 struct CadetReliableMessage *next;
1031 uint64_t bitfield;
1032 uint64_t mask;
1033 uint32_t mid;
1034 uint32_t target;
1035 unsigned int i;
1036 unsigned int r;
1037
1038 bitfield = msg->futures;
1039 mid = ntohl (msg->mid);
1040 LOG (GNUNET_ERROR_TYPE_DEBUG, "free_sent_reliable %u %lX\n", mid, bitfield);
1041 LOG (GNUNET_ERROR_TYPE_DEBUG, " rel %p, head %p\n", rel, rel->head_sent);
1042 for (i = 0, r = 0, copy = rel->head_sent;
1043 i < 64 && NULL != copy && 0 != bitfield;
1044 i++)
1045 { 1169 {
1046 LOG (GNUNET_ERROR_TYPE_DEBUG, " trying bit %u (mid %u)\n", i, mid + i + 1); 1170 case CADET_CHANNEL_NEW:
1047 mask = 0x1LL << i; 1171 /* this should be impossible */
1048 if (0 == (bitfield & mask)) 1172 GNUNET_break (0);
1049 continue; 1173 break;
1050 1174 case CADET_CHANNEL_LOOSE:
1051 LOG (GNUNET_ERROR_TYPE_DEBUG, " set!\n"); 1175 /* This makes no sense. */
1052 /* Bit was set, clear the bit from the bitfield */ 1176 GNUNET_break_op (0);
1053 bitfield &= ~mask; 1177 break;
1054 1178 case CADET_CHANNEL_OPEN_SENT:
1055 /* The i-th bit was set. Do we have that copy? */ 1179 if (NULL == ch->owner)
1056 /* Skip copies with mid < target */ 1180 {
1057 target = mid + i + 1; 1181 /* We're not the owner, wrong direction! */
1058 LOG (GNUNET_ERROR_TYPE_DEBUG, " target %u\n", target); 1182 GNUNET_break_op (0);
1059 while (NULL != copy && GC_is_pid_bigger (target, copy->mid)) 1183 return;
1060 copy = copy->next; 1184 }
1061 1185 if (0 != memcmp (&ch->port,
1062 /* Did we run out of copies? (previously freed, it's ok) */ 1186 port,
1063 if (NULL == copy) 1187 sizeof (struct GNUNET_HashCode)))
1064 { 1188 {
1065 LOG (GNUNET_ERROR_TYPE_DEBUG, "run out of copies...\n"); 1189 /* Other peer failed to provide the right port,
1066 return r; 1190 refuse connection. */
1191 GNUNET_break_op (0);
1192 return;
1067 } 1193 }
1068 1194 LOG (GNUNET_ERROR_TYPE_DEBUG,
1069 /* Did we overshoot the target? (previously freed, it's ok) */ 1195 "Received CHANNEL_OPEN_ACK for waiting %s, entering READY state\n",
1070 if (GC_is_pid_bigger (copy->mid, target)) 1196 GCCH_2s (ch));
1197 if (NULL != ch->retry_control_task) /* can be NULL if ch->is_loopback */
1071 { 1198 {
1072 LOG (GNUNET_ERROR_TYPE_DEBUG, " next copy %u\n", copy->mid); 1199 GNUNET_SCHEDULER_cancel (ch->retry_control_task);
1073 i += copy->mid - target - 1; /* MID: 90, t = 85, i += 4 (i++ later) */ 1200 ch->retry_control_task = NULL;
1074 mask = (0x1LL << (i + 1)) - 1; /* Mask = i-th bit and all before */
1075 bitfield &= ~mask; /* Clear all bits up to MID - 1 */
1076 continue;
1077 } 1201 }
1078 1202 ch->state = CADET_CHANNEL_READY;
1079 /* Now copy->mid == target, free it */ 1203 /* On first connect, send client as many ACKs as we allow messages
1080 next = copy->next; 1204 to be buffered! */
1081 GNUNET_break (GNUNET_YES != rel_message_free (copy, GNUNET_YES)); 1205 for (unsigned int i=0;i<ch->max_pending_messages;i++)
1082 r++; 1206 send_ack_to_client (ch,
1083 copy = next; 1207 GNUNET_YES);
1208 break;
1209 case CADET_CHANNEL_READY:
1210 /* duplicate ACK, maybe we retried the CREATE. Ignore. */
1211 LOG (GNUNET_ERROR_TYPE_DEBUG,
1212 "Received duplicate channel OPEN_ACK for %s\n",
1213 GCCH_2s (ch));
1214 GNUNET_STATISTICS_update (stats,
1215 "# duplicate CREATE_ACKs",
1216 1,
1217 GNUNET_NO);
1218 break;
1084 } 1219 }
1085 LOG (GNUNET_ERROR_TYPE_DEBUG, "free_sent_reliable END\n");
1086 return r;
1087} 1220}
1088 1221
1089 1222
1090/** 1223/**
1091 * Destroy a reliable message after it has been acknowledged, either by 1224 * Test if element @a e1 comes before element @a e2.
1092 * direct mid ACK or bitfield. Updates the appropriate data structures and
1093 * timers and frees all memory.
1094 *
1095 * @param copy Message that is no longer needed: remote peer got it.
1096 * @param update_time Is the timing information relevant?
1097 * If this message is ACK in a batch the timing information
1098 * is skewed by the retransmission, count only for the
1099 * retransmitted message.
1100 * 1225 *
1101 * @return #GNUNET_YES if channel was destroyed as a result of the call, 1226 * @param cls closure, to a flag where we indicate duplicate packets
1102 * #GNUNET_NO otherwise. 1227 * @param m1 a message of to sort
1228 * @param m2 another message to sort
1229 * @return #GNUNET_YES if @e1 < @e2, otherwise #GNUNET_NO
1103 */ 1230 */
1104static int 1231static int
1105rel_message_free (struct CadetReliableMessage *copy, int update_time) 1232is_before (void *cls,
1233 struct CadetOutOfOrderMessage *m1,
1234 struct CadetOutOfOrderMessage *m2)
1106{ 1235{
1107 struct CadetChannelReliability *rel; 1236 int *duplicate = cls;
1108 struct GNUNET_TIME_Relative time; 1237 uint32_t v1 = ntohl (m1->mid.mid);
1238 uint32_t v2 = ntohl (m2->mid.mid);
1239 uint32_t delta;
1109 1240
1110 rel = copy->rel; 1241 delta = v2 - v1;
1111 LOG (GNUNET_ERROR_TYPE_DEBUG, "Freeing %u\n", copy->mid); 1242 if (0 == delta)
1112 if (GNUNET_YES == update_time) 1243 *duplicate = GNUNET_YES;
1244 if (delta > (uint32_t) INT_MAX)
1113 { 1245 {
1114 time = GNUNET_TIME_absolute_get_duration (copy->timestamp); 1246 /* in overflow range, we can safely assume we wrapped around */
1115 if (0 == rel->expected_delay.rel_value_us) 1247 return GNUNET_NO;
1116 rel->expected_delay = time;
1117 else
1118 {
1119 rel->expected_delay.rel_value_us *= 7;
1120 rel->expected_delay.rel_value_us += time.rel_value_us;
1121 rel->expected_delay.rel_value_us /= 8;
1122 }
1123 LOG (GNUNET_ERROR_TYPE_DEBUG, " message time %12s\n",
1124 GNUNET_STRINGS_relative_time_to_string (time, GNUNET_NO));
1125 LOG (GNUNET_ERROR_TYPE_DEBUG, " new delay %12s\n",
1126 GNUNET_STRINGS_relative_time_to_string (rel->expected_delay,
1127 GNUNET_NO));
1128 rel->retry_timer = rel->expected_delay;
1129 } 1248 }
1130 else 1249 else
1131 { 1250 {
1132 LOG (GNUNET_ERROR_TYPE_DEBUG, "batch free, ignoring timing\n"); 1251 /* result is small, thus v2 > v1, thus m1 < m2 */
1133 }
1134 rel->ch->pending_messages--;
1135 if (NULL != copy->chq)
1136 {
1137 GCT_cancel (copy->chq->tq);
1138 /* copy->q is set to NULL by ch_message_sent */
1139 }
1140 GNUNET_CONTAINER_DLL_remove (rel->head_sent, rel->tail_sent, copy);
1141 LOG (GNUNET_ERROR_TYPE_DEBUG, " free send copy MID %u at %p\n",
1142 copy->mid, copy);
1143 GNUNET_free (copy);
1144
1145 if (GNUNET_NO != rel->ch->destroy && 0 == rel->ch->pending_messages)
1146 {
1147 GCCH_destroy (rel->ch);
1148 return GNUNET_YES; 1252 return GNUNET_YES;
1149 } 1253 }
1150 return GNUNET_NO;
1151} 1254}
1152 1255
1153 1256
1154/** 1257/**
1155 * Channel was ACK'd by remote peer, mark as ready and cancel retransmission. 1258 * We got payload data for a channel. Pass it on to the client
1259 * and send an ACK to the other end (once flow control allows it!)
1156 * 1260 *
1157 * @param ch Channel to mark as ready. 1261 * @param ch channel that got data
1158 * @param fwd Was the ACK message a FWD ACK? (dest->root, SYNACK) 1262 * @param cti identifier of the connection that delivered the message
1263 * @param msg message that was received
1159 */ 1264 */
1160static void 1265void
1161channel_confirm (struct CadetChannel *ch, int fwd) 1266GCCH_handle_channel_plaintext_data (struct CadetChannel *ch,
1267 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti,
1268 const struct GNUNET_CADET_ChannelAppDataMessage *msg)
1162{ 1269{
1163 struct CadetChannelReliability *rel; 1270 struct GNUNET_MQ_Envelope *env;
1164 enum CadetChannelState oldstate; 1271 struct GNUNET_CADET_LocalData *ld;
1165 1272 struct CadetChannelClient *ccc;
1166 rel = fwd ? ch->root_rel : ch->dest_rel; 1273 size_t payload_size;
1167 if (NULL == rel) 1274 struct CadetOutOfOrderMessage *com;
1275 int duplicate;
1276 uint32_t mid_min;
1277 uint32_t mid_max;
1278 uint32_t mid_msg;
1279 uint32_t delta;
1280
1281 GNUNET_assert (GNUNET_NO == ch->is_loopback);
1282 if ( (GNUNET_YES == ch->destroy) &&
1283 (NULL == ch->owner) &&
1284 (NULL == ch->dest) )
1285 {
1286 /* This client is gone, but we still have messages to send to
1287 the other end (which is why @a ch is not yet dead). However,
1288 we cannot pass messages to our client anymore. */
1289 LOG (GNUNET_ERROR_TYPE_DEBUG,
1290 "Dropping incoming payload on %s as this end is already closed\n",
1291 GCCH_2s (ch));
1292 /* send back DESTROY notification to stop further retransmissions! */
1293 GCT_send_channel_destroy (ch->t,
1294 ch->ctn);
1295 return;
1296 }
1297 payload_size = ntohs (msg->header.size) - sizeof (*msg);
1298 env = GNUNET_MQ_msg_extra (ld,
1299 payload_size,
1300 GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA);
1301 ld->ccn = (NULL == ch->dest) ? ch->owner->ccn : ch->dest->ccn;
1302 GNUNET_memcpy (&ld[1],
1303 &msg[1],
1304 payload_size);
1305 ccc = (NULL != ch->owner) ? ch->owner : ch->dest;
1306 if ( (GNUNET_YES == ccc->client_ready) &&
1307 ( (GNUNET_YES == ch->out_of_order) ||
1308 (msg->mid.mid == ch->mid_recv.mid) ) )
1168 { 1309 {
1169 GNUNET_break (GNUNET_NO != ch->destroy); 1310 LOG (GNUNET_ERROR_TYPE_DEBUG,
1311 "Giving %u bytes of payload with MID %u from %s to client %s\n",
1312 (unsigned int) payload_size,
1313 ntohl (msg->mid.mid),
1314 GCCH_2s (ch),
1315 GSC_2s (ccc->c));
1316 ccc->client_ready = GNUNET_NO;
1317 GSC_send_to_client (ccc->c,
1318 env);
1319 ch->mid_recv.mid = htonl (1 + ntohl (ch->mid_recv.mid));
1320 ch->mid_futures >>= 1;
1321 send_channel_data_ack (ch);
1170 return; 1322 return;
1171 } 1323 }
1172 LOG (GNUNET_ERROR_TYPE_DEBUG, " channel confirm %s %s\n",
1173 GC_f2s (fwd), GCCH_2s (ch));
1174 oldstate = ch->state;
1175 ch->state = CADET_CHANNEL_READY;
1176 1324
1177 if (CADET_CHANNEL_READY != oldstate || GNUNET_YES == is_loopback (ch)) 1325 if (GNUNET_YES == ch->reliable)
1178 { 1326 {
1179 rel->client_ready = GNUNET_YES; 1327 /* check if message ought to be dropped because it is ancient/too distant/duplicate */
1180 rel->expected_delay = rel->retry_timer; 1328 mid_min = ntohl (ch->mid_recv.mid);
1181 LOG (GNUNET_ERROR_TYPE_DEBUG, " confirm retry timer %s\n", 1329 mid_max = mid_min + ch->max_pending_messages;
1182 GNUNET_STRINGS_relative_time_to_string (rel->retry_timer, GNUNET_NO)); 1330 mid_msg = ntohl (msg->mid.mid);
1183 if (GCT_get_connections_buffer (ch->t) > 0 || GCT_is_loopback (ch->t)) 1331 if ( ( (uint32_t) (mid_msg - mid_min) > ch->max_pending_messages) ||
1184 send_client_ack (ch, fwd); 1332 ( (uint32_t) (mid_max - mid_msg) > ch->max_pending_messages) )
1185
1186 if (NULL != rel->retry_task)
1187 { 1333 {
1188 GNUNET_SCHEDULER_cancel (rel->retry_task); 1334 LOG (GNUNET_ERROR_TYPE_DEBUG,
1189 rel->retry_task = NULL; 1335 "%s at %u drops ancient or far-future message %u\n",
1190 } 1336 GCCH_2s (ch),
1191 else if (NULL != rel->uniq) 1337 (unsigned int) mid_min,
1192 { 1338 ntohl (msg->mid.mid));
1193 GCT_cancel (rel->uniq->tq); 1339
1194 /* ch_message_sent will free and NULL uniq */ 1340 GNUNET_STATISTICS_update (stats,
1341 "# duplicate DATA (ancient or future)",
1342 1,
1343 GNUNET_NO);
1344 GNUNET_MQ_discard (env);
1345 send_channel_data_ack (ch);
1346 return;
1195 } 1347 }
1196 else if (GNUNET_NO == is_loopback (ch)) 1348 /* mark bit for future ACKs */
1349 delta = mid_msg - mid_min - 1; /* overflow/underflow are OK here */
1350 if (delta < 64)
1197 { 1351 {
1198 /* We SHOULD have been trying to retransmit this! */ 1352 if (0 != (ch->mid_futures & (1LLU << delta)))
1199 GNUNET_break (0); 1353 {
1354 /* Duplicate within the queue, drop also */
1355 LOG (GNUNET_ERROR_TYPE_DEBUG,
1356 "Duplicate payload of %u bytes on %s (mid %u) dropped\n",
1357 (unsigned int) payload_size,
1358 GCCH_2s (ch),
1359 ntohl (msg->mid.mid));
1360 GNUNET_STATISTICS_update (stats,
1361 "# duplicate DATA",
1362 1,
1363 GNUNET_NO);
1364 GNUNET_MQ_discard (env);
1365 send_channel_data_ack (ch);
1366 return;
1367 }
1368 ch->mid_futures |= (1LLU << delta);
1369 LOG (GNUNET_ERROR_TYPE_DEBUG,
1370 "Marked bit %llX for mid %u (base: %u); now: %llX\n",
1371 (1LLU << delta),
1372 mid_msg,
1373 mid_min,
1374 ch->mid_futures);
1200 } 1375 }
1201 } 1376 }
1202 1377 else /* ! ch->reliable */
1203 /* In case of a FWD ACK (SYNACK) send a BCK ACK (ACK). */
1204 if (GNUNET_YES == fwd)
1205 send_ack (ch, GNUNET_NO);
1206}
1207
1208
1209/**
1210 * Save a copy to retransmit in case it gets lost.
1211 *
1212 * Initializes all needed callbacks and timers.
1213 *
1214 * @param ch Channel this message goes on.
1215 * @param msg Message to copy.
1216 * @param fwd Is this fwd traffic?
1217 */
1218static struct CadetReliableMessage *
1219channel_save_copy (struct CadetChannel *ch,
1220 const struct GNUNET_MessageHeader *msg,
1221 int fwd)
1222{
1223 struct CadetChannelReliability *rel;
1224 struct CadetReliableMessage *copy;
1225 uint32_t mid;
1226 uint16_t type;
1227 uint16_t size;
1228
1229 rel = fwd ? ch->root_rel : ch->dest_rel;
1230 mid = rel->mid_send - 1;
1231 type = ntohs (msg->type);
1232 size = ntohs (msg->size);
1233
1234 LOG (GNUNET_ERROR_TYPE_DEBUG, "save MID %u %s\n", mid, GC_m2s (type));
1235 copy = GNUNET_malloc (sizeof (struct CadetReliableMessage) + size);
1236 LOG (GNUNET_ERROR_TYPE_DEBUG, " at %p\n", copy);
1237 copy->mid = mid;
1238 copy->rel = rel;
1239 copy->type = type;
1240 GNUNET_memcpy (&copy[1], msg, size);
1241 GNUNET_CONTAINER_DLL_insert_tail (rel->head_sent, rel->tail_sent, copy);
1242 ch->pending_messages++;
1243
1244 return copy;
1245}
1246
1247
1248/**
1249 * Create a new channel.
1250 *
1251 * @param t Tunnel this channel is in.
1252 * @param owner Client that owns the channel, NULL for foreign channels.
1253 * @param lid_root Local ID for root client.
1254 *
1255 * @return A new initialized channel. NULL on error.
1256 */
1257static struct CadetChannel *
1258channel_new (struct CadetTunnel *t,
1259 struct CadetClient *owner,
1260 struct GNUNET_CADET_ClientChannelNumber lid_root)
1261{
1262 struct CadetChannel *ch;
1263
1264 ch = GNUNET_new (struct CadetChannel);
1265 ch->root = owner;
1266 ch->lid_root = lid_root;
1267 ch->t = t;
1268
1269 GNUNET_STATISTICS_update (stats, "# channels", 1, GNUNET_NO);
1270
1271 if (NULL != owner)
1272 {
1273 ch->gid = GCT_get_next_ctn (t);
1274 GML_channel_add (owner, lid_root, ch);
1275 }
1276 GCT_add_channel (t, ch);
1277
1278 return ch;
1279}
1280
1281
1282/**
1283 * Handle a loopback message: call the appropriate handler for the message type.
1284 *
1285 * @param ch Channel this message is on.
1286 * @param msgh Message header.
1287 * @param fwd Is this FWD traffic?
1288 */
1289void
1290handle_loopback (struct CadetChannel *ch,
1291 const struct GNUNET_MessageHeader *msgh,
1292 int fwd)
1293{
1294 uint16_t type;
1295
1296 type = ntohs (msgh->type);
1297 LOG (GNUNET_ERROR_TYPE_DEBUG,
1298 "Loopback %s %s message!\n",
1299 GC_f2s (fwd), GC_m2s (type));
1300
1301 switch (type)
1302 { 1378 {
1303 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA: 1379 /* Channel is unreliable, so we do not ACK. But we also cannot
1304 /* Don't send hop ACK, wait for client to ACK */ 1380 allow buffering everything, so check if we have space... */
1305 LOG (GNUNET_ERROR_TYPE_DEBUG, "SEND loopback %u (%u)\n", 1381 if (ccc->num_recv >= ch->max_pending_messages)
1306 ntohl (((struct GNUNET_CADET_ChannelAppDataMessage *) msgh)->mid), ntohs (msgh->size)); 1382 {
1307 GCCH_handle_data (ch, (struct GNUNET_CADET_ChannelAppDataMessage *) msgh, fwd); 1383 struct CadetOutOfOrderMessage *drop;
1308 break;
1309
1310 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK:
1311 GCCH_handle_data_ack (ch,
1312 (const struct GNUNET_CADET_ChannelDataAckMessage *) msgh, fwd);
1313 break;
1314
1315 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN:
1316 GCCH_handle_create (ch->t,
1317 (const struct GNUNET_CADET_ChannelOpenMessage *) msgh);
1318 break;
1319
1320 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK:
1321 GCCH_handle_ack (ch,
1322 (const struct GNUNET_CADET_ChannelManageMessage *) msgh,
1323 fwd);
1324 break;
1325
1326 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_NACK_DEPRECATED:
1327 GCCH_handle_nack (ch);
1328 break;
1329
1330 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY:
1331 GCCH_handle_destroy (ch,
1332 (const struct GNUNET_CADET_ChannelManageMessage *) msgh,
1333 fwd);
1334 break;
1335 1384
1336 default: 1385 /* Yep, need to drop. Drop the oldest message in
1337 GNUNET_break_op (0); 1386 the buffer. */
1338 LOG (GNUNET_ERROR_TYPE_DEBUG, 1387 LOG (GNUNET_ERROR_TYPE_DEBUG,
1339 "end-to-end message not known (%u)\n", 1388 "Queue full due slow client on %s, dropping oldest message\n",
1340 ntohs (msgh->type)); 1389 GCCH_2s (ch));
1390 GNUNET_STATISTICS_update (stats,
1391 "# messages dropped due to slow client",
1392 1,
1393 GNUNET_NO);
1394 drop = ccc->head_recv;
1395 GNUNET_CONTAINER_DLL_remove (ccc->head_recv,
1396 ccc->tail_recv,
1397 drop);
1398 ccc->num_recv--;
1399 GNUNET_MQ_discard (drop->env);
1400 GNUNET_free (drop);
1401 }
1341 } 1402 }
1342}
1343
1344
1345
1346/******************************************************************************/
1347/******************************** API ***********************************/
1348/******************************************************************************/
1349
1350/**
1351 * Destroy a channel and free all resources.
1352 *
1353 * @param ch Channel to destroy.
1354 */
1355void
1356GCCH_destroy (struct CadetChannel *ch)
1357{
1358 struct CadetClient *c;
1359 struct CadetTunnel *t;
1360 1403
1361 if (NULL == ch) 1404 /* Insert message into sorted out-of-order queue */
1405 com = GNUNET_new (struct CadetOutOfOrderMessage);
1406 com->mid = msg->mid;
1407 com->env = env;
1408 duplicate = GNUNET_NO;
1409 GNUNET_CONTAINER_DLL_insert_sorted (struct CadetOutOfOrderMessage,
1410 is_before,
1411 &duplicate,
1412 ccc->head_recv,
1413 ccc->tail_recv,
1414 com);
1415 ccc->num_recv++;
1416 if (GNUNET_YES == duplicate)
1417 {
1418 /* Duplicate within the queue, drop also (this is not covered by
1419 the case above if "delta" >= 64, which could be the case if
1420 max_pending_messages is also >= 64 or if our client is unready
1421 and we are seeing retransmissions of the message our client is
1422 blocked on. */
1423 LOG (GNUNET_ERROR_TYPE_DEBUG,
1424 "Duplicate payload of %u bytes on %s (mid %u) dropped\n",
1425 (unsigned int) payload_size,
1426 GCCH_2s (ch),
1427 ntohl (msg->mid.mid));
1428 GNUNET_STATISTICS_update (stats,
1429 "# duplicate DATA",
1430 1,
1431 GNUNET_NO);
1432 GNUNET_CONTAINER_DLL_remove (ccc->head_recv,
1433 ccc->tail_recv,
1434 com);
1435 ccc->num_recv--;
1436 GNUNET_MQ_discard (com->env);
1437 GNUNET_free (com);
1438 send_channel_data_ack (ch);
1362 return; 1439 return;
1363 if (2 == ch->destroy)
1364 return; /* recursive call */
1365 ch->destroy = 2;
1366
1367 LOG (GNUNET_ERROR_TYPE_DEBUG, "destroying channel %s:%u\n",
1368 GCT_2s (ch->t), ch->gid);
1369 GCCH_debug (ch, GNUNET_ERROR_TYPE_DEBUG);
1370
1371 c = ch->root;
1372 if (NULL != c)
1373 {
1374 GML_channel_remove (c, ch->lid_root, ch);
1375 } 1440 }
1376 1441 LOG (GNUNET_ERROR_TYPE_DEBUG,
1377 c = ch->dest; 1442 "Queued %s payload of %u bytes on %s-%X(%p) (mid %u, need %u first)\n",
1378 if (NULL != c) 1443 (GNUNET_YES == ccc->client_ready)
1379 { 1444 ? "out-of-order"
1380 GML_channel_remove (c, ch->lid_dest, ch); 1445 : "client-not-ready",
1381 } 1446 (unsigned int) payload_size,
1382 1447 GCCH_2s (ch),
1383 channel_rel_free_all (ch->root_rel); 1448 ntohl (ccc->ccn.channel_of_client),
1384 channel_rel_free_all (ch->dest_rel); 1449 ccc,
1385 1450 ntohl (msg->mid.mid),
1386 t = ch->t; 1451 ntohl (ch->mid_recv.mid));
1387 GCT_remove_channel (t, ch); 1452 /* NOTE: this ACK we _could_ skip, as the packet is out-of-order and
1388 GNUNET_STATISTICS_update (stats, "# channels", -1, GNUNET_NO); 1453 the sender may already be transmitting the previous one. Needs
1389 1454 experimental evaluation to see if/when this ACK helps or
1390 GNUNET_free (ch); 1455 hurts. (We might even want another option.) */
1391 GCT_destroy_if_empty (t); 1456 send_channel_data_ack (ch);
1392}
1393
1394
1395/**
1396 * Get the channel's public ID.
1397 *
1398 * @param ch Channel.
1399 *
1400 * @return ID used to identify the channel with the remote peer.
1401 */
1402struct GNUNET_CADET_ChannelTunnelNumber
1403GCCH_get_id (const struct CadetChannel *ch)
1404{
1405 return ch->gid;
1406}
1407
1408
1409/**
1410 * Get the channel tunnel.
1411 *
1412 * @param ch Channel to get the tunnel from.
1413 *
1414 * @return tunnel of the channel.
1415 */
1416struct CadetTunnel *
1417GCCH_get_tunnel (const struct CadetChannel *ch)
1418{
1419 return ch->t;
1420}
1421
1422
1423/**
1424 * Get free buffer space towards the client on a specific channel.
1425 *
1426 * @param ch Channel.
1427 * @param fwd Is query about FWD traffic?
1428 *
1429 * @return Free buffer space [0 - 64]
1430 */
1431unsigned int
1432GCCH_get_buffer (struct CadetChannel *ch, int fwd)
1433{
1434 struct CadetChannelReliability *rel;
1435
1436 rel = fwd ? ch->dest_rel : ch->root_rel;
1437 LOG (GNUNET_ERROR_TYPE_DEBUG, " get buffer, channel %s\n", GCCH_2s (ch));
1438 GCCH_debug (ch, GNUNET_ERROR_TYPE_DEBUG);
1439 /* If rel is NULL it means that the end is not yet created,
1440 * most probably is a loopback channel at the point of sending
1441 * the ChannelCreate to itself.
1442 */
1443 if (NULL == rel)
1444 {
1445 LOG (GNUNET_ERROR_TYPE_DEBUG, " rel is NULL: max\n");
1446 return 64;
1447 }
1448
1449 LOG (GNUNET_ERROR_TYPE_DEBUG, " n_recv %d\n", rel->n_recv);
1450 return (64 - rel->n_recv);
1451}
1452
1453
1454/**
1455 * Get flow control status of end point: is client allow to send?
1456 *
1457 * @param ch Channel.
1458 * @param fwd Is query about FWD traffic? (Request root status).
1459 *
1460 * @return #GNUNET_YES if client is allowed to send us data.
1461 */
1462int
1463GCCH_get_allowed (struct CadetChannel *ch, int fwd)
1464{
1465 struct CadetChannelReliability *rel;
1466
1467 rel = fwd ? ch->root_rel : ch->dest_rel;
1468
1469 if (NULL == rel)
1470 {
1471 /* Probably shutting down: root/dest NULL'ed to mark disconnection */
1472 GNUNET_break (GNUNET_NO != ch->destroy);
1473 return 0;
1474 }
1475
1476 return rel->client_allowed;
1477} 1457}
1478 1458
1479 1459
1480/** 1460/**
1481 * Is the root client for this channel on this peer? 1461 * Function called once the tunnel has sent one of our messages.
1482 * 1462 * If the message is unreliable, simply frees the `crm`. If the
1483 * @param ch Channel. 1463 * message was reliable, calculate retransmission time and
1484 * @param fwd Is this for fwd traffic? 1464 * wait for ACK (or retransmit).
1485 * 1465 *
1486 * @return #GNUNET_YES in case it is. 1466 * @param cls the `struct CadetReliableMessage` that was sent
1467 * @param cid identifier of the connection within the tunnel, NULL
1468 * if transmission failed
1487 */ 1469 */
1488int 1470static void
1489GCCH_is_origin (struct CadetChannel *ch, int fwd) 1471data_sent_cb (void *cls,
1490{ 1472 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid);
1491 struct CadetClient *c;
1492
1493 c = fwd ? ch->root : ch->dest;
1494 return NULL != c;
1495}
1496 1473
1497 1474
1498/** 1475/**
1499 * Is the destination client for this channel on this peer? 1476 * We need to retry a transmission, the last one took too long to
1500 * 1477 * be acknowledged.
1501 * @param ch Channel.
1502 * @param fwd Is this for fwd traffic?
1503 * 1478 *
1504 * @return #GNUNET_YES in case it is. 1479 * @param cls the `struct CadetChannel` where we need to retransmit
1505 */ 1480 */
1506int 1481static void
1507GCCH_is_terminal (struct CadetChannel *ch, int fwd) 1482retry_transmission (void *cls)
1508{ 1483{
1509 struct CadetClient *c; 1484 struct CadetChannel *ch = cls;
1485 struct CadetReliableMessage *crm = ch->head_sent;
1510 1486
1511 c = fwd ? ch->dest : ch->root; 1487 ch->retry_data_task = NULL;
1512 return NULL != c; 1488 GNUNET_assert (NULL == crm->qe);
1489 LOG (GNUNET_ERROR_TYPE_DEBUG,
1490 "Retrying transmission on %s of message %u\n",
1491 GCCH_2s (ch),
1492 (unsigned int) ntohl (crm->data_message->mid.mid));
1493 crm->qe = GCT_send (ch->t,
1494 &crm->data_message->header,
1495 &data_sent_cb,
1496 crm);
1497 GNUNET_assert (NULL == ch->retry_data_task);
1513} 1498}
1514 1499
1515 1500
1516/** 1501/**
1517 * Send an end-to-end ACK message for the most recent in-sequence payload. 1502 * We got an PLAINTEXT_DATA_ACK for a message in our queue, remove it from
1518 * 1503 * the queue and tell our client that it can send more.
1519 * If channel is not reliable, do nothing.
1520 * 1504 *
1521 * @param ch Channel this is about. 1505 * @param ch the channel that got the PLAINTEXT_DATA_ACK
1522 * @param fwd Is for FWD traffic? (ACK dest->owner) 1506 * @param cti identifier of the connection that delivered the message
1507 * @param crm the message that got acknowledged
1523 */ 1508 */
1524void 1509static void
1525GCCH_send_data_ack (struct CadetChannel *ch, int fwd) 1510handle_matching_ack (struct CadetChannel *ch,
1511 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti,
1512 struct CadetReliableMessage *crm)
1526{ 1513{
1527 struct GNUNET_CADET_ChannelDataAckMessage msg; 1514 GNUNET_CONTAINER_DLL_remove (ch->head_sent,
1528 struct CadetChannelReliability *rel; 1515 ch->tail_sent,
1529 struct CadetReliableMessage *copy; 1516 crm);
1530 unsigned int delta; 1517 ch->pending_messages--;
1531 uint64_t mask; 1518 GNUNET_assert (ch->pending_messages < ch->max_pending_messages);
1532 uint32_t ack; 1519 LOG (GNUNET_ERROR_TYPE_DEBUG,
1533 1520 "Received DATA_ACK on %s for message %u (%u ACKs pending)\n",
1534 if (GNUNET_NO == ch->reliable) 1521 GCCH_2s (ch),
1535 return; 1522 (unsigned int) ntohl (crm->data_message->mid.mid),
1536 1523 ch->pending_messages);
1537 rel = fwd ? ch->dest_rel : ch->root_rel; 1524 if (NULL != crm->qe)
1538 ack = rel->mid_recv - 1; 1525 {
1539 1526 GCT_send_cancel (crm->qe);
1540 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK); 1527 crm->qe = NULL;
1541 msg.header.size = htons (sizeof (msg)); 1528 }
1542 msg.ctn = ch->gid; 1529 if ( (1 == crm->num_transmissions) &&
1543 msg.mid = htonl (ack); 1530 (NULL != cti) )
1544 1531 {
1545 msg.futures = 0LL; 1532 GCC_ack_observed (cti);
1546 for (copy = rel->head_recv; NULL != copy; copy = copy->next) 1533 if (0 == memcmp (cti,
1547 { 1534 &crm->connection_taken,
1548 if (copy->type != GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA) 1535 sizeof (struct GNUNET_CADET_ConnectionTunnelIdentifier)))
1549 { 1536 {
1550 LOG (GNUNET_ERROR_TYPE_DEBUG, " Type %s, expected DATA\n", 1537 GCC_latency_observed (cti,
1551 GC_m2s (copy->type)); 1538 GNUNET_TIME_absolute_get_duration (crm->first_transmission_time));
1552 continue;
1553 } 1539 }
1554 GNUNET_assert (GC_is_pid_bigger(copy->mid, ack));
1555 delta = copy->mid - (ack + 1);
1556 if (63 < delta)
1557 break;
1558 mask = 0x1LL << delta;
1559 msg.futures |= mask;
1560 LOG (GNUNET_ERROR_TYPE_DEBUG,
1561 " setting bit for %u (delta %u) (%lX) -> %lX\n",
1562 copy->mid, delta, mask, msg.futures);
1563 } 1540 }
1564 1541 GNUNET_free (crm->data_message);
1565 GCCH_send_prebuilt_message (&msg.header, ch, !fwd, NULL); 1542 GNUNET_free (crm);
1566 LOG (GNUNET_ERROR_TYPE_DEBUG, "send_data_ack END\n"); 1543 send_ack_to_client (ch,
1544 (NULL == ch->owner)
1545 ? GNUNET_NO
1546 : GNUNET_YES);
1567} 1547}
1568 1548
1569 1549
1570/** 1550/**
1571 * Allow a client to send us more data, in case it was choked. 1551 * We got an acknowledgement for payload data for a channel.
1552 * Possibly resume transmissions.
1572 * 1553 *
1573 * @param ch Channel. 1554 * @param ch channel that got the ack
1574 * @param fwd Is this about FWD traffic? (Root client). 1555 * @param cti identifier of the connection that delivered the message
1556 * @param ack details about what was received
1575 */ 1557 */
1576void 1558void
1577GCCH_allow_client (struct CadetChannel *ch, int fwd) 1559GCCH_handle_channel_plaintext_data_ack (struct CadetChannel *ch,
1560 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti,
1561 const struct GNUNET_CADET_ChannelDataAckMessage *ack)
1578{ 1562{
1579 struct CadetChannelReliability *rel; 1563 struct CadetReliableMessage *crm;
1580 unsigned int buffer; 1564 struct CadetReliableMessage *crmn;
1581 1565 int found;
1582 LOG (GNUNET_ERROR_TYPE_DEBUG, "GMCH allow\n"); 1566 uint32_t mid_base;
1567 uint64_t mid_mask;
1568 unsigned int delta;
1583 1569
1584 if (CADET_CHANNEL_READY != ch->state) 1570 GNUNET_break (GNUNET_NO == ch->is_loopback);
1571 if (GNUNET_NO == ch->reliable)
1585 { 1572 {
1586 LOG (GNUNET_ERROR_TYPE_DEBUG, " channel not ready yet!\n"); 1573 /* not expecting ACKs on unreliable channel, odd */
1574 GNUNET_break_op (0);
1587 return; 1575 return;
1588 } 1576 }
1589 1577 /* mid_base is the MID of the next message that the
1590 if (GNUNET_YES == ch->reliable) 1578 other peer expects (i.e. that is missing!), everything
1591 { 1579 LOWER (but excluding mid_base itself) was received. */
1592 rel = fwd ? ch->root_rel : ch->dest_rel; 1580 mid_base = ntohl (ack->mid.mid);
1593 if (NULL == rel) 1581 mid_mask = GNUNET_htonll (ack->futures);
1582 found = GNUNET_NO;
1583 for (crm = ch->head_sent;
1584 NULL != crm;
1585 crm = crmn)
1586 {
1587 crmn = crm->next;
1588 delta = (unsigned int) (ntohl (crm->data_message->mid.mid) - mid_base);
1589 if (delta >= UINT_MAX - ch->max_pending_messages)
1594 { 1590 {
1595 GNUNET_break (GNUNET_NO != ch->destroy); 1591 /* overflow, means crm was a bit in the past, so this ACK counts for it. */
1596 return; 1592 LOG (GNUNET_ERROR_TYPE_DEBUG,
1597 } 1593 "Got DATA_ACK with base %u satisfying past message %u on %s\n",
1598 if (NULL != rel->head_sent) 1594 (unsigned int) mid_base,
1599 { 1595 ntohl (crm->data_message->mid.mid),
1600 if (64 <= rel->mid_send - rel->head_sent->mid) 1596 GCCH_2s (ch));
1601 { 1597 handle_matching_ack (ch,
1602 LOG (GNUNET_ERROR_TYPE_DEBUG, " too big MID gap! Wait for ACK.\n"); 1598 cti,
1603 return; 1599 crm);
1604 } 1600 found = GNUNET_YES;
1605 else 1601 continue;
1606 {
1607 LOG (GNUNET_ERROR_TYPE_DEBUG, " gap ok: %u - %u\n",
1608 rel->head_sent->mid, rel->mid_send);
1609 struct CadetReliableMessage *aux;
1610 for (aux = rel->head_sent; NULL != aux; aux = aux->next)
1611 {
1612 LOG (GNUNET_ERROR_TYPE_DEBUG, " - sent mid %u\n", aux->mid);
1613 }
1614 }
1615 } 1602 }
1616 else 1603 delta--;
1604 if (delta >= 64)
1605 continue;
1606 LOG (GNUNET_ERROR_TYPE_DEBUG,
1607 "Testing bit %llX for mid %u (base: %u)\n",
1608 (1LLU << delta),
1609 ntohl (crm->data_message->mid.mid),
1610 mid_base);
1611 if (0 != (mid_mask & (1LLU << delta)))
1617 { 1612 {
1618 LOG (GNUNET_ERROR_TYPE_DEBUG, " head sent is NULL\n"); 1613 LOG (GNUNET_ERROR_TYPE_DEBUG,
1614 "Got DATA_ACK with mask for %u on %s\n",
1615 ntohl (crm->data_message->mid.mid),
1616 GCCH_2s (ch));
1617 handle_matching_ack (ch,
1618 cti,
1619 crm);
1620 found = GNUNET_YES;
1619 } 1621 }
1620 } 1622 }
1621 1623 if (GNUNET_NO == found)
1622 if (is_loopback (ch))
1623 buffer = GCCH_get_buffer (ch, fwd);
1624 else
1625 buffer = GCT_get_connections_buffer (ch->t);
1626
1627 if (0 == buffer)
1628 { 1624 {
1629 LOG (GNUNET_ERROR_TYPE_DEBUG, " no buffer space.\n"); 1625 /* ACK for message we already dropped, might have been a
1626 duplicate ACK? Ignore. */
1627 LOG (GNUNET_ERROR_TYPE_DEBUG,
1628 "Duplicate DATA_ACK on %s, ignoring\n",
1629 GCCH_2s (ch));
1630 GNUNET_STATISTICS_update (stats,
1631 "# duplicate DATA_ACKs",
1632 1,
1633 GNUNET_NO);
1630 return; 1634 return;
1631 } 1635 }
1632 1636 if (NULL != ch->retry_data_task)
1633 LOG (GNUNET_ERROR_TYPE_DEBUG, " buffer space %u, allowing\n", buffer); 1637 {
1634 send_client_ack (ch, fwd); 1638 GNUNET_SCHEDULER_cancel (ch->retry_data_task);
1639 ch->retry_data_task = NULL;
1640 }
1641 if ( (NULL != ch->head_sent) &&
1642 (NULL == ch->head_sent->qe) )
1643 ch->retry_data_task
1644 = GNUNET_SCHEDULER_add_at (ch->head_sent->next_retry,
1645 &retry_transmission,
1646 ch);
1635} 1647}
1636 1648
1637 1649
1638/** 1650/**
1639 * Log channel info. 1651 * Destroy channel, based on the other peer closing the
1652 * connection. Also needs to remove this channel from
1653 * the tunnel.
1640 * 1654 *
1641 * @param ch Channel. 1655 * @param ch channel to destroy
1642 * @param level Debug level to use. 1656 * @param cti identifier of the connection that delivered the message,
1657 * NULL if we are simulating receiving a destroy due to shutdown
1643 */ 1658 */
1644void 1659void
1645GCCH_debug (struct CadetChannel *ch, enum GNUNET_ErrorType level) 1660GCCH_handle_remote_destroy (struct CadetChannel *ch,
1661 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti)
1646{ 1662{
1647 int do_log; 1663 struct CadetChannelClient *ccc;
1648 1664
1649 do_log = GNUNET_get_log_call_status (level & (~GNUNET_ERROR_TYPE_BULK), 1665 GNUNET_assert (GNUNET_NO == ch->is_loopback);
1650 "cadet-chn", 1666 LOG (GNUNET_ERROR_TYPE_DEBUG,
1651 __FILE__, __FUNCTION__, __LINE__); 1667 "Received remote channel DESTROY for %s\n",
1652 if (0 == do_log) 1668 GCCH_2s (ch));
1653 return; 1669 if (GNUNET_YES == ch->destroy)
1654
1655 if (NULL == ch)
1656 { 1670 {
1657 LOG2 (level, "CHN *** DEBUG NULL CHANNEL ***\n"); 1671 /* Local client already gone, this is instant-death. */
1672 channel_destroy (ch);
1658 return; 1673 return;
1659 } 1674 }
1660 LOG2 (level, "CHN Channel %s:%X (%p)\n", GCT_2s (ch->t), ch->gid, ch); 1675 ccc = (NULL != ch->owner) ? ch->owner : ch->dest;
1661 LOG2 (level, "CHN root %p/%p\n", ch->root, ch->root_rel); 1676 if ( (NULL != ccc) &&
1662 if (NULL != ch->root) 1677 (NULL != ccc->head_recv) )
1663 {
1664 LOG2 (level, "CHN cli %s\n", GML_2s (ch->root));
1665 LOG2 (level, "CHN ready %s\n", ch->root_rel->client_ready ? "YES" : "NO");
1666 LOG2 (level, "CHN id %X\n", ch->lid_root.channel_of_client);
1667 LOG2 (level, "CHN recv %d\n", ch->root_rel->n_recv);
1668 LOG2 (level, "CHN MID r: %d, s: %d\n",
1669 ch->root_rel->mid_recv, ch->root_rel->mid_send);
1670 }
1671 LOG2 (level, "CHN dest %p/%p\n",
1672 ch->dest, ch->dest_rel);
1673 if (NULL != ch->dest)
1674 { 1678 {
1675 LOG2 (level, "CHN cli %s\n", GML_2s (ch->dest)); 1679 LOG (GNUNET_ERROR_TYPE_WARNING,
1676 LOG2 (level, "CHN ready %s\n", ch->dest_rel->client_ready ? "YES" : "NO"); 1680 "Lost end of transmission due to remote shutdown on %s\n",
1677 LOG2 (level, "CHN id %X\n", ch->lid_dest); 1681 GCCH_2s (ch));
1678 LOG2 (level, "CHN recv %d\n", ch->dest_rel->n_recv); 1682 /* FIXME: change API to notify client about truncated transmission! */
1679 LOG2 (level, "CHN MID r: %d, s: %d\n",
1680 ch->dest_rel->mid_recv, ch->dest_rel->mid_send);
1681
1682 } 1683 }
1684 ch->destroy = GNUNET_YES;
1685 if (NULL != ccc)
1686 GSC_handle_remote_channel_destroy (ccc->c,
1687 ccc->ccn,
1688 ch);
1689 channel_destroy (ch);
1683} 1690}
1684 1691
1685 1692
1686/** 1693/**
1687 * Handle an ACK given by a client. 1694 * Test if element @a e1 comes before element @a e2.
1688 * 1695 *
1689 * Mark client as ready and send him any buffered data we could have for him. 1696 * @param cls closure, to a flag where we indicate duplicate packets
1690 * 1697 * @param crm1 an element of to sort
1691 * @param ch Channel. 1698 * @param crm2 another element to sort
1692 * @param fwd Is this a "FWD ACK"? (FWD ACKs are sent by dest and go BCK) 1699 * @return #GNUNET_YES if @e1 < @e2, otherwise #GNUNET_NO
1693 */ 1700 */
1694void 1701static int
1695GCCH_handle_local_ack (struct CadetChannel *ch, int fwd) 1702cmp_crm_by_next_retry (void *cls,
1703 struct CadetReliableMessage *crm1,
1704 struct CadetReliableMessage *crm2)
1696{ 1705{
1697 struct CadetChannelReliability *rel; 1706 if (crm1->next_retry.abs_value_us <
1698 struct CadetClient *c; 1707 crm2->next_retry.abs_value_us)
1699 1708 return GNUNET_YES;
1700 rel = fwd ? ch->dest_rel : ch->root_rel; 1709 return GNUNET_NO;
1701 c = fwd ? ch->dest : ch->root;
1702
1703 rel->client_ready = GNUNET_YES;
1704 send_client_buffered_data (ch, c, fwd);
1705
1706 if (GNUNET_YES == ch->destroy && 0 == rel->n_recv)
1707 {
1708 send_destroy (ch, GNUNET_YES);
1709 GCCH_destroy (ch);
1710 return;
1711 }
1712 /* if loopback is marked for destruction, no need to ACK to the other peer,
1713 * it requested the destruction and is already gone, therefore, else if.
1714 */
1715 else if (is_loopback (ch))
1716 {
1717 unsigned int buffer;
1718
1719 buffer = GCCH_get_buffer (ch, fwd);
1720 if (0 < buffer)
1721 GCCH_allow_client (ch, fwd);
1722
1723 return;
1724 }
1725 GCT_send_connection_acks (ch->t);
1726} 1710}
1727 1711
1728 1712
1729/** 1713/**
1730 * Handle data given by a client. 1714 * Function called once the tunnel has sent one of our messages.
1731 * 1715 * If the message is unreliable, simply frees the `crm`. If the
1732 * Check whether the client is allowed to send in this tunnel, save if channel 1716 * message was reliable, calculate retransmission time and
1733 * is reliable and send an ACK to the client if there is still buffer space 1717 * wait for ACK (or retransmit).
1734 * in the tunnel. 1718 *
1735 * 1719 * @param cls the `struct CadetReliableMessage` that was sent
1736 * @param ch Channel. 1720 * @param cid identifier of the connection within the tunnel, NULL
1737 * @param c Client which sent the data. 1721 * if transmission failed
1738 * @param fwd Is this a FWD data?
1739 * @param message Data message.
1740 * @param size Size of data.
1741 *
1742 * @return #GNUNET_OK if everything goes well, #GNUNET_SYSERR in case of en error.
1743 */ 1722 */
1744int 1723static void
1745GCCH_handle_local_data (struct CadetChannel *ch, 1724data_sent_cb (void *cls,
1746 struct CadetClient *c, 1725 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
1747 int fwd,
1748 const struct GNUNET_MessageHeader *message,
1749 size_t size)
1750{ 1726{
1751 struct CadetChannelReliability *rel; 1727 struct CadetReliableMessage *crm = cls;
1752 struct GNUNET_CADET_ChannelAppDataMessage *payload; 1728 struct CadetChannel *ch = crm->ch;
1753 uint16_t p2p_size = sizeof(struct GNUNET_CADET_ChannelAppDataMessage) + size; 1729
1754 unsigned char cbuf[p2p_size]; 1730 GNUNET_assert (GNUNET_NO == ch->is_loopback);
1755 unsigned char buffer; 1731 GNUNET_assert (NULL != crm->qe);
1756 1732 crm->qe = NULL;
1757 /* Is the client in the channel? */ 1733 GNUNET_CONTAINER_DLL_remove (ch->head_sent,
1758 if ( !( (fwd && 1734 ch->tail_sent,
1759 ch->root == c) 1735 crm);
1760 || 1736 if (GNUNET_NO == ch->reliable)
1761 (!fwd &&
1762 ch->dest == c) ) )
1763 { 1737 {
1764 GNUNET_break_op (0); 1738 GNUNET_free (crm->data_message);
1765 return GNUNET_SYSERR; 1739 GNUNET_free (crm);
1740 ch->pending_messages--;
1741 send_ack_to_client (ch,
1742 (NULL == ch->owner)
1743 ? GNUNET_NO
1744 : GNUNET_YES);
1745 return;
1766 } 1746 }
1767 1747 if (NULL == cid)
1768 rel = fwd ? ch->root_rel : ch->dest_rel;
1769
1770 if (GNUNET_NO == rel->client_allowed)
1771 { 1748 {
1772 GNUNET_break_op (0); 1749 /* There was an error sending. */
1773 return GNUNET_SYSERR; 1750 crm->num_transmissions = GNUNET_SYSERR;
1774 } 1751 }
1775 1752 else if (GNUNET_SYSERR != crm->num_transmissions)
1776 rel->client_allowed = GNUNET_NO;
1777
1778 /* Ok, everything is correct, send the message. */
1779 payload = (struct GNUNET_CADET_ChannelAppDataMessage *) cbuf;
1780 payload->mid = htonl (rel->mid_send);
1781 rel->mid_send++;
1782 GNUNET_memcpy (&payload[1], message, size);
1783 payload->header.size = htons (p2p_size);
1784 payload->header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA);
1785 payload->ctn = ch->gid;
1786 LOG (GNUNET_ERROR_TYPE_DEBUG, " sending on channel...\n");
1787 GCCH_send_prebuilt_message (&payload->header, ch, fwd, NULL);
1788
1789 if (is_loopback (ch))
1790 buffer = GCCH_get_buffer (ch, fwd);
1791 else
1792 buffer = GCT_get_connections_buffer (ch->t);
1793
1794 if (0 < buffer)
1795 GCCH_allow_client (ch, fwd);
1796
1797 return GNUNET_OK;
1798}
1799
1800
1801/**
1802 * Handle a channel destroy requested by a client.
1803 *
1804 * TODO: add "reason" field
1805 *
1806 * Destroy the channel and the tunnel in case this was the last channel.
1807 *
1808 * @param ch Channel.
1809 * @param c Client that requested the destruction (to avoid notifying him).
1810 * @param is_root Is the request coming from root?
1811 */
1812void
1813GCCH_handle_local_destroy (struct CadetChannel *ch,
1814 struct CadetClient *c,
1815 int is_root)
1816{
1817 ch->destroy = GNUNET_YES;
1818 /* Cleanup after the tunnel */
1819 if (GNUNET_NO == is_root && c == ch->dest)
1820 { 1753 {
1821 LOG (GNUNET_ERROR_TYPE_DEBUG, " Client %s is destination.\n", GML_2s (c)); 1754 /* Increment transmission counter, and possibly store @a cid
1822 GML_client_delete_channel (c, ch, ch->lid_dest); 1755 if this was the first transmission. */
1823 ch->dest = NULL; 1756 crm->num_transmissions++;
1757 if (1 == crm->num_transmissions)
1758 {
1759 crm->first_transmission_time = GNUNET_TIME_absolute_get ();
1760 crm->connection_taken = *cid;
1761 GCC_ack_expected (cid);
1762 }
1824 } 1763 }
1825 if (GNUNET_YES == is_root && c == ch->root) 1764 if ( (0 == crm->retry_delay.rel_value_us) &&
1765 (NULL != cid) )
1826 { 1766 {
1827 LOG (GNUNET_ERROR_TYPE_DEBUG, " Client %s is owner.\n", GML_2s (c)); 1767 struct CadetConnection *cc = GCC_lookup (cid);
1828 GML_client_delete_channel (c, ch, ch->lid_root);
1829 ch->root = NULL;
1830 }
1831 1768
1832 send_destroy (ch, GNUNET_NO); 1769 if (NULL != cc)
1833 if (0 == ch->pending_messages) 1770 crm->retry_delay = GCC_get_metrics (cc)->aged_latency;
1834 GCCH_destroy (ch); 1771 else
1772 crm->retry_delay = ch->retry_time;
1773 }
1774 crm->retry_delay = GNUNET_TIME_STD_BACKOFF (crm->retry_delay);
1775 crm->retry_delay = GNUNET_TIME_relative_max (crm->retry_delay,
1776 MIN_RTT_DELAY);
1777 crm->next_retry = GNUNET_TIME_relative_to_absolute (crm->retry_delay);
1778
1779 GNUNET_CONTAINER_DLL_insert_sorted (struct CadetReliableMessage,
1780 cmp_crm_by_next_retry,
1781 NULL,
1782 ch->head_sent,
1783 ch->tail_sent,
1784 crm);
1785 LOG (GNUNET_ERROR_TYPE_DEBUG,
1786 "Message %u sent, next transmission on %s in %s\n",
1787 (unsigned int) ntohl (crm->data_message->mid.mid),
1788 GCCH_2s (ch),
1789 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_remaining (ch->head_sent->next_retry),
1790 GNUNET_YES));
1791 if (NULL == ch->head_sent->qe)
1792 {
1793 if (NULL != ch->retry_data_task)
1794 GNUNET_SCHEDULER_cancel (ch->retry_data_task);
1795 ch->retry_data_task
1796 = GNUNET_SCHEDULER_add_at (ch->head_sent->next_retry,
1797 &retry_transmission,
1798 ch);
1799 }
1835} 1800}
1836 1801
1837 1802
1838/** 1803/**
1839 * Handle a channel create requested by a client. 1804 * Handle data given by a client.
1840 *
1841 * Create the channel and the tunnel in case this was the first0 channel.
1842 * 1805 *
1843 * @param c Client that requested the creation (will be the root). 1806 * Check whether the client is allowed to send in this tunnel, save if
1844 * @param msg Create Channel message. 1807 * channel is reliable and send an ACK to the client if there is still
1808 * buffer space in the tunnel.
1845 * 1809 *
1846 * @return #GNUNET_OK if everything went fine, #GNUNET_SYSERR otherwise. 1810 * @param ch Channel.
1811 * @param sender_ccn ccn of the sender
1812 * @param buf payload to transmit.
1813 * @param buf_len number of bytes in @a buf
1814 * @return #GNUNET_OK if everything goes well,
1815 * #GNUNET_SYSERR in case of an error.
1847 */ 1816 */
1848int 1817int
1849GCCH_handle_local_create (struct CadetClient *c, 1818GCCH_handle_local_data (struct CadetChannel *ch,
1850 struct GNUNET_CADET_LocalChannelCreateMessage *msg) 1819 struct GNUNET_CADET_ClientChannelNumber sender_ccn,
1820 const char *buf,
1821 size_t buf_len)
1851{ 1822{
1852 struct CadetChannel *ch; 1823 struct CadetReliableMessage *crm;
1853 struct CadetTunnel *t;
1854 struct CadetPeer *peer;
1855 struct GNUNET_CADET_ClientChannelNumber ccn;
1856
1857 LOG (GNUNET_ERROR_TYPE_DEBUG, " towards %s:%u\n",
1858 GNUNET_i2s (&msg->peer), GNUNET_h2s (&msg->port));
1859 ccn = msg->ccn;
1860 1824
1861 /* Sanity check for duplicate channel IDs */ 1825 if (ch->pending_messages > ch->max_pending_messages)
1862 if (NULL != GML_channel_get (c, ccn))
1863 { 1826 {
1864 GNUNET_break (0); 1827 GNUNET_break (0);
1865 return GNUNET_SYSERR; 1828 return GNUNET_SYSERR;
1866 } 1829 }
1867 1830 if (GNUNET_YES == ch->destroy)
1868 peer = GCP_get (&msg->peer, GNUNET_YES);
1869 GCP_add_tunnel (peer);
1870 t = GCP_get_tunnel (peer);
1871
1872 if (GCP_get_short_id (peer) == myid)
1873 {
1874 GCT_change_cstate (t, CADET_TUNNEL_READY);
1875 }
1876 else
1877 { 1831 {
1878 /* FIXME change to a tunnel API, eliminate ch <-> peer connection */ 1832 /* we are going down, drop messages */
1879 GCP_connect (peer); 1833 return GNUNET_OK;
1880 } 1834 }
1835 ch->pending_messages++;
1881 1836
1882 /* Create channel */ 1837 if (GNUNET_YES == ch->is_loopback)
1883 ch = channel_new (t, c, ccn);
1884 if (NULL == ch)
1885 {
1886 GNUNET_break (0);
1887 return GNUNET_SYSERR;
1888 }
1889 ch->port = msg->port;
1890 channel_set_options (ch, ntohl (msg->opt));
1891
1892 /* In unreliable channels, we'll use the DLL to buffer BCK data */
1893 ch->root_rel = GNUNET_new (struct CadetChannelReliability);
1894 ch->root_rel->ch = ch;
1895 ch->root_rel->retry_timer = CADET_RETRANSMIT_TIME;
1896 ch->root_rel->expected_delay.rel_value_us = 0;
1897
1898 LOG (GNUNET_ERROR_TYPE_DEBUG, "CREATED CHANNEL %s\n", GCCH_2s (ch));
1899
1900 send_create (ch);
1901
1902 return GNUNET_OK;
1903}
1904
1905
1906/**
1907 * Handler for cadet network payload traffic.
1908 *
1909 * @param ch Channel for the message.
1910 * @param msg Unencryted data message.
1911 * @param fwd Is this message fwd? This only is meaningful in loopback channels.
1912 * #GNUNET_YES if message is FWD on the respective channel (loopback)
1913 * #GNUNET_NO if message is BCK on the respective channel (loopback)
1914 * #GNUNET_SYSERR if message on a one-ended channel (remote)
1915 */
1916void
1917GCCH_handle_data (struct CadetChannel *ch,
1918 const struct GNUNET_CADET_ChannelAppDataMessage *msg,
1919 int fwd)
1920{
1921 struct CadetChannelReliability *rel;
1922 struct CadetClient *c;
1923 struct GNUNET_MessageHeader *payload_msg;
1924 uint32_t mid;
1925 uint16_t payload_type;
1926 uint16_t payload_size;
1927
1928 /* If this is a remote (non-loopback) channel, find 'fwd'. */
1929 if (GNUNET_SYSERR == fwd)
1930 {
1931 if (is_loopback (ch))
1932 {
1933 /* It is a loopback channel after all... */
1934 GNUNET_break (0);
1935 return;
1936 }
1937 fwd = (NULL != ch->dest) ? GNUNET_YES : GNUNET_NO;
1938 }
1939
1940 /* Initialize FWD/BCK data */
1941 c = fwd ? ch->dest : ch->root;
1942 rel = fwd ? ch->dest_rel : ch->root_rel;
1943
1944 if (NULL == c)
1945 { 1838 {
1946 GNUNET_break (GNUNET_NO != ch->destroy); 1839 struct CadetChannelClient *receiver;
1947 return; 1840 struct GNUNET_MQ_Envelope *env;
1948 } 1841 struct GNUNET_CADET_LocalData *ld;
1842 int ack_to_owner;
1949 1843
1950 if (CADET_CHANNEL_READY != ch->state) 1844 env = GNUNET_MQ_msg_extra (ld,
1951 { 1845 buf_len,
1952 if (GNUNET_NO == fwd) 1846 GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA);
1847 if ( (NULL != ch->owner) &&
1848 (sender_ccn.channel_of_client ==
1849 ch->owner->ccn.channel_of_client) )
1953 { 1850 {
1954 /* If we are the root, this means the other peer has sent traffic before 1851 receiver = ch->dest;
1955 * receiving our ACK. Even if the SYNACK goes missing, no traffic should 1852 ack_to_owner = GNUNET_YES;
1956 * be sent before the ACK.
1957 */
1958 GNUNET_break_op (0);
1959 return;
1960 } 1853 }
1961 /* If we are the dest, this means that the SYNACK got to the root but 1854 else if ( (NULL != ch->dest) &&
1962 * the ACK went missing. Treat this as an ACK. 1855 (sender_ccn.channel_of_client ==
1963 */ 1856 ch->dest->ccn.channel_of_client) )
1964 channel_confirm (ch, GNUNET_NO);
1965 }
1966
1967 payload_msg = (struct GNUNET_MessageHeader *) &msg[1];
1968 payload_type = ntohs (payload_msg->type);
1969 payload_size = ntohs (payload_msg->size);
1970
1971 GNUNET_STATISTICS_update (stats, "# messages received", 1, GNUNET_NO);
1972 GNUNET_STATISTICS_update (stats, "# bytes received", payload_size, GNUNET_NO);
1973
1974 mid = ntohl (msg->mid);
1975 LOG (GNUNET_ERROR_TYPE_INFO, "<== %s (%s %4u) on chan %s (%p) %s [%5u]\n",
1976 GC_m2s (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA), GC_m2s (payload_type), mid,
1977 GCCH_2s (ch), ch, GC_f2s (fwd), ntohs (msg->header.size));
1978
1979 if ( (GNUNET_NO == ch->reliable) ||
1980 ( (! GC_is_pid_bigger (rel->mid_recv, mid)) &&
1981 GC_is_pid_bigger (rel->mid_recv + 64, mid) ) )
1982 {
1983 if (GNUNET_YES == ch->reliable)
1984 { 1857 {
1985 /* Is this the exact next expected messasge? */ 1858 receiver = ch->owner;
1986 if (mid == rel->mid_recv) 1859 ack_to_owner = GNUNET_NO;
1987 {
1988 LOG (GNUNET_ERROR_TYPE_DEBUG,
1989 "as expected, sending to client\n");
1990 send_client_data (ch, msg, fwd);
1991 }
1992 else
1993 {
1994 LOG (GNUNET_ERROR_TYPE_DEBUG,
1995 "save for later\n");
1996 add_buffered_data (msg, rel);
1997 }
1998 } 1860 }
1999 else 1861 else
2000 { 1862 {
2001 /* Tunnel is unreliable: send to clients directly */ 1863 GNUNET_break (0);
2002 /* FIXME: accept Out Of Order traffic */ 1864 return GNUNET_SYSERR;
2003 rel->mid_recv = mid + 1;
2004 send_client_data (ch, msg, fwd);
2005 } 1865 }
2006 } 1866 GNUNET_assert (NULL != receiver);
2007 else 1867 ld->ccn = receiver->ccn;
2008 { 1868 GNUNET_memcpy (&ld[1],
2009 GNUNET_STATISTICS_update (stats, "# duplicate MID", 1, GNUNET_NO); 1869 buf,
2010 if (GC_is_pid_bigger (rel->mid_recv, mid)) 1870 buf_len);
1871 if (GNUNET_YES == receiver->client_ready)
2011 { 1872 {
2012 GNUNET_break_op (0); 1873 ch->pending_messages--;
2013 LOG (GNUNET_ERROR_TYPE_WARNING, 1874 GSC_send_to_client (receiver->c,
2014 "MID %u on channel %s not expected (window: %u - %u). Dropping!\n", 1875 env);
2015 mid, GCCH_2s (ch), rel->mid_recv, rel->mid_recv + 63); 1876 send_ack_to_client (ch,
1877 ack_to_owner);
2016 } 1878 }
2017 else 1879 else
2018 { 1880 {
2019 LOG (GNUNET_ERROR_TYPE_INFO, 1881 struct CadetOutOfOrderMessage *oom;
2020 "Duplicate MID %u, channel %s (expecting MID %u). Re-sending ACK!\n", 1882
2021 mid, GCCH_2s (ch), rel->mid_recv); 1883 oom = GNUNET_new (struct CadetOutOfOrderMessage);
2022 if (NULL != rel->uniq) 1884 oom->env = env;
2023 { 1885 GNUNET_CONTAINER_DLL_insert_tail (receiver->head_recv,
2024 LOG (GNUNET_ERROR_TYPE_WARNING, 1886 receiver->tail_recv,
2025 "We are trying to send an ACK, but don't seem have the " 1887 oom);
2026 "bandwidth. Have you set enough [ats] QUOTA in your config?\n"); 1888 receiver->num_recv++;
2027 }
2028
2029 } 1889 }
2030 } 1890 return GNUNET_OK;
2031 1891 }
2032 GCCH_send_data_ack (ch, fwd); 1892
1893 /* Everything is correct, send the message. */
1894 crm = GNUNET_malloc (sizeof (*crm));
1895 crm->ch = ch;
1896 crm->data_message = GNUNET_malloc (sizeof (struct GNUNET_CADET_ChannelAppDataMessage)
1897 + buf_len);
1898 crm->data_message->header.size = htons (sizeof (struct GNUNET_CADET_ChannelAppDataMessage) + buf_len);
1899 crm->data_message->header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA);
1900 ch->mid_send.mid = htonl (ntohl (ch->mid_send.mid) + 1);
1901 crm->data_message->mid = ch->mid_send;
1902 crm->data_message->ctn = ch->ctn;
1903 GNUNET_memcpy (&crm->data_message[1],
1904 buf,
1905 buf_len);
1906 GNUNET_CONTAINER_DLL_insert_tail (ch->head_sent,
1907 ch->tail_sent,
1908 crm);
1909 LOG (GNUNET_ERROR_TYPE_DEBUG,
1910 "Sending message %u from local client to %s with %u bytes\n",
1911 ntohl (crm->data_message->mid.mid),
1912 GCCH_2s (ch),
1913 buf_len);
1914 if (NULL != ch->retry_data_task)
1915 {
1916 GNUNET_SCHEDULER_cancel (ch->retry_data_task);
1917 ch->retry_data_task = NULL;
1918 }
1919 crm->qe = GCT_send (ch->t,
1920 &crm->data_message->header,
1921 &data_sent_cb,
1922 crm);
1923 GNUNET_assert (NULL == ch->retry_data_task);
1924 return GNUNET_OK;
2033} 1925}
2034 1926
2035 1927
2036/** 1928/**
2037 * Handler for cadet network traffic end-to-end ACKs. 1929 * Handle ACK from client on local channel. Means the client is ready
1930 * for more data, see if we have any for it.
2038 * 1931 *
2039 * @param ch Channel on which we got this message. 1932 * @param ch channel to destroy
2040 * @param msg Data message. 1933 * @param client_ccn ccn of the client sending the ack
2041 * @param fwd Is this message fwd? This only is meaningful in loopback channels.
2042 * #GNUNET_YES if message is FWD on the respective channel (loopback)
2043 * #GNUNET_NO if message is BCK on the respective channel (loopback)
2044 * #GNUNET_SYSERR if message on a one-ended channel (remote)
2045 */ 1934 */
2046void 1935void
2047GCCH_handle_data_ack (struct CadetChannel *ch, 1936GCCH_handle_local_ack (struct CadetChannel *ch,
2048 const struct GNUNET_CADET_ChannelDataAckMessage *msg, 1937 struct GNUNET_CADET_ClientChannelNumber client_ccn)
2049 int fwd)
2050{ 1938{
2051 struct CadetChannelReliability *rel; 1939 struct CadetChannelClient *ccc;
2052 struct CadetReliableMessage *copy; 1940 struct CadetOutOfOrderMessage *com;
2053 struct CadetReliableMessage *next; 1941
2054 uint32_t ack; 1942 if ( (NULL != ch->owner) &&
2055 int work; 1943 (ch->owner->ccn.channel_of_client == client_ccn.channel_of_client) )
2056 1944 ccc = ch->owner;
2057 /* If this is a remote (non-loopback) channel, find 'fwd'. */ 1945 else if ( (NULL != ch->dest) &&
2058 if (GNUNET_SYSERR == fwd) 1946 (ch->dest->ccn.channel_of_client == client_ccn.channel_of_client) )
2059 { 1947 ccc = ch->dest;
2060 if (is_loopback (ch))
2061 {
2062 /* It is a loopback channel after all... */
2063 GNUNET_break (0);
2064 return;
2065 }
2066 /* Inverted: if message came 'FWD' is a 'BCK ACK'. */
2067 fwd = (NULL != ch->dest) ? GNUNET_NO : GNUNET_YES;
2068 }
2069
2070 ack = ntohl (msg->mid);
2071 LOG (GNUNET_ERROR_TYPE_INFO,
2072 "<== %s (0x%010lX %4u) on chan %s (%p) %s [%5u]\n",
2073 GC_m2s (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK), msg->futures, ack,
2074 GCCH_2s (ch), ch, GC_f2s (fwd), ntohs (msg->header.size));
2075
2076 if (GNUNET_YES == fwd)
2077 rel = ch->root_rel;
2078 else 1948 else
2079 rel = ch->dest_rel; 1949 GNUNET_assert (0);
2080 1950 ccc->client_ready = GNUNET_YES;
2081 if (NULL == rel) 1951 com = ccc->head_recv;
2082 { 1952 if (NULL == com)
2083 GNUNET_break (GNUNET_NO != ch->destroy);
2084 return;
2085 }
2086
2087 /* Free ACK'd copies: no need to retransmit those anymore FIXME refactor */
2088 for (work = GNUNET_NO, copy = rel->head_sent; copy != NULL; copy = next)
2089 { 1953 {
2090 if (GC_is_pid_bigger (copy->mid, ack)) 1954 LOG (GNUNET_ERROR_TYPE_DEBUG,
2091 { 1955 "Got LOCAL_ACK, %s-%X ready to receive more data, but none pending on %s-%X(%p)!\n",
2092 LOG (GNUNET_ERROR_TYPE_DEBUG, " head %u, out!\n", copy->mid); 1956 GSC_2s (ccc->c),
2093 if (0 < channel_rel_free_sent (rel, msg)) 1957 ntohl (client_ccn.channel_of_client),
2094 work = GNUNET_YES; 1958 GCCH_2s (ch),
2095 break; 1959 ntohl (ccc->ccn.channel_of_client),
2096 } 1960 ccc);
2097 work = GNUNET_YES; 1961 return; /* none pending */
2098 LOG (GNUNET_ERROR_TYPE_DEBUG, " id %u\n", copy->mid); 1962 }
2099 next = copy->next; 1963 if (GNUNET_YES == ch->is_loopback)
2100 if (GNUNET_YES == rel_message_free (copy, GNUNET_YES)) 1964 {
2101 { 1965 int to_owner;
2102 LOG (GNUNET_ERROR_TYPE_DEBUG, " channel destoyed\n"); 1966
2103 return; 1967 /* Messages are always in-order, just send */
2104 } 1968 GNUNET_CONTAINER_DLL_remove (ccc->head_recv,
2105 } 1969 ccc->tail_recv,
2106 1970 com);
2107 /* ACK client if needed and possible */ 1971 ccc->num_recv--;
2108 GCCH_allow_client (ch, fwd); 1972 GSC_send_to_client (ccc->c,
2109 1973 com->env);
2110 /* If some message was free'd, update the retransmission delay */ 1974 /* Notify sender that we can receive more */
2111 if (GNUNET_YES == work) 1975 if ( (NULL != ch->owner) &&
2112 { 1976 (ccc->ccn.channel_of_client ==
2113 if (NULL != rel->retry_task) 1977 ch->owner->ccn.channel_of_client) )
2114 { 1978 {
2115 GNUNET_SCHEDULER_cancel (rel->retry_task); 1979 to_owner = GNUNET_NO;
2116 rel->retry_task = NULL;
2117 if (NULL != rel->head_sent && NULL == rel->head_sent->chq)
2118 {
2119 struct GNUNET_TIME_Absolute new_target;
2120 struct GNUNET_TIME_Relative delay;
2121
2122 delay = GNUNET_TIME_relative_saturating_multiply (rel->retry_timer,
2123 CADET_RETRANSMIT_MARGIN);
2124 new_target = GNUNET_TIME_absolute_add (rel->head_sent->timestamp,
2125 delay);
2126 delay = GNUNET_TIME_absolute_get_remaining (new_target);
2127 rel->retry_task =
2128 GNUNET_SCHEDULER_add_delayed (delay,
2129 &channel_retransmit_message,
2130 rel);
2131 }
2132 } 1980 }
2133 else 1981 else
2134 { 1982 {
2135 /* Work was done but no task was pending. 1983 GNUNET_assert ( (NULL != ch->dest) &&
2136 * Task was cancelled by a retransmission that is sitting in the queue. 1984 (ccc->ccn.channel_of_client ==
2137 */ 1985 ch->dest->ccn.channel_of_client) );
2138 // FIXME add test to make sure this is the case, probably add return 1986 to_owner = GNUNET_YES;
2139 // value to GCCH_send_prebuilt_message
2140 } 1987 }
1988 send_ack_to_client (ch,
1989 to_owner);
1990 GNUNET_free (com);
1991 return;
2141 } 1992 }
2142}
2143
2144 1993
2145/** 1994 if ( (com->mid.mid != ch->mid_recv.mid) &&
2146 * Handler for channel create messages. 1995 (GNUNET_NO == ch->out_of_order) &&
2147 * 1996 (GNUNET_YES == ch->reliable) )
2148 * Does not have fwd parameter because it's always 'FWD': channel is incoming.
2149 *
2150 * @param t Tunnel this channel will be in.
2151 * @param msg Channel crate message.
2152 */
2153struct CadetChannel *
2154GCCH_handle_create (struct CadetTunnel *t,
2155 const struct GNUNET_CADET_ChannelOpenMessage *msg)
2156{
2157 struct GNUNET_CADET_ClientChannelNumber ccn;
2158 struct GNUNET_CADET_ChannelTunnelNumber gid;
2159 struct CadetChannel *ch;
2160 struct CadetClient *c;
2161 int new_channel;
2162 const struct GNUNET_HashCode *port;
2163
2164 gid = msg->ctn;
2165 ch = GCT_get_channel (t, gid);
2166 if (NULL == ch)
2167 { 1997 {
2168 /* Create channel */ 1998 LOG (GNUNET_ERROR_TYPE_DEBUG,
2169 ccn.channel_of_client = htonl (0); 1999 "Got LOCAL_ACK, %s-%X ready to receive more data (but next one is out-of-order %u vs. %u)!\n",
2170 ch = channel_new (t, NULL, ccn); 2000 GSC_2s (ccc->c),
2171 ch->gid = gid; 2001 ntohl (ccc->ccn.channel_of_client),
2172 channel_set_options (ch, ntohl (msg->opt)); 2002 ntohl (com->mid.mid),
2173 new_channel = GNUNET_YES; 2003 ntohl (ch->mid_recv.mid));
2174 } 2004 return; /* missing next one in-order */
2175 else
2176 {
2177 new_channel = GNUNET_NO;
2178 } 2005 }
2179 port = &msg->port;
2180
2181 LOG (GNUNET_ERROR_TYPE_INFO,
2182 "<== %s ( 0x%08X %4u) on chan %s (%p) %s [%5u]\n",
2183 GC_m2s (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN), ccn, port,
2184 GCCH_2s (ch), ch, GC_f2s (GNUNET_YES), ntohs (msg->header.size));
2185
2186 if (GNUNET_YES == new_channel || GCT_is_loopback (t))
2187 {
2188 /* Find a destination client */
2189 ch->port = *port;
2190 LOG (GNUNET_ERROR_TYPE_DEBUG, " port %s\n", GNUNET_h2s (port));
2191 c = GML_client_get_by_port (port);
2192 if (NULL == c)
2193 {
2194 LOG (GNUNET_ERROR_TYPE_DEBUG, " no client has port registered\n");
2195 if (is_loopback (ch))
2196 {
2197 LOG (GNUNET_ERROR_TYPE_DEBUG, " loopback: destroy on handler\n");
2198 send_nack (ch);
2199 }
2200 else
2201 {
2202 LOG (GNUNET_ERROR_TYPE_DEBUG, " not loopback: destroy now\n");
2203 send_nack (ch);
2204 GCCH_destroy (ch);
2205 }
2206 return NULL;
2207 }
2208 else
2209 {
2210 LOG (GNUNET_ERROR_TYPE_DEBUG, " client %p has port registered\n", c);
2211 }
2212
2213 add_destination (ch, c);
2214 if (GNUNET_YES == ch->reliable)
2215 LOG (GNUNET_ERROR_TYPE_DEBUG, "Reliable\n");
2216 else
2217 LOG (GNUNET_ERROR_TYPE_DEBUG, "Not Reliable\n");
2218 2006
2219 send_client_create (ch); 2007 LOG (GNUNET_ERROR_TYPE_DEBUG,
2220 ch->state = CADET_CHANNEL_SENT; 2008 "Got LOCAL_ACK, giving payload message %u to %s-%X on %s\n",
2221 } 2009 ntohl (com->mid.mid),
2222 else 2010 GSC_2s (ccc->c),
2223 { 2011 ntohl (ccc->ccn.channel_of_client),
2224 LOG (GNUNET_ERROR_TYPE_DEBUG, " duplicate create channel\n"); 2012 GCCH_2s (ch));
2225 if (NULL != ch->dest_rel->retry_task)
2226 {
2227 LOG (GNUNET_ERROR_TYPE_DEBUG, " clearing retry task\n");
2228 /* we were waiting to re-send our 'SYNACK', wait no more! */
2229 GNUNET_SCHEDULER_cancel (ch->dest_rel->retry_task);
2230 ch->dest_rel->retry_task = NULL;
2231 }
2232 else if (NULL != ch->dest_rel->uniq)
2233 {
2234 /* we are waiting to for our 'SYNACK' to leave the queue, all done! */
2235 return ch;
2236 }
2237 }
2238 send_ack (ch, GNUNET_YES);
2239 2013
2240 return ch; 2014 /* all good, pass next message to client */
2015 GNUNET_CONTAINER_DLL_remove (ccc->head_recv,
2016 ccc->tail_recv,
2017 com);
2018 ccc->num_recv--;
2019 /* FIXME: if unreliable, this is not aggressive
2020 enough, as it would be OK to have lost some! */
2021
2022 ch->mid_recv.mid = htonl (1 + ntohl (com->mid.mid));
2023 ch->mid_futures >>= 1; /* equivalent to division by 2 */
2024 ccc->client_ready = GNUNET_NO;
2025 GSC_send_to_client (ccc->c,
2026 com->env);
2027 GNUNET_free (com);
2028 send_channel_data_ack (ch);
2029 if (NULL != ccc->head_recv)
2030 return;
2031 if (GNUNET_NO == ch->destroy)
2032 return;
2033 GCT_send_channel_destroy (ch->t,
2034 ch->ctn);
2035 channel_destroy (ch);
2241} 2036}
2242 2037
2243 2038
2244/** 2039#define LOG2(level, ...) GNUNET_log_from_nocheck(level,"cadet-chn",__VA_ARGS__)
2245 * Handler for channel NACK messages.
2246 *
2247 * NACK messages always go dest -> root, no need for 'fwd' or 'msg' parameter.
2248 *
2249 * @param ch Channel.
2250 */
2251void
2252GCCH_handle_nack (struct CadetChannel *ch)
2253{
2254 LOG (GNUNET_ERROR_TYPE_INFO,
2255 "<== %s ( 0x%08X %4u) on chan %s (%p) %s [%5u]\n",
2256 GC_m2s (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_NACK_DEPRECATED), ch->gid, 0,
2257 GCCH_2s (ch), ch, "---", 0);
2258
2259 send_client_nack (ch);
2260 GCCH_destroy (ch);
2261}
2262 2040
2263 2041
2264/** 2042/**
2265 * Handler for channel ack messages. 2043 * Log channel info.
2266 * 2044 *
2267 * @param ch Channel. 2045 * @param ch Channel.
2268 * @param msg Message. 2046 * @param level Debug level to use.
2269 * @param fwd Is this message fwd? This only is meaningful in loopback channels.
2270 * #GNUNET_YES if message is FWD on the respective channel (loopback)
2271 * #GNUNET_NO if message is BCK on the respective channel (loopback)
2272 * #GNUNET_SYSERR if message on a one-ended channel (remote)
2273 */
2274void
2275GCCH_handle_ack (struct CadetChannel *ch,
2276 const struct GNUNET_CADET_ChannelManageMessage *msg,
2277 int fwd)
2278{
2279 LOG (GNUNET_ERROR_TYPE_INFO,
2280 "<== %s ( 0x%08X %4u) on chan %s (%p) %s [%5u]\n",
2281 GC_m2s (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK), ch->gid, 0,
2282 GCCH_2s (ch), ch, GC_f2s (fwd), ntohs (msg->header.size));
2283
2284 /* If this is a remote (non-loopback) channel, find 'fwd'. */
2285 if (GNUNET_SYSERR == fwd)
2286 {
2287 if (is_loopback (ch))
2288 {
2289 /* It is a loopback channel after all... */
2290 GNUNET_break (0);
2291 return;
2292 }
2293 fwd = (NULL != ch->dest) ? GNUNET_YES : GNUNET_NO;
2294 }
2295
2296 channel_confirm (ch, !fwd);
2297}
2298
2299
2300/**
2301 * Handler for channel destroy messages.
2302 *
2303 * @param ch Channel to be destroyed of.
2304 * @param msg Message.
2305 * @param fwd Is this message fwd? This only is meaningful in loopback channels.
2306 * #GNUNET_YES if message is FWD on the respective channel (loopback)
2307 * #GNUNET_NO if message is BCK on the respective channel (loopback)
2308 * #GNUNET_SYSERR if message on a one-ended channel (remote)
2309 */ 2047 */
2310void 2048void
2311GCCH_handle_destroy (struct CadetChannel *ch, 2049GCCH_debug (struct CadetChannel *ch,
2312 const struct GNUNET_CADET_ChannelManageMessage *msg, 2050 enum GNUNET_ErrorType level)
2313 int fwd)
2314{ 2051{
2315 struct CadetChannelReliability *rel; 2052 int do_log;
2316
2317 LOG (GNUNET_ERROR_TYPE_INFO,
2318 "<== %s ( 0x%08X %4u) on chan %s (%p) %s [%5u]\n",
2319 GC_m2s (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY), ch->gid, 0,
2320 GCCH_2s (ch), ch, GC_f2s (fwd), ntohs (msg->header.size));
2321
2322 /* If this is a remote (non-loopback) channel, find 'fwd'. */
2323 if (GNUNET_SYSERR == fwd)
2324 {
2325 if (is_loopback (ch))
2326 {
2327 /* It is a loopback channel after all... */
2328 GNUNET_break (0);
2329 return;
2330 }
2331 fwd = (NULL != ch->dest) ? GNUNET_YES : GNUNET_NO;
2332 }
2333 2053
2334 GCCH_debug (ch, GNUNET_ERROR_TYPE_DEBUG); 2054 do_log = GNUNET_get_log_call_status (level & (~GNUNET_ERROR_TYPE_BULK),
2335 if ( (fwd && NULL == ch->dest) || (!fwd && NULL == ch->root) ) 2055 "cadet-chn",
2336 { 2056 __FILE__, __FUNCTION__, __LINE__);
2337 /* Not for us (don't destroy twice a half-open loopback channel) */ 2057 if (0 == do_log)
2338 return; 2058 return;
2339 }
2340
2341 rel = fwd ? ch->dest_rel : ch->root_rel;
2342 if (0 == rel->n_recv)
2343 {
2344 send_destroy (ch, GNUNET_YES);
2345 GCCH_destroy (ch);
2346 }
2347 else
2348 {
2349 ch->destroy = GNUNET_YES;
2350 }
2351}
2352
2353
2354/**
2355 * Sends an already built message on a channel.
2356 *
2357 * If the channel is on a loopback tunnel, notifies the appropriate destination
2358 * client locally.
2359 *
2360 * On a normal channel passes the message to the tunnel for encryption and
2361 * sending on a connection.
2362 *
2363 * This function DOES NOT save the message for retransmission.
2364 *
2365 * @param message Message to send. Function makes a copy of it.
2366 * @param ch Channel on which this message is transmitted.
2367 * @param fwd Is this a fwd message?
2368 * @param existing_copy This is a retransmission, don't save a copy.
2369 */
2370void
2371GCCH_send_prebuilt_message (const struct GNUNET_MessageHeader *message,
2372 struct CadetChannel *ch, int fwd,
2373 void *existing_copy)
2374{
2375 struct CadetChannelQueue *chq;
2376 uint32_t data_id;
2377 uint16_t type;
2378 uint16_t size;
2379 char info[32];
2380
2381 type = ntohs (message->type);
2382 size = ntohs (message->size);
2383
2384 data_id = 0;
2385 switch (type)
2386 {
2387 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA:
2388 {
2389 struct GNUNET_CADET_ChannelAppDataMessage *data_msg;
2390 struct GNUNET_MessageHeader *payload_msg;
2391 uint16_t payload_type;
2392
2393 data_msg = (struct GNUNET_CADET_ChannelAppDataMessage *) message;
2394 data_id = ntohl (data_msg->mid);
2395 payload_msg = (struct GNUNET_MessageHeader *) &data_msg[1];
2396 payload_type = ntohs (payload_msg->type);
2397 strncpy (info, GC_m2s (payload_type), 31);
2398 info[31] = '\0';
2399 break;
2400 }
2401 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK:
2402 {
2403 struct GNUNET_CADET_ChannelDataAckMessage *ack_msg;
2404 ack_msg = (struct GNUNET_CADET_ChannelDataAckMessage *) message;
2405 data_id = ntohl (ack_msg->mid);
2406 SPRINTF (info, "0x%010lX",
2407 (unsigned long int) ack_msg->futures);
2408 break;
2409 }
2410 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN:
2411 {
2412 struct GNUNET_CADET_ChannelOpenMessage *cc_msg;
2413 cc_msg = (struct GNUNET_CADET_ChannelOpenMessage *) message;
2414 SPRINTF (info, " 0x%08X", ntohl (cc_msg->ctn.cn));
2415 break;
2416 }
2417 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK:
2418 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_NACK_DEPRECATED:
2419 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY:
2420 {
2421 struct GNUNET_CADET_ChannelManageMessage *m_msg;
2422 m_msg = (struct GNUNET_CADET_ChannelManageMessage *) message;
2423 SPRINTF (info, " 0x%08X", ntohl (m_msg->ctn.cn));
2424 break;
2425 }
2426 default:
2427 info[0] = '\0';
2428 }
2429 LOG (GNUNET_ERROR_TYPE_INFO,
2430 "==> %s (%12s %4u) on chan %s (%p) %s [%5u]\n",
2431 GC_m2s (type), info, data_id,
2432 GCCH_2s (ch), ch, GC_f2s (fwd), size);
2433 2059
2434 if (GCT_is_loopback (ch->t)) 2060 if (NULL == ch)
2435 { 2061 {
2436 handle_loopback (ch, message, fwd); 2062 LOG2 (level, "CHN *** DEBUG NULL CHANNEL ***\n");
2437 return; 2063 return;
2438 } 2064 }
2439 2065 LOG2 (level,
2440 switch (type) 2066 "CHN %s:%X (%p)\n",
2067 GCT_2s (ch->t),
2068 ch->ctn,
2069 ch);
2070 if (NULL != ch->owner)
2441 { 2071 {
2442 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA: 2072 LOG2 (level,
2443 if (GNUNET_YES == ch->reliable) 2073 "CHN origin %s ready %s local-id: %u\n",
2444 { 2074 GSC_2s (ch->owner->c),
2445 chq = GNUNET_new (struct CadetChannelQueue); 2075 ch->owner->client_ready ? "YES" : "NO",
2446 chq->type = type; 2076 ntohl (ch->owner->ccn.channel_of_client));
2447 if (NULL == existing_copy)
2448 chq->copy = channel_save_copy (ch, message, fwd);
2449 else
2450 {
2451 chq->copy = (struct CadetReliableMessage *) existing_copy;
2452 if (NULL != chq->copy->chq)
2453 {
2454 /* Last retransmission was queued but not yet sent!
2455 * This retransmission was scheduled by a ch_message_sent which
2456 * followed a very fast RTT, so the tiny delay made the
2457 * retransmission function to execute before the previous
2458 * retransmitted message even had a chance to leave the peer.
2459 * Cancel this message and wait until the pending
2460 * retransmission leaves the peer and ch_message_sent starts
2461 * the timer for the next one.
2462 */
2463 GNUNET_free (chq);
2464 LOG (GNUNET_ERROR_TYPE_DEBUG,
2465 " exisitng copy not yet transmitted!\n");
2466 return;
2467 }
2468 LOG (GNUNET_ERROR_TYPE_DEBUG,
2469 " using existing copy: %p {r:%p q:%p t:%u}\n",
2470 existing_copy,
2471 chq->copy->rel, chq->copy->chq, chq->copy->type);
2472 }
2473 LOG (GNUNET_ERROR_TYPE_DEBUG, " new chq: %p\n", chq);
2474 chq->copy->chq = chq;
2475 chq->tq = GCT_send_prebuilt_message (message, ch->t, NULL,
2476 GNUNET_YES,
2477 &ch_message_sent, chq);
2478 /* q itself is stored in copy */
2479 GNUNET_assert (NULL != chq->tq || GNUNET_NO != ch->destroy);
2480 }
2481 else
2482 {
2483 fire_and_forget (message, ch, GNUNET_NO);
2484 }
2485 break;
2486
2487
2488 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK:
2489 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN:
2490 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK:
2491 chq = GNUNET_new (struct CadetChannelQueue);
2492 chq->type = type;
2493 chq->rel = fwd ? ch->root_rel : ch->dest_rel;
2494 if (NULL != chq->rel->uniq)
2495 {
2496 if (NULL != chq->rel->uniq->tq)
2497 {
2498 GCT_cancel (chq->rel->uniq->tq);
2499 /* ch_message_sent is called, freeing and NULLing uniq */
2500 GNUNET_break (NULL == chq->rel->uniq);
2501 }
2502 else
2503 {
2504 GNUNET_break (0);
2505 GNUNET_free (chq->rel->uniq);
2506 }
2507 }
2508
2509 chq->rel->uniq = chq;
2510 chq->tq = GCT_send_prebuilt_message (message, ch->t, NULL, GNUNET_YES,
2511 &ch_message_sent, chq);
2512 if (NULL == chq->tq)
2513 {
2514 GNUNET_break (0);
2515 chq->rel->uniq = NULL;
2516 GCT_debug (ch->t, GNUNET_ERROR_TYPE_ERROR);
2517 GNUNET_free (chq);
2518 chq = NULL;
2519 return;
2520 }
2521 break;
2522
2523
2524 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY:
2525 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_NACK_DEPRECATED:
2526 fire_and_forget (message, ch, GNUNET_YES);
2527 break;
2528
2529
2530 default:
2531 GNUNET_break (0);
2532 LOG (GNUNET_ERROR_TYPE_WARNING, "type %s unknown!\n", GC_m2s (type));
2533 fire_and_forget (message, ch, GNUNET_YES);
2534 } 2077 }
2078 if (NULL != ch->dest)
2079 {
2080 LOG2 (level,
2081 "CHN destination %s ready %s local-id: %u\n",
2082 GSC_2s (ch->dest->c),
2083 ch->dest->client_ready ? "YES" : "NO",
2084 ntohl (ch->dest->ccn.channel_of_client));
2085 }
2086 LOG2 (level,
2087 "CHN Message IDs recv: %d (%LLX), send: %d\n",
2088 ntohl (ch->mid_recv.mid),
2089 (unsigned long long) ch->mid_futures,
2090 ntohl (ch->mid_send.mid));
2535} 2091}
2536 2092
2537 2093
2538/**
2539 * Get the static string for identification of the channel.
2540 *
2541 * @param ch Channel.
2542 *
2543 * @return Static string with the channel IDs.
2544 */
2545const char *
2546GCCH_2s (const struct CadetChannel *ch)
2547{
2548 static char buf[64];
2549
2550 if (NULL == ch)
2551 return "(NULL Channel)";
2552 2094
2553 SPRINTF (buf, 2095/* end of gnunet-service-cadet-new_channel.c */
2554 "%s:%s gid:%X (%X / %X)",
2555 GCT_2s (ch->t),
2556 GNUNET_h2s (&ch->port),
2557 ntohl (ch->gid.cn),
2558 ntohl (ch->lid_root.channel_of_client),
2559 ntohl (ch->lid_dest.channel_of_client));
2560
2561 return buf;
2562}
diff --git a/src/cadet/gnunet-service-cadet_channel.h b/src/cadet/gnunet-service-cadet_channel.h
index 9d4893269..16517c457 100644
--- a/src/cadet/gnunet-service-cadet_channel.h
+++ b/src/cadet/gnunet-service-cadet_channel.h
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2013 GNUnet e.V. 3 Copyright (C) 2001-2017 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -20,344 +20,261 @@
20 20
21/** 21/**
22 * @file cadet/gnunet-service-cadet_channel.h 22 * @file cadet/gnunet-service-cadet_channel.h
23 * @brief cadet service; dealing with end-to-end channels 23 * @brief GNUnet CADET service with encryption
24 * @author Bartlomiej Polot 24 * @author Bartlomiej Polot
25 * 25 * @author Christian Grothoff
26 * All functions in this file should use the prefix GMCH (Gnunet Cadet CHannel)
27 */ 26 */
28
29#ifndef GNUNET_SERVICE_CADET_CHANNEL_H 27#ifndef GNUNET_SERVICE_CADET_CHANNEL_H
30#define GNUNET_SERVICE_CADET_CHANNEL_H 28#define GNUNET_SERVICE_CADET_CHANNEL_H
31 29
32#ifdef __cplusplus 30#include "gnunet-service-cadet.h"
33extern "C" 31#include "gnunet-service-cadet_peer.h"
34{
35#if 0 /* keep Emacsens' auto-indent happy */
36}
37#endif
38#endif
39
40#include "platform.h"
41#include "gnunet_util_lib.h"
42
43#include "cadet_protocol.h" 32#include "cadet_protocol.h"
44#include "cadet.h" 33
45 34
46/** 35/**
47 * Struct containing all information regarding a channel to a remote client. 36 * A channel is a bidirectional connection between two CADET
37 * clients. Communiation can be reliable, unreliable, in-order
38 * or out-of-order. One client is the "local" client, this
39 * one initiated the connection. The other client is the
40 * "incoming" client, this one listened on a port to accept
41 * the connection from the "local" client.
48 */ 42 */
49struct CadetChannel; 43struct CadetChannel;
50 44
51 45
52#include "gnunet-service-cadet_tunnel.h"
53#include "gnunet-service-cadet_local.h"
54
55
56/** 46/**
57 * Destroy a channel and free all resources. 47 * Hash the @a port and @a initiator and @a listener to
48 * calculate the "challenge" @a h_port we send to the other
49 * peer on #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN.
58 * 50 *
59 * @param ch Channel to destroy. 51 * @param[out] h_port set to the hash of @a port, @a initiator and @a listener
52 * @param port cadet port, as seen by CADET clients
53 * @param listener peer that is listining on @a port
60 */ 54 */
61void 55void
62GCCH_destroy (struct CadetChannel *ch); 56GCCH_hash_port (struct GNUNET_HashCode *h_port,
57 const struct GNUNET_HashCode *port,
58 const struct GNUNET_PeerIdentity *listener);
63 59
64 60
65/** 61/**
66 * Get the channel's public ID. 62 * Get the static string for identification of the channel.
67 * 63 *
68 * @param ch Channel. 64 * @param ch Channel.
69 * 65 *
70 * @return ID used to identify the channel with the remote peer. 66 * @return Static string with the channel IDs.
71 */
72struct GNUNET_CADET_ChannelTunnelNumber
73GCCH_get_id (const struct CadetChannel *ch);
74
75
76/**
77 * Get the channel tunnel.
78 *
79 * @param ch Channel to get the tunnel from.
80 *
81 * @return tunnel of the channel.
82 */ 67 */
83struct CadetTunnel * 68const char *
84GCCH_get_tunnel (const struct CadetChannel *ch); 69GCCH_2s (const struct CadetChannel *ch);
85 70
86 71
87/** 72/**
88 * Get free buffer space towards the client on a specific channel. 73 * Log channel info.
89 * 74 *
90 * @param ch Channel. 75 * @param ch Channel.
91 * @param fwd Is query about FWD traffic? 76 * @param level Debug level to use.
92 *
93 * @return Free buffer space [0 - 64]
94 */ 77 */
95unsigned int 78void
96GCCH_get_buffer (struct CadetChannel *ch, int fwd); 79GCCH_debug (struct CadetChannel *ch,
80 enum GNUNET_ErrorType level);
97 81
98 82
99/** 83/**
100 * Get flow control status of end point: is client allow to send? 84 * Get the channel's public ID.
101 * 85 *
102 * @param ch Channel. 86 * @param ch Channel.
103 * @param fwd Is query about FWD traffic? (Request root status).
104 * 87 *
105 * @return #GNUNET_YES if client is allowed to send us data. 88 * @return ID used to identify the channel with the remote peer.
106 */ 89 */
107int 90struct GNUNET_CADET_ChannelTunnelNumber
108GCCH_get_allowed (struct CadetChannel *ch, int fwd); 91GCCH_get_id (const struct CadetChannel *ch);
109 92
110 93
111/** 94/**
112 * Is the root client for this channel on this peer? 95 * Create a new channel.
113 * 96 *
114 * @param ch Channel. 97 * @param owner local client owning the channel
115 * @param fwd Is this for fwd traffic? 98 * @param owner_id local chid of this channel at the @a owner
116 * 99 * @param destination peer to which we should build the channel
117 * @return #GNUNET_YES in case it is. 100 * @param port desired port at @a destination
101 * @param options options for the channel
102 * @return handle to the new channel
118 */ 103 */
119int 104struct CadetChannel *
120GCCH_is_origin (struct CadetChannel *ch, int fwd); 105GCCH_channel_local_new (struct CadetClient *owner,
106 struct GNUNET_CADET_ClientChannelNumber owner_id,
107 struct CadetPeer *destination,
108 const struct GNUNET_HashCode *port,
109 uint32_t options);
121 110
122/**
123 * Is the destination client for this channel on this peer?
124 *
125 * @param ch Channel.
126 * @param fwd Is this for fwd traffic?
127 *
128 * @return #GNUNET_YES in case it is.
129 */
130int
131GCCH_is_terminal (struct CadetChannel *ch, int fwd);
132 111
133/** 112/**
134 * Send an end-to-end ACK message for the most recent in-sequence payload. 113 * A client is bound to the port that we have a channel
135 * 114 * open to. Send the acknowledgement for the connection
136 * If channel is not reliable, do nothing. 115 * request and establish the link with the client.
137 * 116 *
138 * @param ch Channel this is about. 117 * @param ch open incoming channel
139 * @param fwd Is for FWD traffic? (ACK dest->owner) 118 * @param c client listening on the respective @a port
119 * @param port port number @a c is listening on
140 */ 120 */
141void 121void
142GCCH_send_data_ack (struct CadetChannel *ch, int fwd); 122GCCH_bind (struct CadetChannel *ch,
123 struct CadetClient *c,
124 const struct GNUNET_HashCode *port);
143 125
144/**
145 * Notify the destination client that a new incoming channel was created.
146 *
147 * @param ch Channel that was created.
148 */
149void
150GCCH_send_create (struct CadetChannel *ch);
151 126
152/** 127/**
153 * Allow a client to send us more data, in case it was choked. 128 * Destroy locally created channel. Called by the
129 * local client, so no need to tell the client.
154 * 130 *
155 * @param ch Channel. 131 * @param ch channel to destroy
156 * @param fwd Is this about FWD traffic? (Root client). 132 * @param c client that caused the destruction
133 * @param ccn client number of the client @a c
157 */ 134 */
158void 135void
159GCCH_allow_client (struct CadetChannel *ch, int fwd); 136GCCH_channel_local_destroy (struct CadetChannel *ch,
137 struct CadetClient *c,
138 struct GNUNET_CADET_ClientChannelNumber ccn);
160 139
161/**
162 * Log channel info.
163 *
164 * @param ch Channel.
165 * @param level Debug level to use.
166 */
167void
168GCCH_debug (struct CadetChannel *ch, enum GNUNET_ErrorType level);
169 140
170/** 141/**
171 * Handle an ACK given by a client. 142 * Function called once and only once after a channel was bound
172 * 143 * to its tunnel via #GCT_add_channel() is ready for transmission.
173 * Mark client as ready and send him any buffered data we could have for him. 144 * Note that this is only the case for channels that this peer
174 * 145 * initiates, as for incoming channels we assume that they are
175 * @param ch Channel. 146 * ready for transmission immediately upon receiving the open
176 * @param fwd Is this a "FWD ACK"? (FWD ACKs are sent by root and go BCK) 147 * message. Used to bootstrap the #GCT_send() process.
177 */ 148 *
178void 149 * @param ch the channel for which the tunnel is now ready
179GCCH_handle_local_ack (struct CadetChannel *ch, int fwd);
180
181/**
182 * Handle data given by a client.
183 *
184 * Check whether the client is allowed to send in this tunnel, save if channel
185 * is reliable and send an ACK to the client if there is still buffer space
186 * in the tunnel.
187 *
188 * @param ch Channel.
189 * @param c Client which sent the data.
190 * @param fwd Is this a FWD data?
191 * @param message Data message.
192 * @param size Size of data.
193 *
194 * @return GNUNET_OK if everything goes well, GNUNET_SYSERR in case of en error.
195 */
196int
197GCCH_handle_local_data (struct CadetChannel *ch,
198 struct CadetClient *c, int fwd,
199 const struct GNUNET_MessageHeader *message,
200 size_t size);
201
202/**
203 * Handle a channel destroy requested by a client.
204 *
205 * Destroy the channel and the tunnel in case this was the last channel.
206 *
207 * @param ch Channel.
208 * @param c Client that requested the destruction (to avoid notifying him).
209 * @param is_root Is the request coming from root?
210 */ 150 */
211void 151void
212GCCH_handle_local_destroy (struct CadetChannel *ch, 152GCCH_tunnel_up (struct CadetChannel *ch);
213 struct CadetClient *c,
214 int is_root);
215
216 153
217/**
218 * Handle a channel create requested by a client.
219 *
220 * Create the channel and the tunnel in case this was the first0 channel.
221 *
222 * @param c Client that requested the creation (will be the root).
223 * @param msg Create Channel message.
224 *
225 * @return #GNUNET_OK if everything went fine, #GNUNET_SYSERR otherwise.
226 */
227int
228GCCH_handle_local_create (struct CadetClient *c,
229 struct GNUNET_CADET_LocalChannelCreateMessage *msg);
230 154
231/** 155/**
232 * Handler for cadet network payload traffic. 156 * Create a new channel based on a request coming in over the network.
233 * 157 *
234 * @param ch Channel for the message. 158 * @param t tunnel to the remote peer
235 * @param msg Unencryted data message. 159 * @param chid identifier of this channel in the tunnel
236 * @param fwd Is this message fwd? This only is meaningful in loopback channels. 160 * @param origin peer to who initiated the channel
237 * #GNUNET_YES if message is FWD on the respective channel (loopback) 161 * @param h_port hash of desired local port
238 * #GNUNET_NO if message is BCK on the respective channel (loopback) 162 * @param options options for the channel
239 * #GNUNET_SYSERR if message on a one-ended channel (remote) 163 * @return handle to the new channel
240 */ 164 */
241void 165struct CadetChannel *
242GCCH_handle_data (struct CadetChannel *ch, 166GCCH_channel_incoming_new (struct CadetTunnel *t,
243 const struct GNUNET_CADET_ChannelAppDataMessage *msg, 167 struct GNUNET_CADET_ChannelTunnelNumber chid,
244 int fwd); 168 const struct GNUNET_HashCode *h_port,
169 uint32_t options);
245 170
246 171
247/** 172/**
248 * Handler for cadet network traffic end-to-end ACKs. 173 * We got a #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN message again for
174 * this channel. If the binding was successful, (re)transmit the
175 * #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK.
249 * 176 *
250 * @param ch Channel on which we got this message. 177 * @param ch channel that got the duplicate open
251 * @param msg Data message. 178 * @param cti identifier of the connection that delivered the message
252 * @param fwd Is this message fwd? This only is meaningful in loopback channels.
253 * #GNUNET_YES if message is FWD on the respective channel (loopback)
254 * #GNUNET_NO if message is BCK on the respective channel (loopback)
255 * #GNUNET_SYSERR if message on a one-ended channel (remote)
256 */ 179 */
257void 180void
258GCCH_handle_data_ack (struct CadetChannel *ch, 181GCCH_handle_duplicate_open (struct CadetChannel *ch,
259 const struct GNUNET_CADET_ChannelDataAckMessage *msg, 182 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti);
260 int fwd);
261 183
262 184
263/**
264 * Handler for channel create messages.
265 *
266 * Does not have fwd parameter because it's always 'FWD': channel is incoming.
267 *
268 * @param t Tunnel this channel will be in.
269 * @param msg Channel crate message.
270 */
271struct CadetChannel *
272GCCH_handle_create (struct CadetTunnel *t,
273 const struct GNUNET_CADET_ChannelOpenMessage *msg);
274
275 185
276/** 186/**
277 * Handler for channel NACK messages. 187 * We got payload data for a channel. Pass it on to the client.
278 *
279 * NACK messages always go dest -> root, no need for 'fwd' or 'msg' parameter.
280 * 188 *
281 * @param ch Channel. 189 * @param ch channel that got data
190 * @param cti identifier of the connection that delivered the message
191 * @param msg message that was received
282 */ 192 */
283void 193void
284GCCH_handle_nack (struct CadetChannel *ch); 194GCCH_handle_channel_plaintext_data (struct CadetChannel *ch,
195 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti,
196 const struct GNUNET_CADET_ChannelAppDataMessage *msg);
285 197
286 198
287/** 199/**
288 * Handler for channel ack messages. 200 * We got an acknowledgement for payload data for a channel.
201 * Possibly resume transmissions.
289 * 202 *
290 * @param ch Channel this channel is to be created in. 203 * @param ch channel that got the ack
291 * @param msg Message. 204 * @param cti identifier of the connection that delivered the message
292 * @param fwd Is this message fwd? This only is meaningful in loopback channels. 205 * @param ack details about what was received
293 * #GNUNET_YES if message is FWD on the respective channel (loopback)
294 * #GNUNET_NO if message is BCK on the respective channel (loopback)
295 * #GNUNET_SYSERR if message on a one-ended channel (remote)
296 */ 206 */
297void 207void
298GCCH_handle_ack (struct CadetChannel *ch, 208GCCH_handle_channel_plaintext_data_ack (struct CadetChannel *ch,
299 const struct GNUNET_CADET_ChannelManageMessage *msg, 209 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti,
300 int fwd); 210 const struct GNUNET_CADET_ChannelDataAckMessage *ack);
301 211
302 212
303/** 213/**
304 * Handler for channel destroy messages. 214 * We got an acknowledgement for the creation of the channel
215 * (the port is open on the other side). Begin transmissions.
305 * 216 *
306 * @param ch Channel this channel is to be destroyed of. 217 * @param ch channel to destroy
307 * @param msg Message. 218 * @param cti identifier of the connection that delivered the message,
308 * @param fwd Is this message fwd? This only is meaningful in loopback channels. 219 * NULL if the ACK was inferred because we got payload or are on loopback
309 * #GNUNET_YES if message is FWD on the respective channel (loopback) 220 * @param port port number (needed to verify receiver knows the port)
310 * #GNUNET_NO if message is BCK on the respective channel (loopback)
311 * #GNUNET_SYSERR if message on a one-ended channel (remote)
312 */ 221 */
313void 222void
314GCCH_handle_destroy (struct CadetChannel *ch, 223GCCH_handle_channel_open_ack (struct CadetChannel *ch,
315 const struct GNUNET_CADET_ChannelManageMessage *msg, 224 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti,
316 int fwd); 225 const struct GNUNET_HashCode *port);
317 226
318 227
319/** 228/**
320 * Sends an already built message on a channel. 229 * Destroy channel, based on the other peer closing the
321 * 230 * connection. Also needs to remove this channel from
322 * If the channel is on a loopback tunnel, notifies the appropriate destination 231 * the tunnel.
323 * client locally.
324 * 232 *
325 * On a normal channel passes the message to the tunnel for encryption and 233 * FIXME: need to make it possible to defer destruction until we have
326 * sending on a connection. 234 * received all messages up to the destroy, and right now the destroy
235 * message (and this API) fails to give is the information we need!
327 * 236 *
328 * This function DOES NOT save the message for retransmission. 237 * FIXME: also need to know if the other peer got a destroy from
238 * us before!
329 * 239 *
330 * @param message Message to send. Function makes a copy of it. 240 * @param ch channel to destroy
331 * @param ch Channel on which this message is transmitted. 241 * @param cti identifier of the connection that delivered the message,
332 * @param fwd Is this a fwd message? 242 * NULL during shutdown
333 * @param existing_copy This is a retransmission, don't save a copy.
334 */ 243 */
335void 244void
336GCCH_send_prebuilt_message (const struct GNUNET_MessageHeader *message, 245GCCH_handle_remote_destroy (struct CadetChannel *ch,
337 struct CadetChannel *ch, int fwd, 246 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti);
338 void *existing_copy);
339 247
340 248
341/** 249/**
342 * Get the static string for identification of the channel. 250 * Handle data given by a client.
343 * 251 *
344 * @param ch Channel.i 252 * Check whether the client is allowed to send in this tunnel, save if
253 * channel is reliable and send an ACK to the client if there is still
254 * buffer space in the tunnel.
345 * 255 *
346 * @return Static string with the channel IDs. 256 * @param ch Channel.
257 * @param sender_ccn ccn of the sender
258 * @param buf payload to transmit.
259 * @param buf_len number of bytes in @a buf
260 * @return #GNUNET_OK if everything goes well,
261 * #GNUNET_SYSERR in case of an error.
347 */ 262 */
348const char * 263int
349GCCH_2s (const struct CadetChannel *ch); 264GCCH_handle_local_data (struct CadetChannel *ch,
350 265 struct GNUNET_CADET_ClientChannelNumber sender_ccn,
351 266 const char *buf,
267 size_t buf_len);
352 268
353 269
354#if 0 /* keep Emacsens' auto-indent happy */ 270/**
355{ 271 * Handle ACK from client on local channel.
356#endif 272 *
357#ifdef __cplusplus 273 * @param ch channel to destroy
358} 274 * @param client_ccn ccn of the client sending the ack
359#endif 275 */
276void
277GCCH_handle_local_ack (struct CadetChannel *ch,
278 struct GNUNET_CADET_ClientChannelNumber client_ccn);
360 279
361/* ifndef GNUNET_SERVICE_CADET_CHANNEL_H */
362#endif 280#endif
363/* end of gnunet-service-cadet_channel.h */
diff --git a/src/cadet/gnunet-service-cadet_connection.c b/src/cadet/gnunet-service-cadet_connection.c
index af27647b3..7b66f61a2 100644
--- a/src/cadet/gnunet-service-cadet_connection.c
+++ b/src/cadet/gnunet-service-cadet_connection.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2001-2015 GNUnet e.V. 3 Copyright (C) 2001-2017 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -17,242 +17,126 @@
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA. 18 Boston, MA 02110-1301, USA.
19*/ 19*/
20
20/** 21/**
21 * @file cadet/gnunet-service-cadet_connection.c 22 * @file cadet/gnunet-service-cadet_connection.c
22 * @brief GNUnet CADET service connection handling 23 * @brief management of CORE-level end-to-end connections; establishes
24 * end-to-end routes and transmits messages along the route
23 * @author Bartlomiej Polot 25 * @author Bartlomiej Polot
26 * @author Christian Grothoff
24 */ 27 */
25#include "platform.h" 28#include "platform.h"
26#include "gnunet_util_lib.h" 29#include "gnunet-service-cadet_connection.h"
30#include "gnunet-service-cadet_channel.h"
31#include "gnunet-service-cadet_paths.h"
32#include "gnunet-service-cadet_tunnels.h"
33#include "gnunet_cadet_service.h"
27#include "gnunet_statistics_service.h" 34#include "gnunet_statistics_service.h"
28#include "cadet_path.h"
29#include "cadet_protocol.h" 35#include "cadet_protocol.h"
30#include "cadet.h"
31#include "gnunet-service-cadet_connection.h"
32#include "gnunet-service-cadet_peer.h"
33#include "gnunet-service-cadet_tunnel.h"
34
35
36/**
37 * Should we run somewhat expensive checks on our invariants?
38 */
39#define CHECK_INVARIANTS 0
40
41
42#define LOG(level, ...) GNUNET_log_from (level,"cadet-con",__VA_ARGS__)
43#define LOG2(level, ...) GNUNET_log_from_nocheck(level,"cadet-con",__VA_ARGS__)
44
45
46#define CADET_MAX_POLL_TIME GNUNET_TIME_relative_multiply (\
47 GNUNET_TIME_UNIT_MINUTES,\
48 10)
49#define AVG_MSGS 32
50
51
52/******************************************************************************/
53/******************************** STRUCTS **********************************/
54/******************************************************************************/
55
56/**
57 * Handle for messages queued but not yet sent.
58 */
59struct CadetConnectionQueue
60{
61 36
62 struct CadetConnectionQueue *next;
63 struct CadetConnectionQueue *prev;
64 37
65 /** 38#define LOG(level, ...) GNUNET_log_from(level,"cadet-con",__VA_ARGS__)
66 * Peer queue handle, to cancel if necessary.
67 */
68 struct CadetPeerQueue *peer_q;
69
70 /**
71 * Continuation to call once sent.
72 */
73 GCC_sent cont;
74
75 /**
76 * Closure for @e cont.
77 */
78 void *cont_cls;
79
80 /**
81 * Was this a forced message? (Do not account for it)
82 */
83 int forced;
84};
85 39
86 40
87/** 41/**
88 * Struct to encapsulate all the Flow Control information to a peer to which 42 * All the states a connection can be in.
89 * we are directly connected (on a core level).
90 */ 43 */
91struct CadetFlowControl 44enum CadetConnectionState
92{ 45{
93 /** 46 /**
94 * Connection this controls. 47 * Uninitialized status, we have not yet even gotten the message queue.
95 */
96 struct CadetConnection *c;
97
98 struct CadetConnectionQueue *q_head;
99 struct CadetConnectionQueue *q_tail;
100
101 /**
102 * How many messages are in the queue on this connection.
103 */
104 unsigned int queue_n;
105
106 /**
107 * How many messages do we accept in the queue.
108 * If 0, the connection is broken in this direction (next hop disconnected).
109 */
110 unsigned int queue_max;
111
112 /**
113 * ID of the next packet to send.
114 */
115 struct CadetEncryptedMessageIdentifier next_pid;
116
117 /**
118 * ID of the last packet sent towards the peer.
119 */
120 struct CadetEncryptedMessageIdentifier last_pid_sent;
121
122 /**
123 * ID of the last packet received from the peer.
124 */
125 struct CadetEncryptedMessageIdentifier last_pid_recv;
126
127 /**
128 * Bitmap of past 32 messages received:
129 * - LSB being @c last_pid_recv.
130 * - MSB being @c last_pid_recv - 31 (mod UINTMAX).
131 */
132 uint32_t recv_bitmap;
133
134 /**
135 * Last ACK sent to the peer (peer is not allowed to send
136 * messages with PIDs higher than this value).
137 */ 48 */
138 struct CadetEncryptedMessageIdentifier last_ack_sent; 49 CADET_CONNECTION_NEW,
139 50
140 /** 51 /**
141 * Last ACK sent towards the origin (for traffic towards leaf node). 52 * Connection create message in queue, awaiting transmission by CORE.
142 */ 53 */
143 struct CadetEncryptedMessageIdentifier last_ack_recv; 54 CADET_CONNECTION_SENDING_CREATE,
144 55
145 /** 56 /**
146 * Task to poll the peer in case of a lost ACK causes stall. 57 * Connection create message sent, waiting for ACK.
147 */ 58 */
148 struct GNUNET_SCHEDULER_Task *poll_task; 59 CADET_CONNECTION_SENT,
149 60
150 /** 61 /**
151 * How frequently to poll for ACKs. 62 * We are an inbound connection, and received a CREATE. Need to
63 * send an CREATE_ACK back.
152 */ 64 */
153 struct GNUNET_TIME_Relative poll_time; 65 CADET_CONNECTION_CREATE_RECEIVED,
154 66
155 /** 67 /**
156 * Queued poll message, to cancel if not necessary anymore (got ACK). 68 * Connection confirmed, ready to carry traffic.
157 */ 69 */
158 struct CadetConnectionQueue *poll_msg; 70 CADET_CONNECTION_READY
159 71
160 /**
161 * Queued poll message, to cancel if not necessary anymore (got ACK).
162 */
163 struct CadetConnectionQueue *ack_msg;
164}; 72};
165 73
74
166/** 75/**
167 * Keep a record of the last messages sent on this connection. 76 * Low-level connection to a destination.
168 */ 77 */
169struct CadetConnectionPerformance 78struct CadetConnection
170{ 79{
171 /**
172 * Circular buffer for storing measurements.
173 */
174 double usecsperbyte[AVG_MSGS];
175 80
176 /** 81 /**
177 * Running average of @c usecsperbyte. 82 * ID of the connection.
178 */
179 double avg;
180
181 /**
182 * How many values of @c usecsperbyte are valid.
183 */
184 uint16_t size;
185
186 /**
187 * Index of the next "free" position in @c usecsperbyte.
188 */ 83 */
189 uint16_t idx; 84 struct GNUNET_CADET_ConnectionTunnelIdentifier cid;
190};
191
192 85
193/**
194 * Struct containing all information regarding a connection to a peer.
195 */
196struct CadetConnection
197{
198 /** 86 /**
199 * Tunnel this connection is part of. 87 * To which peer does this connection go?
200 */ 88 */
201 struct CadetTunnel *t; 89 struct CadetPeer *destination;
202 90
203 /** 91 /**
204 * Flow control information for traffic fwd. 92 * Which tunnel is using this connection?
205 */ 93 */
206 struct CadetFlowControl fwd_fc; 94 struct CadetTConnection *ct;
207 95
208 /** 96 /**
209 * Flow control information for traffic bck. 97 * Path we are using to our destination.
210 */ 98 */
211 struct CadetFlowControl bck_fc; 99 struct CadetPeerPath *path;
212 100
213 /** 101 /**
214 * Measure connection performance on the endpoint. 102 * Pending message, NULL if we are ready to transmit.
215 */ 103 */
216 struct CadetConnectionPerformance *perf; 104 struct GNUNET_MQ_Envelope *env;
217 105
218 /** 106 /**
219 * ID of the connection. 107 * Handle for calling #GCP_request_mq_cancel() once we are finished.
220 */ 108 */
221 struct GNUNET_CADET_ConnectionTunnelIdentifier id; 109 struct GCP_MessageQueueManager *mq_man;
222 110
223 /** 111 /**
224 * Path being used for the tunnel. At the origin of the connection 112 * Task for connection maintenance.
225 * it's a pointer to the destination's path pool, otherwise just a copy.
226 */ 113 */
227 struct CadetPeerPath *path; 114 struct GNUNET_SCHEDULER_Task *task;
228 115
229 /** 116 /**
230 * Task to keep the used paths alive at the owner, 117 * Queue entry for keepalive messages.
231 * time tunnel out on all the other peers.
232 */ 118 */
233 struct GNUNET_SCHEDULER_Task *fwd_maintenance_task; 119 struct CadetTunnelQueueEntry *keepalive_qe;
234 120
235 /** 121 /**
236 * Task to keep the used paths alive at the destination, 122 * Function to call once we are ready to transmit.
237 * time tunnel out on all the other peers.
238 */ 123 */
239 struct GNUNET_SCHEDULER_Task *bck_maintenance_task; 124 GCC_ReadyCallback ready_cb;
240 125
241 /** 126 /**
242 * Queue handle for maintainance traffic. One handle for FWD and BCK since 127 * Closure for @e ready_cb.
243 * one peer never needs to maintain both directions (no loopback connections).
244 */ 128 */
245 struct CadetPeerQueue *maintenance_q; 129 void *ready_cb_cls;
246 130
247 /** 131 /**
248 * Should equal #get_next_hop(), or NULL if that peer disconnected. 132 * How long do we wait before we try again with a CREATE message?
249 */ 133 */
250 struct CadetPeer *next_peer; 134 struct GNUNET_TIME_Relative retry_delay;
251 135
252 /** 136 /**
253 * Should equal #get_prev_hop(), or NULL if that peer disconnected. 137 * Performance metrics for this connection.
254 */ 138 */
255 struct CadetPeer *prev_peer; 139 struct CadetConnectionMetrics metrics;
256 140
257 /** 141 /**
258 * State of the connection. 142 * State of the connection.
@@ -260,221 +144,36 @@ struct CadetConnection
260 enum CadetConnectionState state; 144 enum CadetConnectionState state;
261 145
262 /** 146 /**
263 * Position of the local peer in the path. 147 * Options for the route, control buffering.
264 */ 148 */
265 unsigned int own_pos; 149 enum GNUNET_CADET_ChannelOption options;
266 150
267 /** 151 /**
268 * Pending message count. 152 * How many latency observations did we make for this connection?
269 */ 153 */
270 unsigned int pending_messages; 154 unsigned int latency_datapoints;
271 155
272 /** 156 /**
273 * Destroy flag: 157 * Offset of our @e destination in @e path.
274 * - if 0, connection in use.
275 * - if 1, destroy on last message.
276 * - if 2, connection is being destroyed don't re-enter.
277 */ 158 */
278 int destroy; 159 unsigned int off;
279 160
280 /** 161 /**
281 * In-connection-map flag. Sometimes, when @e destroy is set but 162 * Are we ready to transmit via @e mq_man right now?
282 * actual destruction is delayed to enable us to finish processing
283 * queues (i.e. in the direction that is still working), we remove
284 * the connection from the map to prevent it from still being
285 * found (and used) by accident. This flag is set to #GNUNET_YES
286 * for a connection that is not in the #connections map. Should
287 * only be #GNUNET_YES if #destroy is also non-zero.
288 */ 163 */
289 int was_removed; 164 int mqm_ready;
290 165
291 /**
292 * Counter to do exponential backoff when creating a connection (max 64).
293 */
294 unsigned short create_retry;
295
296 /**
297 * Task to check if connection has duplicates.
298 */
299 struct GNUNET_SCHEDULER_Task *check_duplicates_task;
300}; 166};
301 167
302 168
303/******************************************************************************/
304/******************************* GLOBALS ***********************************/
305/******************************************************************************/
306
307/**
308 * Global handle to the statistics service.
309 */
310extern struct GNUNET_STATISTICS_Handle *stats;
311
312/**
313 * Local peer own ID (memory efficient handle).
314 */
315extern GNUNET_PEER_Id myid;
316
317/**
318 * Local peer own ID (full value).
319 */
320extern struct GNUNET_PeerIdentity my_full_id;
321
322/**
323 * Connections known, indexed by cid (CadetConnection).
324 */
325static struct GNUNET_CONTAINER_MultiShortmap *connections;
326
327/**
328 * How many connections are we willing to maintain.
329 * Local connections are always allowed,
330 * even if there are more connections than max.
331 */
332static unsigned long long max_connections;
333
334/**
335 * How many messages *in total* are we willing to queue, divide by number of
336 * connections to get connection queue size.
337 */
338static unsigned long long max_msgs_queue;
339
340/**
341 * How often to send path keepalives. Paths timeout after 4 missed.
342 */
343static struct GNUNET_TIME_Relative refresh_connection_time;
344
345/**
346 * How often to send path create / ACKs.
347 */
348static struct GNUNET_TIME_Relative create_connection_time;
349
350
351/******************************************************************************/
352/******************************** STATIC ***********************************/
353/******************************************************************************/
354
355
356
357#if 0 // avoid compiler warning for unused static function
358static void
359fc_debug (struct CadetFlowControl *fc)
360{
361 LOG (GNUNET_ERROR_TYPE_DEBUG, " IN: %u/%u\n",
362 ntohl (fc->last_pid_recv.pid),
363 ntohl (fc->last_ack_sent.pid));
364 LOG (GNUNET_ERROR_TYPE_DEBUG, " OUT: %u/%u\n",
365 fc->last_pid_sent, fc->last_ack_recv);
366 LOG (GNUNET_ERROR_TYPE_DEBUG, " QUEUE: %u/%u\n",
367 fc->queue_n, fc->queue_max);
368}
369
370static void
371connection_debug (struct CadetConnection *c)
372{
373 if (NULL == c)
374 {
375 LOG (GNUNET_ERROR_TYPE_INFO, "DEBUG NULL CONNECTION\n");
376 return;
377 }
378 LOG (GNUNET_ERROR_TYPE_DEBUG, "Connection %s:%X\n",
379 peer2s (c->t->peer), GCC_2s (c));
380 LOG (GNUNET_ERROR_TYPE_DEBUG, " state: %u, pending msgs: %u\n",
381 c->state, c->pending_messages);
382 LOG (GNUNET_ERROR_TYPE_DEBUG, " FWD FC\n");
383 fc_debug (&c->fwd_fc);
384 LOG (GNUNET_ERROR_TYPE_DEBUG, " BCK FC\n");
385 fc_debug (&c->bck_fc);
386}
387#endif
388
389
390/**
391 * Schedule next keepalive task, taking in consideration
392 * the connection state and number of retries.
393 *
394 * @param c Connection for which to schedule the next keepalive.
395 * @param fwd Direction for the next keepalive.
396 */
397static void
398schedule_next_keepalive (struct CadetConnection *c, int fwd);
399
400
401/**
402 * Resets the connection timeout task, some other message has done the
403 * task's job.
404 * - For the first peer on the direction this means to send
405 * a keepalive or a path confirmation message (either create or ACK).
406 * - For all other peers, this means to destroy the connection,
407 * due to lack of activity.
408 * Starts the timeout if no timeout was running (connection just created).
409 *
410 * @param c Connection whose timeout to reset.
411 * @param fwd Is this forward?
412 */
413static void
414connection_reset_timeout (struct CadetConnection *c, int fwd);
415
416
417/**
418 * Get string description for tunnel state. Reentrant.
419 *
420 * @param s Tunnel state.
421 *
422 * @return String representation.
423 */
424static const char *
425GCC_state2s (enum CadetConnectionState s)
426{
427 switch (s)
428 {
429 case CADET_CONNECTION_NEW:
430 return "CADET_CONNECTION_NEW";
431 case CADET_CONNECTION_SENT:
432 return "CADET_CONNECTION_SENT";
433 case CADET_CONNECTION_ACK:
434 return "CADET_CONNECTION_ACK";
435 case CADET_CONNECTION_READY:
436 return "CADET_CONNECTION_READY";
437 case CADET_CONNECTION_DESTROYED:
438 return "CADET_CONNECTION_DESTROYED";
439 case CADET_CONNECTION_BROKEN:
440 return "CADET_CONNECTION_BROKEN";
441 default:
442 GNUNET_break (0);
443 LOG (GNUNET_ERROR_TYPE_ERROR, " conn state %u unknown!\n", s);
444 return "CADET_CONNECTION_STATE_ERROR";
445 }
446}
447
448
449/** 169/**
450 * Initialize a Flow Control structure to the initial state. 170 * Lookup a connection by its identifier.
451 * 171 *
452 * @param fc Flow Control structure to initialize. 172 * @param cid identifier to resolve
173 * @return NULL if connection was not found
453 */ 174 */
454static void 175struct CadetConnection *
455fc_init (struct CadetFlowControl *fc) 176GCC_lookup (const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
456{
457 fc->next_pid.pid = 0;
458 fc->last_pid_sent.pid = htonl (UINT32_MAX);
459 fc->last_pid_recv.pid = htonl (UINT32_MAX);
460 fc->last_ack_sent.pid = (uint32_t) 0;
461 fc->last_ack_recv.pid = (uint32_t) 0;
462 fc->poll_task = NULL;
463 fc->poll_time = GNUNET_TIME_UNIT_SECONDS;
464 fc->queue_n = 0;
465 fc->queue_max = (max_msgs_queue / max_connections) + 1;
466}
467
468
469/**
470 * Find a connection.
471 *
472 * @param cid Connection ID.
473 *
474 * @return conntection with the given ID @cid or NULL if not found.
475 */
476static struct CadetConnection *
477connection_get (const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
478{ 177{
479 return GNUNET_CONTAINER_multishortmap_get (connections, 178 return GNUNET_CONTAINER_multishortmap_get (connections,
480 &cid->connection_of_tunnel); 179 &cid->connection_of_tunnel);
@@ -482,3232 +181,911 @@ connection_get (const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
482 181
483 182
484/** 183/**
485 * Change the connection state. Cannot change a connection marked as destroyed. 184 * Update the connection state. Also triggers the necessary
185 * MQM notifications.
486 * 186 *
487 * @param c Connection to change. 187 * @param cc connection to update the state for
488 * @param state New state to set. 188 * @param new_state new state for @a cc
189 * @param new_mqm_ready new `mqm_ready` state for @a cc
489 */ 190 */
490static void 191static void
491connection_change_state (struct CadetConnection* c, 192update_state (struct CadetConnection *cc,
492 enum CadetConnectionState state) 193 enum CadetConnectionState new_state,
194 int new_mqm_ready)
493{ 195{
494 LOG (GNUNET_ERROR_TYPE_DEBUG, 196 int old_ready;
495 "Connection %s state %s -> %s\n", 197 int new_ready;
496 GCC_2s (c), GCC_state2s (c->state), GCC_state2s (state));
497 if (CADET_CONNECTION_DESTROYED <= c->state) /* Destroyed or broken. */
498 {
499 LOG (GNUNET_ERROR_TYPE_DEBUG, "state not changing anymore\n");
500 return;
501 }
502 c->state = state;
503 if (CADET_CONNECTION_READY == state)
504 c->create_retry = 1;
505}
506
507 198
508/** 199 if ( (new_state == cc->state) &&
509 * Mark a connection as "destroyed", to send all pending traffic and freeing 200 (new_mqm_ready == cc->mqm_ready) )
510 * all associated resources, without accepting new status changes on it. 201 return; /* no change, nothing to do */
511 * 202 old_ready = ( (CADET_CONNECTION_READY == cc->state) &&
512 * @param c Connection to mark as destroyed. 203 (GNUNET_YES == cc->mqm_ready) );
513 */ 204 new_ready = ( (CADET_CONNECTION_READY == new_state) &&
514static void 205 (GNUNET_YES == new_mqm_ready) );
515mark_destroyed (struct CadetConnection *c) 206 cc->state = new_state;
516{ 207 cc->mqm_ready = new_mqm_ready;
517 c->destroy = GNUNET_YES; 208 if (old_ready != new_ready)
518 connection_change_state (c, CADET_CONNECTION_DESTROYED); 209 cc->ready_cb (cc->ready_cb_cls,
210 new_ready);
519} 211}
520 212
521 213
522/** 214/**
523 * Function called if a connection has been stalled for a while, 215 * Destroy a connection, part of the internal implementation. Called
524 * possibly due to a missed ACK. Poll the neighbor about its ACK status. 216 * only from #GCC_destroy_from_core() or #GCC_destroy_from_tunnel().
525 *
526 * @param cls Closure (poll ctx).
527 */
528static void
529send_poll (void *cls);
530
531
532/**
533 * Send an ACK on the connection, informing the predecessor about
534 * the available buffer space. Should not be called in case the peer
535 * is origin (no predecessor) in the @c fwd direction.
536 *
537 * Note that for fwd ack, the FWD mean forward *traffic* (root->dest),
538 * the ACK itself goes "back" (dest->root).
539 * 217 *
540 * @param c Connection on which to send the ACK. 218 * @param cc connection to destroy
541 * @param buffer How much space free to advertise?
542 * @param fwd Is this FWD ACK? (Going dest -> root)
543 * @param force Don't optimize out.
544 */ 219 */
545static void 220static void
546send_ack (struct CadetConnection *c, 221GCC_destroy (struct CadetConnection *cc)
547 unsigned int buffer,
548 int fwd,
549 int force)
550{ 222{
551 static struct CadetEncryptedMessageIdentifier zero;
552 struct CadetFlowControl *next_fc;
553 struct CadetFlowControl *prev_fc;
554 struct GNUNET_CADET_ConnectionEncryptedAckMessage msg;
555 struct CadetEncryptedMessageIdentifier ack_cemi;
556 int delta;
557
558 GCC_check_connections ();
559 GNUNET_assert (GNUNET_NO == GCC_is_origin (c, fwd));
560
561 next_fc = fwd ? &c->fwd_fc : &c->bck_fc;
562 prev_fc = fwd ? &c->bck_fc : &c->fwd_fc;
563
564 LOG (GNUNET_ERROR_TYPE_DEBUG, "send %s ack on %s\n",
565 GC_f2s (fwd), GCC_2s (c));
566
567 /* Check if we need to transmit the ACK. */
568 delta = ntohl (prev_fc->last_ack_sent.pid) - ntohl (prev_fc->last_pid_recv.pid);
569 if (3 < delta && buffer < delta && GNUNET_NO == force)
570 {
571 LOG (GNUNET_ERROR_TYPE_DEBUG, "Not sending ACK, delta > 3\n");
572 LOG (GNUNET_ERROR_TYPE_DEBUG,
573 " last pid recv: %u, last ack sent: %u\n",
574 ntohl (prev_fc->last_pid_recv.pid),
575 ntohl (prev_fc->last_ack_sent.pid));
576 GCC_check_connections ();
577 return;
578 }
579
580 /* Ok, ACK might be necessary, what PID to ACK? */
581 ack_cemi.pid = htonl (ntohl (prev_fc->last_pid_recv.pid) + buffer);
582 LOG (GNUNET_ERROR_TYPE_DEBUG, 223 LOG (GNUNET_ERROR_TYPE_DEBUG,
583 " ACK %u, last PID %u, last ACK %u, qmax %u, q %u\n", 224 "Destroying %s\n",
584 ntohl (ack_cemi.pid), 225 GCC_2s (cc));
585 ntohl (prev_fc->last_pid_recv.pid), 226 if (NULL != cc->mq_man)
586 ntohl (prev_fc->last_ack_sent.pid),
587 next_fc->queue_max, next_fc->queue_n);
588 if ( (ack_cemi.pid == prev_fc->last_ack_sent.pid) &&
589 (GNUNET_NO == force) )
590 {
591 LOG (GNUNET_ERROR_TYPE_DEBUG, "Not sending FWD ACK, not needed\n");
592 GCC_check_connections ();
593 return;
594 }
595
596 /* Check if message is already in queue */
597 if (NULL != prev_fc->ack_msg)
598 {
599 if (GC_is_pid_bigger (ntohl (ack_cemi.pid),
600 ntohl (prev_fc->last_ack_sent.pid)))
601 {
602 LOG (GNUNET_ERROR_TYPE_DEBUG, " canceling old ACK\n");
603 GCC_cancel (prev_fc->ack_msg);
604 /* GCC_cancel triggers ack_sent(), which clears fc->ack_msg */
605 }
606 else
607 {
608 LOG (GNUNET_ERROR_TYPE_DEBUG, " same ACK already in queue\n");
609 GCC_check_connections ();
610 return;
611 }
612 }
613 GNUNET_break (GC_is_pid_bigger (ntohl (ack_cemi.pid),
614 ntohl (prev_fc->last_ack_sent.pid)));
615 prev_fc->last_ack_sent = ack_cemi;
616
617 /* Build ACK message and send on conn */
618 msg.header.size = htons (sizeof (msg));
619 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CONNECTION_HOP_BY_HOP_ENCRYPTED_ACK);
620 msg.cemi_max = ack_cemi;
621 msg.cid = c->id;
622
623 prev_fc->ack_msg = GCC_send_prebuilt_message (&msg.header,
624 UINT16_MAX,
625 zero,
626 c,
627 !fwd,
628 GNUNET_YES,
629 NULL, NULL);
630 GNUNET_assert (NULL != prev_fc->ack_msg);
631 GCC_check_connections ();
632}
633
634
635/**
636 * Update performance information if we are a connection's endpoint.
637 *
638 * @param c Connection to update.
639 * @param wait How much time did we wait to send the last message.
640 * @param size Size of the last message.
641 */
642static void
643update_perf (struct CadetConnection *c,
644 struct GNUNET_TIME_Relative wait,
645 uint16_t size)
646{
647 struct CadetConnectionPerformance *p;
648 double usecsperbyte;
649
650 if (NULL == c->perf)
651 return; /* Only endpoints are interested in timing. */
652
653 p = c->perf;
654 usecsperbyte = ((double) wait.rel_value_us) / size;
655 if (p->size == AVG_MSGS)
656 {
657 /* Array is full. Substract oldest value, add new one and store. */
658 p->avg -= (p->usecsperbyte[p->idx] / AVG_MSGS);
659 p->usecsperbyte[p->idx] = usecsperbyte;
660 p->avg += (p->usecsperbyte[p->idx] / AVG_MSGS);
661 }
662 else
663 {
664 /* Array not yet full. Add current value to avg and store. */
665 p->usecsperbyte[p->idx] = usecsperbyte;
666 p->avg *= p->size;
667 p->avg += p->usecsperbyte[p->idx];
668 p->size++;
669 p->avg /= p->size;
670 }
671 p->idx = (p->idx + 1) % AVG_MSGS;
672}
673
674
675/**
676 * Callback called when a connection queued message is sent.
677 *
678 * Calculates the average time and connection packet tracking.
679 *
680 * @param cls Closure (ConnectionQueue Handle), can be NULL.
681 * @param c Connection this message was on.
682 * @param fwd Was this a FWD going message?
683 * @param sent Was it really sent? (Could have been canceled)
684 * @param type Type of message sent.
685 * @param payload_type Type of payload, if applicable.
686 * @param pid Message ID, or 0 if not applicable (create, destroy, etc).
687 * @param size Size of the message.
688 * @param wait Time spent waiting for core (only the time for THIS message)
689 */
690static void
691conn_message_sent (void *cls,
692 struct CadetConnection *c,
693 int fwd,
694 int sent,
695 uint16_t type,
696 uint16_t payload_type,
697 struct CadetEncryptedMessageIdentifier pid,
698 size_t size,
699 struct GNUNET_TIME_Relative wait)
700{
701 struct CadetConnectionQueue *q = cls;
702 struct CadetFlowControl *fc;
703 int forced;
704
705 GCC_check_connections ();
706 LOG (GNUNET_ERROR_TYPE_INFO,
707 ">>> %s (%s %4u) on conn %s (%p) %s [%5u] in queue %s\n",
708 GC_m2s (type), GC_m2s (payload_type),
709 ntohl (pid.pid),
710 GCC_2s (c),
711 c,
712 GC_f2s (fwd), size,
713 GNUNET_STRINGS_relative_time_to_string (wait, GNUNET_YES));
714
715 /* If c is NULL, nothing to update. */
716 if (NULL == c)
717 {
718 if (type != GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN
719 && type != GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY)
720 {
721 LOG (GNUNET_ERROR_TYPE_ERROR, "Message %s sent on NULL connection!\n",
722 GC_m2s (type));
723 }
724 GCC_check_connections ();
725 return;
726 }
727
728 LOG (GNUNET_ERROR_TYPE_DEBUG, " %ssent %s %s pid %u\n",
729 sent ? "" : "not ", GC_f2s (fwd),
730 GC_m2s (type), GC_m2s (payload_type),
731 ntohl (pid.pid));
732 GCC_debug (c, GNUNET_ERROR_TYPE_DEBUG);
733
734 /* Update flow control info. */
735 fc = fwd ? &c->fwd_fc : &c->bck_fc;
736
737 if (NULL != q)
738 { 227 {
739 GNUNET_CONTAINER_DLL_remove (fc->q_head, fc->q_tail, q); 228 GCP_request_mq_cancel (cc->mq_man,
740 forced = q->forced; 229 NULL);
741 if (NULL != q->cont) 230 cc->mq_man = NULL;
742 {
743 LOG (GNUNET_ERROR_TYPE_DEBUG, " calling cont\n");
744 q->cont (q->cont_cls, c, q, type, fwd, size);
745 }
746 GNUNET_free (q);
747 } 231 }
748 else /* CONN_CREATE or CONN_ACK */ 232 if (NULL != cc->task)
749 { 233 {
750 GNUNET_assert (GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED != type); 234 GNUNET_SCHEDULER_cancel (cc->task);
751 forced = GNUNET_YES; 235 cc->task = NULL;
752 } 236 }
753 237 if (NULL != cc->keepalive_qe)
754 LOG (GNUNET_ERROR_TYPE_DEBUG, " C_P- %p %u\n", c, c->pending_messages);
755 c->pending_messages--;
756 if ( (GNUNET_YES == c->destroy) &&
757 (0 == c->pending_messages) )
758 { 238 {
759 LOG (GNUNET_ERROR_TYPE_DEBUG, 239 GCT_send_cancel (cc->keepalive_qe);
760 "! destroying connection!\n"); 240 cc->keepalive_qe = NULL;
761 GCC_destroy (c);
762 GCC_check_connections ();
763 return;
764 } 241 }
765 242 GCPP_del_connection (cc->path,
766 /* Send ACK if needed, after accounting for sent ID in fc->queue_n */ 243 cc->off,
767 switch (type) 244 cc);
768 { 245 for (unsigned int i=0;i<cc->off;i++)
769 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE: 246 GCP_remove_connection (GCPP_get_peer_at_offset (cc->path,
770 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK: 247 i),
771 c->maintenance_q = NULL; 248 cc);
772 /* Don't trigger a keepalive for sent ACKs, only SYN and SYNACKs */ 249 GNUNET_assert (GNUNET_YES ==
773 if (GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE == type || !fwd) 250 GNUNET_CONTAINER_multishortmap_remove (connections,
774 schedule_next_keepalive (c, fwd); 251 &GCC_get_id (cc)->connection_of_tunnel,
775 break; 252 cc));
776 253 GNUNET_free (cc);
777 case GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED:
778 if (GNUNET_YES == sent)
779 {
780 fc->last_pid_sent = pid;
781 if (GC_is_pid_bigger (ntohl (fc->last_pid_sent.pid) + 1,
782 ntohl (fc->last_ack_recv.pid)) )
783 GCC_start_poll (c, fwd);
784 GCC_send_ack (c, fwd, GNUNET_NO);
785 connection_reset_timeout (c, fwd);
786 }
787
788 LOG (GNUNET_ERROR_TYPE_DEBUG, "! Q_N- %p %u\n", fc, fc->queue_n);
789 if (GNUNET_NO == forced)
790 {
791 fc->queue_n--;
792 LOG (GNUNET_ERROR_TYPE_DEBUG,
793 "! accounting pid %u\n",
794 ntohl (fc->last_pid_sent.pid));
795 }
796 else
797 {
798 LOG (GNUNET_ERROR_TYPE_DEBUG,
799 "! forced, Q_N not accounting pid %u\n",
800 ntohl (fc->last_pid_sent.pid));
801 }
802 break;
803
804 case GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX:
805 if (GNUNET_YES == sent)
806 connection_reset_timeout (c, fwd);
807 break;
808
809 case GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED_POLL:
810 fc->poll_msg = NULL;
811 if (2 == c->destroy)
812 {
813 LOG (GNUNET_ERROR_TYPE_DEBUG, "POLL canceled on shutdown\n");
814 return;
815 }
816 if (0 == fc->queue_max)
817 {
818 LOG (GNUNET_ERROR_TYPE_DEBUG, "POLL cancelled: neighbor disconnected\n");
819 return;
820 }
821 LOG (GNUNET_ERROR_TYPE_DEBUG, "POLL sent for %s, scheduling new one!\n",
822 GCC_2s (c));
823 GNUNET_assert (NULL == fc->poll_task);
824 fc->poll_time = GNUNET_TIME_STD_BACKOFF (fc->poll_time);
825 fc->poll_task = GNUNET_SCHEDULER_add_delayed (fc->poll_time,
826 &send_poll, fc);
827 LOG (GNUNET_ERROR_TYPE_DEBUG, " task %u\n", fc->poll_task);
828 break;
829
830 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_HOP_BY_HOP_ENCRYPTED_ACK:
831 fc->ack_msg = NULL;
832 break;
833
834 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN:
835 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY:
836 break;
837
838 default:
839 LOG (GNUNET_ERROR_TYPE_ERROR, "%s unknown\n", GC_m2s (type));
840 GNUNET_break (0);
841 break;
842 }
843 LOG (GNUNET_ERROR_TYPE_DEBUG, "! message sent!\n");
844
845 update_perf (c, wait, size);
846 GCC_check_connections ();
847}
848
849
850/**
851 * Get the previous hop in a connection
852 *
853 * @param c Connection.
854 *
855 * @return Previous peer in the connection.
856 */
857static struct CadetPeer *
858get_prev_hop (const struct CadetConnection *c)
859{
860 GNUNET_PEER_Id id;
861
862 if (NULL == c->path)
863 return NULL;
864 LOG (GNUNET_ERROR_TYPE_DEBUG,
865 " get prev hop %s [%u/%u]\n",
866 GCC_2s (c), c->own_pos, c->path->length);
867 if (0 == c->own_pos || c->path->length < 2)
868 id = c->path->peers[0];
869 else
870 id = c->path->peers[c->own_pos - 1];
871
872 LOG (GNUNET_ERROR_TYPE_DEBUG, " ID: %s (%u)\n",
873 GNUNET_i2s (GNUNET_PEER_resolve2 (id)), id);
874
875 return GCP_get_short (id, GNUNET_YES);
876}
877
878
879/**
880 * Get the next hop in a connection
881 *
882 * @param c Connection.
883 *
884 * @return Next peer in the connection.
885 */
886static struct CadetPeer *
887get_next_hop (const struct CadetConnection *c)
888{
889 GNUNET_PEER_Id id;
890
891 if (NULL == c->path)
892 return NULL;
893
894 LOG (GNUNET_ERROR_TYPE_DEBUG, " get next hop %s [%u/%u]\n",
895 GCC_2s (c), c->own_pos, c->path->length);
896 if ((c->path->length - 1) == c->own_pos || c->path->length < 2)
897 id = c->path->peers[c->path->length - 1];
898 else
899 id = c->path->peers[c->own_pos + 1];
900
901 LOG (GNUNET_ERROR_TYPE_DEBUG, " ID: %s (%u)\n",
902 GNUNET_i2s (GNUNET_PEER_resolve2 (id)), id);
903
904 return GCP_get_short (id, GNUNET_YES);
905} 254}
906 255
907 256
908/**
909 * Check that the direct neighbours (previous and next hop)
910 * are properly associated with this connection.
911 *
912 * @param c connection to check
913 */
914static void
915check_neighbours (const struct CadetConnection *c)
916{
917 if (NULL == c->path)
918 return; /* nothing to check */
919 GCP_check_connection (get_next_hop (c), c);
920 GCP_check_connection (get_prev_hop (c), c);
921}
922
923 257
924/** 258/**
925 * Helper for #GCC_check_connections(). Calls #check_neighbours(). 259 * Destroy a connection, called when the CORE layer is already done
260 * (i.e. has received a BROKEN message), but if we still have to
261 * communicate the destruction of the connection to the tunnel (if one
262 * exists).
926 * 263 *
927 * @param cls NULL 264 * @param cc connection to destroy
928 * @param key ignored
929 * @param value the `struct CadetConnection` to check
930 * @return #GNUNET_OK (continue to iterate)
931 */
932static int
933check_connection (void *cls,
934 const struct GNUNET_ShortHashCode *key,
935 void *value)
936{
937 struct CadetConnection *c = value;
938
939 check_neighbours (c);
940 return GNUNET_OK;
941}
942
943
944/**
945 * Check invariants for all connections using #check_neighbours().
946 */ 265 */
947void 266void
948GCC_check_connections () 267GCC_destroy_without_core (struct CadetConnection *cc)
949{
950 if (0 == CHECK_INVARIANTS)
951 return;
952 if (NULL == connections)
953 return;
954 GNUNET_CONTAINER_multishortmap_iterate (connections,
955 &check_connection,
956 NULL);
957}
958
959
960/**
961 * Get the hop in a connection.
962 *
963 * @param c Connection.
964 * @param fwd Next in the FWD direction?
965 *
966 * @return Next peer in the connection.
967 */
968static struct CadetPeer *
969get_hop (struct CadetConnection *c, int fwd)
970{
971 return (fwd) ? get_next_hop (c) : get_prev_hop (c);
972}
973
974
975/**
976 * Get a bit mask for a message received out-of-order.
977 *
978 * @param last_pid_recv Last PID we received prior to the out-of-order.
979 * @param ooo_pid PID of the out-of-order message.
980 */
981static uint32_t
982get_recv_bitmask (struct CadetEncryptedMessageIdentifier last_pid_recv,
983 struct CadetEncryptedMessageIdentifier ooo_pid)
984{
985 // FIXME: should assert that the delta is in range...
986 return 1 << (ntohl (last_pid_recv.pid) - ntohl (ooo_pid.pid));
987}
988
989
990/**
991 * Check is an out-of-order message is ok:
992 * - at most 31 messages behind.
993 * - not duplicate.
994 *
995 * @param last_pid_recv Last in-order PID received.
996 */
997static int
998is_ooo_ok (struct CadetEncryptedMessageIdentifier last_pid_recv,
999 struct CadetEncryptedMessageIdentifier ooo_pid,
1000 uint32_t ooo_bitmap)
1001{
1002 uint32_t mask;
1003
1004 if (GC_is_pid_bigger (ntohl (last_pid_recv.pid) - 31,
1005 ntohl (ooo_pid.pid)))
1006 return GNUNET_NO;
1007
1008 mask = get_recv_bitmask (last_pid_recv,
1009 ooo_pid);
1010 if (0 != (ooo_bitmap & mask))
1011 return GNUNET_NO;
1012
1013 return GNUNET_YES;
1014}
1015
1016
1017/**
1018 * Is traffic coming from this sender 'FWD' traffic?
1019 *
1020 * @param c Connection to check.
1021 * @param sender Short peer identity of neighbor.
1022 *
1023 * @return #GNUNET_YES in case the sender is the 'prev' hop and therefore
1024 * the traffic is 'FWD'.
1025 * #GNUNET_NO for BCK.
1026 * #GNUNET_SYSERR for errors (sender isn't a hop in the connection).
1027 */
1028static int
1029is_fwd (const struct CadetConnection *c,
1030 const struct CadetPeer *sender)
1031{
1032 GNUNET_PEER_Id id;
1033
1034 id = GCP_get_short_id (sender);
1035 if (GCP_get_short_id (get_prev_hop (c)) == id)
1036 return GNUNET_YES;
1037
1038 if (GCP_get_short_id (get_next_hop (c)) == id)
1039 return GNUNET_NO;
1040
1041 return GNUNET_SYSERR;
1042}
1043
1044
1045/**
1046 * Sends a CONNECTION ACK message in reponse to a received CONNECTION_CREATE
1047 * or a first CONNECTION_ACK directed to us.
1048 *
1049 * @param c Connection to confirm.
1050 * @param fwd Should we send it FWD? (root->dest)
1051 * (First (~SYNACK) goes BCK, second (~ACK) goes FWD)
1052 */
1053static void
1054send_connection_ack (struct CadetConnection *c, int fwd)
1055{
1056 static struct CadetEncryptedMessageIdentifier zero;
1057 struct GNUNET_CADET_ConnectionCreateAckMessage msg;
1058 struct CadetTunnel *t;
1059 const uint16_t size = sizeof (struct GNUNET_CADET_ConnectionCreateAckMessage);
1060 const uint16_t type = GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK;
1061
1062 GCC_check_connections ();
1063 t = c->t;
1064 LOG (GNUNET_ERROR_TYPE_INFO,
1065 "==> %s ({ C %s ACK} 0) on conn %s (%p) %s [%5u]\n",
1066 GC_m2s (type), GC_f2s (!fwd), GCC_2s (c), c, GC_f2s (fwd), size);
1067
1068 msg.header.size = htons (size);
1069 msg.header.type = htons (type);
1070 msg.reserved = htonl (0);
1071 msg.cid = c->id;
1072
1073 GNUNET_assert (NULL == c->maintenance_q);
1074 c->maintenance_q = GCP_send (get_hop (c, fwd),
1075 &msg.header,
1076 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK,
1077 zero,
1078 c,
1079 fwd,
1080 &conn_message_sent, NULL);
1081 LOG (GNUNET_ERROR_TYPE_DEBUG, " C_P+ %p %u (conn`ACK)\n",
1082 c, c->pending_messages);
1083 c->pending_messages++;
1084
1085 if (CADET_TUNNEL_NEW == GCT_get_cstate (t))
1086 GCT_change_cstate (t, CADET_TUNNEL_WAITING);
1087 if (CADET_CONNECTION_READY != c->state)
1088 connection_change_state (c, CADET_CONNECTION_SENT);
1089 GCC_check_connections ();
1090}
1091
1092
1093/**
1094 * Send a notification that a connection is broken.
1095 *
1096 * @param c Connection that is broken.
1097 * @param id1 Peer that has disconnected.
1098 * @param id2 Peer that has disconnected.
1099 * @param fwd Direction towards which to send it.
1100 */
1101static void
1102send_broken (struct CadetConnection *c,
1103 const struct GNUNET_PeerIdentity *id1,
1104 const struct GNUNET_PeerIdentity *id2,
1105 int fwd)
1106{
1107 static struct CadetEncryptedMessageIdentifier zero;
1108 struct GNUNET_CADET_ConnectionBrokenMessage msg;
1109
1110 GCC_check_connections ();
1111 msg.header.size = htons (sizeof (struct GNUNET_CADET_ConnectionBrokenMessage));
1112 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN);
1113 msg.cid = c->id;
1114 msg.reserved = htonl (0);
1115 msg.peer1 = *id1;
1116 msg.peer2 = *id2;
1117 (void) GCC_send_prebuilt_message (&msg.header,
1118 UINT16_MAX,
1119 zero,
1120 c,
1121 fwd,
1122 GNUNET_YES,
1123 NULL, NULL);
1124 GCC_check_connections ();
1125}
1126
1127
1128/**
1129 * Send a notification that a connection is broken, when a connection
1130 * isn't even known to the local peer or soon to be destroyed.
1131 *
1132 * @param connection_id Connection ID.
1133 * @param id1 Peer that has disconnected, probably local peer.
1134 * @param id2 Peer that has disconnected can be NULL if unknown.
1135 * @param neighbor Peer to notify (neighbor who sent the connection).
1136 */
1137static void
1138send_broken_unknown (const struct GNUNET_CADET_ConnectionTunnelIdentifier *connection_id,
1139 const struct GNUNET_PeerIdentity *id1,
1140 const struct GNUNET_PeerIdentity *id2,
1141 struct CadetPeer *neighbor)
1142{
1143 static struct CadetEncryptedMessageIdentifier zero;
1144 struct GNUNET_CADET_ConnectionBrokenMessage msg;
1145
1146 GCC_check_connections ();
1147 LOG (GNUNET_ERROR_TYPE_INFO, "--> BROKEN on unknown connection %s\n",
1148 GNUNET_sh2s (&connection_id->connection_of_tunnel));
1149
1150 msg.header.size = htons (sizeof (struct GNUNET_CADET_ConnectionBrokenMessage));
1151 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN);
1152 msg.cid = *connection_id;
1153 msg.reserved = htonl (0);
1154 msg.peer1 = *id1;
1155 if (NULL != id2)
1156 msg.peer2 = *id2;
1157 else
1158 memset (&msg.peer2, 0, sizeof (msg.peer2));
1159 GNUNET_assert (NULL != GCP_send (neighbor,
1160 &msg.header,
1161 UINT16_MAX,
1162 zero,
1163 NULL,
1164 GNUNET_SYSERR, /* connection, fwd */
1165 NULL, NULL)); /* continuation */
1166 GCC_check_connections ();
1167}
1168
1169
1170/**
1171 * Send keepalive packets for a connection.
1172 *
1173 * @param c Connection to keep alive..
1174 * @param fwd Is this a FWD keepalive? (owner -> dest).
1175 */
1176static void
1177send_connection_keepalive (struct CadetConnection *c, int fwd)
1178{ 268{
1179 struct GNUNET_MessageHeader msg; 269 if (NULL != cc->ct)
1180 struct CadetFlowControl *fc;
1181 int tunnel_ready;
1182
1183 GCC_check_connections ();
1184 LOG (GNUNET_ERROR_TYPE_INFO,
1185 "keepalive %s for connection %s\n",
1186 GC_f2s (fwd), GCC_2s (c));
1187
1188 GNUNET_assert (NULL != c->t);
1189 fc = fwd ? &c->fwd_fc : &c->bck_fc;
1190 tunnel_ready = GNUNET_YES == GCT_has_queued_traffic (c->t)
1191 && CADET_TUNNEL_KEY_OK <= GCT_get_estate (c->t);
1192 if (0 < fc->queue_n || tunnel_ready)
1193 { 270 {
1194 LOG (GNUNET_ERROR_TYPE_INFO, "not sending keepalive, traffic in queue\n"); 271 GCT_connection_lost (cc->ct);
1195 return; 272 cc->ct = NULL;
1196 } 273 }
1197 274 GCC_destroy (cc);
1198 GNUNET_STATISTICS_update (stats, "# keepalives sent", 1, GNUNET_NO);
1199
1200 GNUNET_assert (NULL != c->t);
1201 msg.size = htons (sizeof (msg));
1202 msg.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE);
1203
1204 GNUNET_assert (NULL ==
1205 GCT_send_prebuilt_message (&msg, c->t, c,
1206 GNUNET_NO, NULL, NULL));
1207 GCC_check_connections ();
1208}
1209
1210
1211/**
1212 * Send CONNECTION_{CREATE/ACK} packets for a connection.
1213 *
1214 * @param c Connection for which to send the message.
1215 * @param fwd If #GNUNET_YES, send CREATE, otherwise send ACK.
1216 */
1217static void
1218connection_recreate (struct CadetConnection *c, int fwd)
1219{
1220 LOG (GNUNET_ERROR_TYPE_DEBUG,
1221 "sending connection recreate\n");
1222 if (fwd)
1223 GCC_send_create (c);
1224 else
1225 send_connection_ack (c, GNUNET_NO);
1226} 275}
1227 276
1228 277
1229/** 278/**
1230 * Generic connection timer management. 279 * Destroy a connection, called if the tunnel association with the
1231 * Depending on the role of the peer in the connection will send the 280 * connection was already broken, but we still need to notify the CORE
1232 * appropriate message (build or keepalive) 281 * layer about the breakage.
1233 * 282 *
1234 * @param c Conncetion to maintain. 283 * @param cc connection to destroy
1235 * @param fwd Is FWD?
1236 */ 284 */
1237static void 285void
1238connection_maintain (struct CadetConnection *c, int fwd) 286GCC_destroy_without_tunnel (struct CadetConnection *cc)
1239{ 287{
1240 if (GNUNET_NO != c->destroy) 288 cc->ct = NULL;
289 if ( (CADET_CONNECTION_SENDING_CREATE != cc->state) &&
290 (NULL != cc->mq_man) )
1241 { 291 {
1242 LOG (GNUNET_ERROR_TYPE_INFO, "not sending keepalive, being destroyed\n"); 292 struct GNUNET_MQ_Envelope *env;
1243 return; 293 struct GNUNET_CADET_ConnectionDestroyMessage *destroy_msg;
1244 }
1245
1246 if (NULL == c->t)
1247 {
1248 GNUNET_break (0);
1249 GCC_debug (c, GNUNET_ERROR_TYPE_ERROR);
1250 return;
1251 }
1252 294
1253 if (CADET_TUNNEL_SEARCHING == GCT_get_cstate (c->t)) 295 /* Need to notify next hop that we are down. */
1254 { 296 env = GNUNET_MQ_msg (destroy_msg,
1255 /* If status is SEARCHING, why is there a connection? Should be WAITING */ 297 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY);
1256 GNUNET_break (0); 298 destroy_msg->cid = cc->cid;
1257 GCT_debug (c->t, GNUNET_ERROR_TYPE_ERROR); 299 GCP_request_mq_cancel (cc->mq_man,
1258 LOG (GNUNET_ERROR_TYPE_INFO, "not sending keepalive, tunnel SEARCHING\n"); 300 env);
1259 schedule_next_keepalive (c, fwd); 301 cc->mq_man = NULL;
1260 return;
1261 }
1262 switch (c->state)
1263 {
1264 case CADET_CONNECTION_NEW:
1265 GNUNET_break (0);
1266 /* fall-through */
1267 case CADET_CONNECTION_SENT:
1268 connection_recreate (c, fwd);
1269 break;
1270 case CADET_CONNECTION_READY:
1271 send_connection_keepalive (c, fwd);
1272 break;
1273 default:
1274 break;
1275 } 302 }
303 GCC_destroy (cc);
1276} 304}
1277 305
1278 306
1279/** 307/**
1280 * Keep the connection alive. 308 * Return the tunnel associated with this connection.
1281 * 309 *
1282 * @param c Connection to keep alive. 310 * @param cc connection to query
1283 * @param fwd Direction. 311 * @return corresponding entry in the tunnel's connection list
1284 */ 312 */
1285static void 313struct CadetTConnection *
1286connection_keepalive (struct CadetConnection *c, 314GCC_get_ct (struct CadetConnection *cc)
1287 int fwd)
1288{ 315{
1289 GCC_check_connections (); 316 return cc->ct;
1290 LOG (GNUNET_ERROR_TYPE_DEBUG,
1291 "%s keepalive for %s\n",
1292 GC_f2s (fwd), GCC_2s (c));
1293
1294 if (fwd)
1295 c->fwd_maintenance_task = NULL;
1296 else
1297 c->bck_maintenance_task = NULL;
1298 connection_maintain (c, fwd);
1299 GCC_check_connections ();
1300 /* Next execution will be scheduled by message_sent or _maintain*/
1301} 317}
1302 318
1303 319
1304/** 320/**
1305 * Keep the connection alive in the FWD direction. 321 * Obtain performance @a metrics from @a cc.
1306 * 322 *
1307 * @param cls Closure (connection to keepalive). 323 * @param cc connection to query
324 * @return the metrics
1308 */ 325 */
1309static void 326const struct CadetConnectionMetrics *
1310connection_fwd_keepalive (void *cls) 327GCC_get_metrics (struct CadetConnection *cc)
1311{ 328{
1312 struct CadetConnection *c = cls; 329 return &cc->metrics;
1313
1314 GCC_check_connections ();
1315 connection_keepalive (c,
1316 GNUNET_YES);
1317 GCC_check_connections ();
1318} 330}
1319 331
1320 332
1321/** 333/**
1322 * Keep the connection alive in the BCK direction. 334 * Send a #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE through the
335 * tunnel to prevent it from timing out.
1323 * 336 *
1324 * @param cls Closure (connection to keepalive). 337 * @param cls the `struct CadetConnection` to keep alive.
1325 */ 338 */
1326static void 339static void
1327connection_bck_keepalive (void *cls) 340send_keepalive (void *cls);
1328{
1329 struct CadetConnection *c = cls;
1330
1331 GCC_check_connections ();
1332 connection_keepalive (c,
1333 GNUNET_NO);
1334 GCC_check_connections ();
1335}
1336 341
1337 342
1338/** 343/**
1339 * Schedule next keepalive task, taking in consideration 344 * Keepalive was transmitted. Remember this, and possibly
1340 * the connection state and number of retries. 345 * schedule the next one.
1341 * 346 *
1342 * If the peer is not the origin, do nothing. 347 * @param cls the `struct CadetConnection` to keep alive.
1343 * 348 * @param cid identifier of the connection within the tunnel, NULL
1344 * @param c Connection for which to schedule the next keepalive. 349 * if transmission failed
1345 * @param fwd Direction for the next keepalive.
1346 */ 350 */
1347static void 351static void
1348schedule_next_keepalive (struct CadetConnection *c, int fwd) 352keepalive_done (void *cls,
353 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
1349{ 354{
1350 struct GNUNET_TIME_Relative delay; 355 struct CadetConnection *cc = cls;
1351 struct GNUNET_SCHEDULER_Task * *task_id;
1352 GNUNET_SCHEDULER_TaskCallback keepalive_task;
1353
1354 GCC_check_connections ();
1355 if (GNUNET_NO == GCC_is_origin (c, fwd))
1356 return;
1357
1358 /* Calculate delay to use, depending on the state of the connection */
1359 if (CADET_CONNECTION_READY == c->state)
1360 {
1361 delay = refresh_connection_time;
1362 }
1363 else
1364 {
1365 if (1 > c->create_retry)
1366 c->create_retry = 1;
1367 delay = GNUNET_TIME_relative_saturating_multiply (create_connection_time,
1368 c->create_retry);
1369 if (c->create_retry < 64) // TODO make configurable
1370 c->create_retry *= 2;
1371 }
1372
1373 /* Select direction-dependent parameters */
1374 if (GNUNET_YES == fwd)
1375 {
1376 task_id = &c->fwd_maintenance_task;
1377 keepalive_task = &connection_fwd_keepalive;
1378 }
1379 else
1380 {
1381 task_id = &c->bck_maintenance_task;
1382 keepalive_task = &connection_bck_keepalive;
1383 }
1384 356
1385 /* Check that no one scheduled it before us */ 357 cc->keepalive_qe = NULL;
1386 if (NULL != *task_id) 358 if ( (GNUNET_YES == cc->mqm_ready) &&
1387 { 359 (NULL == cc->task) )
1388 /* No need for a _break. It can happen for instance when sending a SYNACK 360 cc->task = GNUNET_SCHEDULER_add_delayed (keepalive_period,
1389 * for a duplicate SYN: the first SYNACK scheduled the task. */ 361 &send_keepalive,
1390 GNUNET_SCHEDULER_cancel (*task_id); 362 cc);
1391 }
1392
1393 /* Schedule the task */
1394 *task_id = GNUNET_SCHEDULER_add_delayed (delay,
1395 keepalive_task,
1396 c);
1397 LOG (GNUNET_ERROR_TYPE_INFO,
1398 "next keepalive for %s in in %s\n",
1399 GCC_2s (c), GNUNET_STRINGS_relative_time_to_string (delay, GNUNET_YES));
1400 GCC_check_connections ();
1401} 363}
1402 364
1403 365
1404/** 366/**
1405 * Cancel all transmissions that belong to a certain connection. 367 * Send a #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE through the
368 * tunnel to prevent it from timing out.
1406 * 369 *
1407 * If the connection is scheduled for destruction and no more messages are left, 370 * @param cls the `struct CadetConnection` to keep alive.
1408 * the connection will be destroyed by the continuation call.
1409 *
1410 * @param c Connection which to cancel. Might be destroyed during this call.
1411 * @param fwd Cancel fwd traffic?
1412 */ 371 */
1413static void 372static void
1414connection_cancel_queues (struct CadetConnection *c, 373send_keepalive (void *cls)
1415 int fwd)
1416{ 374{
1417 struct CadetFlowControl *fc; 375 struct CadetConnection *cc = cls;
376 struct GNUNET_MessageHeader msg;
1418 377
1419 GCC_check_connections (); 378 cc->task = NULL;
1420 LOG (GNUNET_ERROR_TYPE_DEBUG, 379 if (CADET_TUNNEL_KEY_OK != GCT_get_estate (cc->ct->t))
1421 "Cancel %s queues for connection %s\n",
1422 GC_f2s (fwd), GCC_2s (c));
1423 if (NULL == c)
1424 { 380 {
1425 GNUNET_break (0); 381 /* Tunnel not yet ready, wait with keepalives... */
382 cc->task = GNUNET_SCHEDULER_add_delayed (keepalive_period,
383 &send_keepalive,
384 cc);
1426 return; 385 return;
1427 } 386 }
1428 387 GNUNET_assert (NULL != cc->ct);
1429 fc = fwd ? &c->fwd_fc : &c->bck_fc; 388 GNUNET_assert (GNUNET_YES == cc->mqm_ready);
1430 if (NULL != fc->poll_task) 389 GNUNET_assert (NULL == cc->keepalive_qe);
1431 {
1432 GNUNET_SCHEDULER_cancel (fc->poll_task);
1433 fc->poll_task = NULL;
1434 LOG (GNUNET_ERROR_TYPE_DEBUG, " cancelled POLL task for fc %p\n", fc);
1435 }
1436 if (NULL != fc->poll_msg)
1437 {
1438 GCC_cancel (fc->poll_msg);
1439 LOG (GNUNET_ERROR_TYPE_DEBUG, " cancelled POLL msg for fc %p\n", fc);
1440 }
1441
1442 while (NULL != fc->q_head)
1443 {
1444 GCC_cancel (fc->q_head);
1445 }
1446 GCC_check_connections ();
1447}
1448
1449
1450/**
1451 * Function called if a connection has been stalled for a while,
1452 * possibly due to a missed ACK. Poll the neighbor about its ACK status.
1453 *
1454 * @param cls Closure (poll ctx).
1455 */
1456static void
1457send_poll (void *cls)
1458{
1459 static struct CadetEncryptedMessageIdentifier zero;
1460 struct CadetFlowControl *fc = cls;
1461 struct GNUNET_CADET_ConnectionHopByHopPollMessage msg;
1462 struct CadetConnection *c;
1463 int fwd;
1464
1465 fc->poll_task = NULL;
1466 GCC_check_connections ();
1467 c = fc->c;
1468 fwd = fc == &c->fwd_fc;
1469 LOG (GNUNET_ERROR_TYPE_DEBUG, "Polling connection %s %s\n",
1470 GCC_2s (c), GC_f2s (fwd));
1471
1472 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED_POLL);
1473 msg.header.size = htons (sizeof (msg));
1474 msg.cid = c->id;
1475 msg.cemi = fc->last_pid_sent;
1476 LOG (GNUNET_ERROR_TYPE_DEBUG, " last pid sent: %u\n", ntohl (fc->last_pid_sent.pid));
1477 fc->poll_msg
1478 = GCC_send_prebuilt_message (&msg.header,
1479 UINT16_MAX,
1480 zero,
1481 c,
1482 fc == &c->fwd_fc,
1483 GNUNET_YES,
1484 NULL,
1485 NULL);
1486 GNUNET_assert (NULL != fc->poll_msg);
1487 GCC_check_connections ();
1488}
1489
1490
1491/**
1492 * Generic connection timeout implementation.
1493 *
1494 * Timeout function due to lack of keepalive/traffic from an endpoint.
1495 * Destroys connection if called.
1496 *
1497 * @param c Connection to destroy.
1498 * @param fwd Was the timeout from the origin? (FWD timeout)
1499 */
1500static void
1501connection_timeout (struct CadetConnection *c, int fwd)
1502{
1503 GCC_check_connections ();
1504
1505 LOG (GNUNET_ERROR_TYPE_INFO, 390 LOG (GNUNET_ERROR_TYPE_INFO,
1506 "Connection %s %s timed out. Destroying.\n", 391 "Sending KEEPALIVE on behalf of %s via %s\n",
1507 GCC_2s (c), 392 GCC_2s (cc),
1508 GC_f2s (fwd)); 393 GCT_2s (cc->ct->t));
1509 GCC_debug (c, GNUNET_ERROR_TYPE_DEBUG); 394 GNUNET_STATISTICS_update (stats,
1510 395 "# keepalives sent",
1511 if (GCC_is_origin (c, fwd)) /* Loopback? Something is wrong! */ 396 1,
1512 { 397 GNUNET_NO);
1513 GNUNET_break (0); 398 msg.size = htons (sizeof (msg));
1514 return; 399 msg.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE);
1515 }
1516
1517 /* If dest, send "broken" notification. */
1518 if (GCC_is_terminal (c, fwd))
1519 {
1520 struct CadetPeer *next_hop;
1521
1522 next_hop = fwd ? get_prev_hop (c) : get_next_hop (c);
1523 send_broken_unknown (&c->id, &my_full_id, NULL, next_hop);
1524 }
1525
1526 GCC_destroy (c);
1527 GCC_check_connections ();
1528}
1529
1530
1531/**
1532 * Timeout function due to lack of keepalive/traffic from the owner.
1533 * Destroys connection if called.
1534 *
1535 * @param cls Closure (connection to destroy).
1536 */
1537static void
1538connection_fwd_timeout (void *cls)
1539{
1540 struct CadetConnection *c = cls;
1541
1542 c->fwd_maintenance_task = NULL;
1543 GCC_check_connections ();
1544 connection_timeout (c, GNUNET_YES);
1545 GCC_check_connections ();
1546}
1547
1548
1549/**
1550 * Timeout function due to lack of keepalive/traffic from the destination.
1551 * Destroys connection if called.
1552 *
1553 * @param cls Closure (connection to destroy).
1554 */
1555static void
1556connection_bck_timeout (void *cls)
1557{
1558 struct CadetConnection *c = cls;
1559 400
1560 c->bck_maintenance_task = NULL; 401 cc->keepalive_qe
1561 GCC_check_connections (); 402 = GCT_send (cc->ct->t,
1562 connection_timeout (c, GNUNET_NO); 403 &msg,
1563 GCC_check_connections (); 404 &keepalive_done,
405 cc);
1564} 406}
1565 407
1566 408
1567/** 409/**
1568 * Resets the connection timeout task, some other message has done the 410 * We sent a message for which we expect to receive an ACK via
1569 * task's job. 411 * the connection identified by @a cti.
1570 * - For the first peer on the direction this means to send
1571 * a keepalive or a path confirmation message (either create or ACK).
1572 * - For all other peers, this means to destroy the connection,
1573 * due to lack of activity.
1574 * Starts the timeout if no timeout was running (connection just created).
1575 *
1576 * @param c Connection whose timeout to reset.
1577 * @param fwd Is this forward?
1578 * 412 *
1579 * TODO use heap to improve efficiency of scheduler. 413 * @param cid connection identifier where we expect an ACK
1580 */ 414 */
1581static void 415void
1582connection_reset_timeout (struct CadetConnection *c, int fwd) 416GCC_ack_expected (const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
1583{ 417{
1584 LOG (GNUNET_ERROR_TYPE_DEBUG, "Connection %s reset timeout\n", GC_f2s (fwd)); 418 struct CadetConnection *cc;
1585 if (GCC_is_origin (c, fwd)) /* Startpoint */
1586 {
1587 schedule_next_keepalive (c, fwd);
1588 if (NULL != c->maintenance_q)
1589 {
1590 GCP_send_cancel (c->maintenance_q);
1591 c->maintenance_q = NULL; /* Is set to NULL by conn_message_sent anyway */
1592 }
1593 }
1594 else /* Relay, endpoint. */
1595 {
1596 struct GNUNET_TIME_Relative delay;
1597 struct GNUNET_SCHEDULER_Task * *ti;
1598 GNUNET_SCHEDULER_TaskCallback f;
1599
1600 ti = fwd ? &c->fwd_maintenance_task : &c->bck_maintenance_task;
1601 419
1602 if (NULL != *ti) 420 cc = GCC_lookup (cid);
1603 GNUNET_SCHEDULER_cancel (*ti); 421 if (NULL == cc)
1604 delay = GNUNET_TIME_relative_saturating_multiply (refresh_connection_time, 4); 422 return; /* whopise, connection alredy down? */
1605 LOG (GNUNET_ERROR_TYPE_DEBUG, 423 cc->metrics.num_acked_transmissions++;
1606 " timing out in %s\n",
1607 GNUNET_STRINGS_relative_time_to_string (delay, GNUNET_NO));
1608 f = fwd ? &connection_fwd_timeout : &connection_bck_timeout;
1609 *ti = GNUNET_SCHEDULER_add_delayed (delay, f, c);
1610 }
1611} 424}
1612 425
1613 426
1614/** 427/**
1615 * Iterator to compare each connection's path with the path of a new connection. 428 * We observed an ACK for a message that was originally sent via
429 * the connection identified by @a cti.
1616 * 430 *
1617 * If the connection coincides, the c member of path is set to the connection 431 * @param cti connection identifier where we got an ACK for a message
1618 * and the destroy flag of the connection is set. 432 * that was originally sent via this connection (the ACK
1619 * 433 * may have gotten back to us via a different connection).
1620 * @param cls Closure (new path).
1621 * @param c Connection in the tunnel to check.
1622 */ 434 */
1623static void 435void
1624check_path (void *cls, struct CadetConnection *c) 436GCC_ack_observed (const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
1625{ 437{
1626 struct CadetConnection *new_conn = cls; 438 struct CadetConnection *cc;
1627 struct CadetPeerPath *path = new_conn->path;
1628
1629 LOG (GNUNET_ERROR_TYPE_DEBUG, " checking %s (%p), length %u\n",
1630 GCC_2s (c), c, c->path->length);
1631 439
1632 if (c != new_conn 440 cc = GCC_lookup (cid);
1633 && GNUNET_NO == c->destroy 441 if (NULL == cc)
1634 && CADET_CONNECTION_BROKEN != c->state 442 return; /* whopise, connection alredy down? */
1635 && CADET_CONNECTION_DESTROYED != c->state 443 cc->metrics.num_successes++;
1636 && path_equivalent (path, c->path))
1637 {
1638 new_conn->destroy = GNUNET_YES; /* Do not mark_destroyed, */
1639 new_conn->path->c = c; /* this is only a flag for the Iterator. */
1640 LOG (GNUNET_ERROR_TYPE_DEBUG, " MATCH!\n");
1641 }
1642} 444}
1643 445
1644 446
1645/** 447/**
1646 * Finds out if this path is already being used by an existing connection. 448 * We observed some the given @a latency on the connection
1647 * 449 * identified by @a cti. (The same connection was taken
1648 * Checks the tunnel towards the destination to see if it contains 450 * in both directions.)
1649 * any connection with the same path.
1650 * 451 *
1651 * If the existing connection is ready, it is kept. 452 * @param cid connection identifier where we measured latency
1652 * Otherwise if the sender has a smaller ID that ours, we accept it (and 453 * @param latency the observed latency
1653 * the peer will eventually reject our attempt).
1654 *
1655 * @param path Path to check.
1656 * @return #GNUNET_YES if the tunnel has a connection with the same path,
1657 * #GNUNET_NO otherwise.
1658 */ 454 */
1659static int 455void
1660does_connection_exist (struct CadetConnection *conn) 456GCC_latency_observed (const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
457 struct GNUNET_TIME_Relative latency)
1661{ 458{
1662 struct CadetPeer *p; 459 struct CadetConnection *cc;
1663 struct CadetTunnel *t; 460 double weight;
1664 struct CadetConnection *c; 461 double result;
1665
1666 p = GCP_get_short (conn->path->peers[0], GNUNET_NO);
1667 if (NULL == p)
1668 return GNUNET_NO;
1669 t = GCP_get_tunnel (p);
1670 if (NULL == t)
1671 return GNUNET_NO;
1672
1673 LOG (GNUNET_ERROR_TYPE_DEBUG, "Checking for duplicates\n");
1674 462
1675 GCT_iterate_connections (t, &check_path, conn); 463 cc = GCC_lookup (cid);
1676 464 if (NULL == cc)
1677 if (GNUNET_YES == conn->destroy) 465 return; /* whopise, connection alredy down? */
1678 { 466 GNUNET_STATISTICS_update (stats,
1679 c = conn->path->c; 467 "# latencies observed",
1680 conn->destroy = GNUNET_NO; 468 1,
1681 conn->path->c = conn; 469 GNUNET_NO);
1682 LOG (GNUNET_ERROR_TYPE_DEBUG, " found duplicate of %s\n", GCC_2s (conn)); 470 cc->latency_datapoints++;
1683 LOG (GNUNET_ERROR_TYPE_DEBUG, " duplicate: %s\n", GCC_2s (c)); 471 if (cc->latency_datapoints >= 7)
1684 GCC_debug (c, GNUNET_ERROR_TYPE_DEBUG); 472 weight = 7.0;
1685 if (CADET_CONNECTION_READY == c->state)
1686 {
1687 /* The other peer confirmed a live connection with this path,
1688 * why are they trying to duplicate it? */
1689 GNUNET_STATISTICS_update (stats, "# duplicate connections", 1, GNUNET_NO);
1690 return GNUNET_YES;
1691 }
1692 LOG (GNUNET_ERROR_TYPE_DEBUG, " duplicate not ready, connection unique\n");
1693 return GNUNET_NO;
1694 }
1695 else 473 else
1696 { 474 weight = cc->latency_datapoints;
1697 LOG (GNUNET_ERROR_TYPE_DEBUG, " %s has no duplicates\n", GCC_2s (conn)); 475 /* Compute weighted average, giving at MOST weight 7 to the
1698 return GNUNET_NO; 476 existing values, or less if that value is based on fewer than 7
1699 } 477 measurements. */
478 result = (weight * cc->metrics.aged_latency.rel_value_us) + 1.0 * latency.rel_value_us;
479 result /= (weight + 1.0);
480 cc->metrics.aged_latency.rel_value_us = (uint64_t) result;
1700} 481}
1701 482
1702 483
1703/** 484/**
1704 * @brief Check if the tunnel this connection belongs to has any other 485 * A #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK was received for this connection, implying
1705 * connection with the same path, and destroy one if so. 486 * that the end-to-end connection is up. Process it.
1706 * 487 *
1707 * @param cls Closure (connection to check). 488 * @param cc the connection that got the ACK.
1708 */
1709static void
1710check_duplicates (void *cls)
1711{
1712 struct CadetConnection *c = cls;
1713
1714 c->check_duplicates_task = NULL;
1715 if (GNUNET_YES == does_connection_exist (c))
1716 {
1717 GCT_debug (c->t, GNUNET_ERROR_TYPE_DEBUG);
1718 send_broken (c, &my_full_id, &my_full_id, GCC_is_origin (c, GNUNET_YES));
1719 GCC_destroy (c);
1720 }
1721}
1722
1723
1724/**
1725 * Wait for enough time to let any dead connections time out and check for
1726 * any remaining duplicates.
1727 *
1728 * @param c Connection that is a potential duplicate.
1729 */
1730static void
1731schedule_check_duplicates (struct CadetConnection *c)
1732{
1733 struct GNUNET_TIME_Relative delay;
1734
1735 if (NULL != c->check_duplicates_task)
1736 return;
1737 delay = GNUNET_TIME_relative_saturating_multiply (refresh_connection_time, 5);
1738 c->check_duplicates_task = GNUNET_SCHEDULER_add_delayed (delay,
1739 &check_duplicates,
1740 c);
1741}
1742
1743
1744/**
1745 * Add the connection to the list of both neighbors.
1746 *
1747 * @param c Connection.
1748 *
1749 * @return #GNUNET_OK if everything went fine
1750 * #GNUNET_SYSERR if the was an error and @c c is malformed.
1751 */
1752static int
1753register_neighbors (struct CadetConnection *c)
1754{
1755 c->next_peer = get_next_hop (c);
1756 c->prev_peer = get_prev_hop (c);
1757 GNUNET_assert (c->next_peer != c->prev_peer);
1758 LOG (GNUNET_ERROR_TYPE_DEBUG,
1759 "register neighbors for connection %s\n",
1760 GCC_2s (c));
1761 path_debug (c->path);
1762 LOG (GNUNET_ERROR_TYPE_DEBUG,
1763 "own pos %u\n", c->own_pos);
1764 LOG (GNUNET_ERROR_TYPE_DEBUG,
1765 "putting connection %s to next peer %p\n",
1766 GCC_2s (c),
1767 c->next_peer);
1768 LOG (GNUNET_ERROR_TYPE_DEBUG, "next peer %p %s\n",
1769 c->next_peer,
1770 GCP_2s (c->next_peer));
1771 LOG (GNUNET_ERROR_TYPE_DEBUG,
1772 "putting connection %s to prev peer %p\n",
1773 GCC_2s (c),
1774 c->prev_peer);
1775 LOG (GNUNET_ERROR_TYPE_DEBUG,
1776 "prev peer %p %s\n",
1777 c->prev_peer,
1778 GCP_2s (c->prev_peer));
1779
1780 if ( (GNUNET_NO == GCP_is_neighbor (c->next_peer)) ||
1781 (GNUNET_NO == GCP_is_neighbor (c->prev_peer)) )
1782 {
1783 if (GCC_is_origin (c, GNUNET_YES))
1784 GNUNET_STATISTICS_update (stats, "# local bad paths", 1, GNUNET_NO);
1785 GNUNET_STATISTICS_update (stats, "# bad paths", 1, GNUNET_NO);
1786
1787 LOG (GNUNET_ERROR_TYPE_DEBUG,
1788 " register neighbors failed\n");
1789 LOG (GNUNET_ERROR_TYPE_DEBUG,
1790 " prev: %s, neighbor?: %d\n",
1791 GCP_2s (c->prev_peer),
1792 GCP_is_neighbor (c->prev_peer));
1793 LOG (GNUNET_ERROR_TYPE_DEBUG,
1794 " next: %s, neighbor?: %d\n",
1795 GCP_2s (c->next_peer),
1796 GCP_is_neighbor (c->next_peer));
1797 return GNUNET_SYSERR;
1798 }
1799 GCP_add_connection (c->next_peer, c, GNUNET_NO);
1800 GCP_add_connection (c->prev_peer, c, GNUNET_YES);
1801
1802 return GNUNET_OK;
1803}
1804
1805
1806/**
1807 * Remove the connection from the list of both neighbors.
1808 *
1809 * @param c Connection.
1810 */
1811static void
1812unregister_neighbors (struct CadetConnection *c)
1813{
1814// struct CadetPeer *peer; FIXME dont use next_peer, prev_peer
1815 /* Either already unregistered or never got registered, it's ok either way. */
1816 if (NULL == c->path)
1817 return;
1818 if (NULL != c->next_peer)
1819 {
1820 GCP_remove_connection (c->next_peer, c);
1821 c->next_peer = NULL;
1822 }
1823 if (NULL != c->prev_peer)
1824 {
1825 GCP_remove_connection (c->prev_peer, c);
1826 c->prev_peer = NULL;
1827 }
1828}
1829
1830
1831/**
1832 * Invalidates all paths towards all peers that comprise the connection which
1833 * rely on the disconnected peer.
1834 *
1835 * ~O(n^3) (peers in connection * paths/peer * links/path)
1836 *
1837 * @param c Connection whose peers' paths to clean.
1838 * @param disconnected Peer that disconnected.
1839 */
1840static void
1841invalidate_paths (struct CadetConnection *c,
1842 struct CadetPeer *disconnected)
1843{
1844 struct CadetPeer *peer;
1845 unsigned int i;
1846
1847 for (i = 0; i < c->path->length; i++)
1848 {
1849 peer = GCP_get_short (c->path->peers[i], GNUNET_NO);
1850 if (NULL != peer)
1851 GCP_notify_broken_link (peer, &my_full_id, GCP_get_id (disconnected));
1852 }
1853}
1854
1855
1856/**
1857 * Bind the connection to the peer and the tunnel to that peer.
1858 *
1859 * If the peer has no tunnel, create one. Update tunnel and connection
1860 * data structres to reflect new status.
1861 *
1862 * @param c Connection.
1863 * @param peer Peer.
1864 */
1865static void
1866add_to_peer (struct CadetConnection *c,
1867 struct CadetPeer *peer)
1868{
1869 GCP_add_tunnel (peer);
1870 c->t = GCP_get_tunnel (peer);
1871 GCT_add_connection (c->t, c);
1872}
1873
1874
1875/**
1876 * Log receipt of message on stderr (INFO level).
1877 *
1878 * @param message Message received.
1879 * @param peer Peer who sent the message.
1880 * @param conn_id Connection ID of the message.
1881 */
1882static void
1883log_message (const struct GNUNET_MessageHeader *message,
1884 const struct CadetPeer *peer,
1885 const struct GNUNET_CADET_ConnectionTunnelIdentifier *conn_id)
1886{
1887 uint16_t size;
1888 uint16_t type;
1889 char *arrow;
1890
1891 size = ntohs (message->size);
1892 type = ntohs (message->type);
1893 switch (type)
1894 {
1895 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE:
1896 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK:
1897 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN:
1898 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY:
1899 arrow = "==";
1900 break;
1901 default:
1902 arrow = "--";
1903 }
1904 LOG (GNUNET_ERROR_TYPE_INFO,
1905 "<%s %s on conn %s from %s, %6u bytes\n",
1906 arrow,
1907 GC_m2s (type),
1908 GNUNET_sh2s (&conn_id->connection_of_tunnel),
1909 GCP_2s(peer),
1910 (unsigned int) size);
1911}
1912
1913/******************************************************************************/
1914/******************************** API ***********************************/
1915/******************************************************************************/
1916
1917/**
1918 * Handler for connection creation.
1919 *
1920 * @param peer Message sender (neighbor).
1921 * @param msg Message itself.
1922 */ 489 */
1923void 490void
1924GCC_handle_create (struct CadetPeer *peer, 491GCC_handle_connection_create_ack (struct CadetConnection *cc)
1925 const struct GNUNET_CADET_ConnectionCreateMessage *msg)
1926{ 492{
1927 static struct CadetEncryptedMessageIdentifier zero; 493 LOG (GNUNET_ERROR_TYPE_DEBUG,
1928 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid; 494 "Received CADET_CONNECTION_CREATE_ACK for %s in state %d (%s)\n",
1929 struct GNUNET_PeerIdentity *id; 495 GCC_2s (cc),
1930 struct CadetPeerPath *path; 496 cc->state,
1931 struct CadetPeer *dest_peer; 497 (GNUNET_YES == cc->mqm_ready) ? "MQM ready" : "MQM busy");
1932 struct CadetPeer *orig_peer; 498 if (CADET_CONNECTION_READY == cc->state)
1933 struct CadetConnection *c; 499 return; /* Duplicate ACK, ignore */
1934 unsigned int own_pos; 500 if (NULL != cc->task)
1935 uint16_t size;
1936
1937 GCC_check_connections ();
1938 size = ntohs (msg->header.size);
1939
1940 /* Calculate hops */
1941 size -= sizeof (struct GNUNET_CADET_ConnectionCreateMessage);
1942 if (0 != size % sizeof (struct GNUNET_PeerIdentity))
1943 {
1944 GNUNET_break_op (0);
1945 return;
1946 }
1947 size /= sizeof (struct GNUNET_PeerIdentity);
1948 if (1 > size)
1949 {
1950 GNUNET_break_op (0);
1951 return;
1952 }
1953 LOG (GNUNET_ERROR_TYPE_DEBUG, " path has %u hops.\n", size);
1954
1955 /* Get parameters */
1956 cid = &msg->cid;
1957 log_message (&msg->header, peer, cid);
1958 id = (struct GNUNET_PeerIdentity *) &msg[1];
1959 LOG (GNUNET_ERROR_TYPE_DEBUG, " origin: %s\n", GNUNET_i2s (id));
1960
1961 /* Create connection */
1962 c = connection_get (cid);
1963 if (NULL == c)
1964 {
1965 path = path_build_from_peer_ids ((struct GNUNET_PeerIdentity *) &msg[1],
1966 size, myid, &own_pos);
1967 if (NULL == path)
1968 {
1969 /* Path was malformed, probably our own ID was not in it. */
1970 GNUNET_STATISTICS_update (stats, "# malformed paths", 1, GNUNET_NO);
1971 GNUNET_break_op (0);
1972 return;
1973 }
1974 if (0 == own_pos)
1975 {
1976 /* We received this request from a neighbor, we cannot be origin */
1977 GNUNET_STATISTICS_update (stats, "# fake paths", 1, GNUNET_NO);
1978 GNUNET_break_op (0);
1979 path_destroy (path);
1980 return;
1981 }
1982
1983 LOG (GNUNET_ERROR_TYPE_DEBUG, " Own position: %u\n", own_pos);
1984 LOG (GNUNET_ERROR_TYPE_DEBUG, " Creating connection\n");
1985 c = GCC_new (cid, NULL, path, own_pos);
1986 if (NULL == c)
1987 {
1988 if (path->length - 1 == own_pos)
1989 {
1990 /* If we are destination, why did the creation fail? */
1991 GNUNET_break (0);
1992 path_destroy (path);
1993 GCC_check_connections ();
1994 return;
1995 }
1996 send_broken_unknown (cid, &my_full_id,
1997 GNUNET_PEER_resolve2 (path->peers[own_pos + 1]),
1998 peer);
1999 path_destroy (path);
2000 GCC_check_connections ();
2001 return;
2002 }
2003 GCP_add_path_to_all (path, GNUNET_NO);
2004 connection_reset_timeout (c, GNUNET_YES);
2005 }
2006 else
2007 {
2008 path = path_duplicate (c->path);
2009 }
2010 if (CADET_CONNECTION_NEW == c->state)
2011 connection_change_state (c, CADET_CONNECTION_SENT);
2012
2013 /* Remember peers */
2014 dest_peer = GCP_get (&id[size - 1], GNUNET_YES);
2015 orig_peer = GCP_get (&id[0], GNUNET_YES);
2016
2017 /* Is it a connection to us? */
2018 if (c->own_pos == path->length - 1)
2019 {
2020 LOG (GNUNET_ERROR_TYPE_DEBUG, " It's for us!\n");
2021 GCP_add_path_to_origin (orig_peer, path_duplicate (path), GNUNET_YES);
2022
2023 add_to_peer (c, orig_peer);
2024 if (GNUNET_YES == does_connection_exist (c))
2025 {
2026 /* Peer created a connection equal to one we think exists
2027 * and is fine.
2028 * Solution: Keep both and postpone disambiguation. In the meantime
2029 * the connection will time out or peer will inform us it is broken.
2030 *
2031 * Other options:
2032 * - Use explicit duplicate.
2033 * - Accept new conn and destroy the old. (interruption in higher level)
2034 * - Keep the one with higher ID / created by peer with higher ID. */
2035 schedule_check_duplicates (c);
2036 }
2037
2038 if (CADET_TUNNEL_NEW == GCT_get_cstate (c->t))
2039 GCT_change_cstate (c->t, CADET_TUNNEL_WAITING);
2040 if (NULL == c->maintenance_q)
2041 send_connection_ack (c, GNUNET_NO);
2042 if (CADET_CONNECTION_SENT == c->state)
2043 connection_change_state (c, CADET_CONNECTION_ACK);
2044 }
2045 else
2046 { 501 {
2047 LOG (GNUNET_ERROR_TYPE_DEBUG, " not for us, retransmitting...\n"); 502 GNUNET_SCHEDULER_cancel (cc->task);
2048 GCP_add_path (dest_peer, path_duplicate (path), GNUNET_NO); 503 cc->task = NULL;
2049 GCP_add_path_to_origin (orig_peer, path_duplicate (path), GNUNET_NO);
2050 (void) GCC_send_prebuilt_message (&msg->header,
2051 0,
2052 zero,
2053 c,
2054 GNUNET_YES, GNUNET_YES,
2055 NULL, NULL);
2056 } 504 }
2057 path_destroy (path); 505 cc->metrics.age = GNUNET_TIME_absolute_get ();
2058 GCC_check_connections (); 506 update_state (cc,
507 CADET_CONNECTION_READY,
508 cc->mqm_ready);
509 if ( (NULL == cc->keepalive_qe) &&
510 (GNUNET_YES == cc->mqm_ready) &&
511 (NULL == cc->task) )
512 cc->task = GNUNET_SCHEDULER_add_delayed (keepalive_period,
513 &send_keepalive,
514 cc);
2059} 515}
2060 516
2061 517
2062/** 518/**
2063 * Handler for connection confirmations. 519 * Handle KX message.
2064 * 520 *
2065 * @param peer Message sender (neighbor). 521 * @param cc connection that received encrypted message
2066 * @param msg Message itself. 522 * @param msg the key exchange message
2067 */ 523 */
2068void 524void
2069GCC_handle_confirm (struct CadetPeer *peer, 525GCC_handle_kx (struct CadetConnection *cc,
2070 const struct GNUNET_CADET_ConnectionCreateAckMessage *msg) 526 const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg)
2071{ 527{
2072 static struct CadetEncryptedMessageIdentifier zero; 528 if (CADET_CONNECTION_SENT == cc->state)
2073 struct CadetConnection *c;
2074 enum CadetConnectionState oldstate;
2075 int fwd;
2076
2077 GCC_check_connections ();
2078 log_message (&msg->header, peer, &msg->cid);
2079 c = connection_get (&msg->cid);
2080 if (NULL == c)
2081 {
2082 GNUNET_STATISTICS_update (stats, "# control on unknown connection",
2083 1, GNUNET_NO);
2084 LOG (GNUNET_ERROR_TYPE_DEBUG,
2085 " don't know the connection!\n");
2086 send_broken_unknown (&msg->cid, &my_full_id, NULL, peer);
2087 GCC_check_connections ();
2088 return;
2089 }
2090 if (GNUNET_NO != c->destroy)
2091 { 529 {
2092 GNUNET_assert (CADET_CONNECTION_DESTROYED == c->state); 530 /* We didn't get the CADET_CONNECTION_CREATE_ACK, but instead got payload. That's fine,
2093 GNUNET_STATISTICS_update (stats, "# control on dying connection", 531 clearly something is working, so pretend we got an ACK. */
2094 1, GNUNET_NO);
2095 LOG (GNUNET_ERROR_TYPE_DEBUG, 532 LOG (GNUNET_ERROR_TYPE_DEBUG,
2096 "connection %s being destroyed, ignoring confirm\n", 533 "Faking connection CADET_CONNECTION_CREATE_ACK for %s due to KX\n",
2097 GCC_2s (c)); 534 GCC_2s (cc));
2098 GCC_check_connections (); 535 GCC_handle_connection_create_ack (cc);
2099 return;
2100 }
2101
2102 oldstate = c->state;
2103 LOG (GNUNET_ERROR_TYPE_DEBUG, " via peer %s\n", GCP_2s (peer));
2104 if (get_next_hop (c) == peer)
2105 {
2106 LOG (GNUNET_ERROR_TYPE_DEBUG, " SYNACK\n");
2107 fwd = GNUNET_NO;
2108 if (CADET_CONNECTION_SENT == oldstate)
2109 connection_change_state (c, CADET_CONNECTION_ACK);
2110 }
2111 else if (get_prev_hop (c) == peer)
2112 {
2113 LOG (GNUNET_ERROR_TYPE_DEBUG, " FINAL ACK\n");
2114 fwd = GNUNET_YES;
2115 connection_change_state (c, CADET_CONNECTION_READY);
2116 }
2117 else
2118 {
2119 GNUNET_STATISTICS_update (stats, "# control on connection from wrong peer",
2120 1, GNUNET_NO);
2121 GNUNET_break_op (0);
2122 return;
2123 }
2124
2125 connection_reset_timeout (c, fwd);
2126
2127 GNUNET_assert (NULL != c->path);
2128 GCP_add_path_to_all (c->path, GNUNET_YES);
2129
2130 /* Message for us as creator? */
2131 if (GNUNET_YES == GCC_is_origin (c, GNUNET_YES))
2132 {
2133 if (GNUNET_NO != fwd)
2134 {
2135 GNUNET_break (0);
2136 return;
2137 }
2138 LOG (GNUNET_ERROR_TYPE_DEBUG, " Connection (SYN)ACK for us!\n");
2139
2140 /* If just created, cancel the short timeout and start a long one */
2141 if (CADET_CONNECTION_SENT == oldstate)
2142 {
2143 c->create_retry = 1;
2144 connection_reset_timeout (c, GNUNET_YES);
2145 }
2146
2147 /* Change connection state, send ACK */
2148 connection_change_state (c, CADET_CONNECTION_READY);
2149 send_connection_ack (c, GNUNET_YES);
2150
2151 /* Change tunnel state, trigger KX */
2152 if (CADET_TUNNEL_WAITING == GCT_get_cstate (c->t))
2153 GCT_change_cstate (c->t, CADET_TUNNEL_READY);
2154 GCC_check_connections ();
2155 return;
2156 }
2157
2158 /* Message for us as destination? */
2159 if (GCC_is_terminal (c, GNUNET_YES))
2160 {
2161 if (GNUNET_YES != fwd)
2162 {
2163 GNUNET_break (0);
2164 return;
2165 }
2166 LOG (GNUNET_ERROR_TYPE_DEBUG, " Connection ACK for us!\n");
2167
2168 /* If just created, cancel the short timeout and start a long one */
2169 if (CADET_CONNECTION_ACK == oldstate)
2170 connection_reset_timeout (c, GNUNET_NO);
2171
2172 /* Change tunnel state */
2173 if (CADET_TUNNEL_WAITING == GCT_get_cstate (c->t))
2174 GCT_change_cstate (c->t, CADET_TUNNEL_READY);
2175 GCC_check_connections ();
2176 } 536 }
2177 else 537 GCT_handle_kx (cc->ct,
2178 { 538 msg);
2179 LOG (GNUNET_ERROR_TYPE_DEBUG, " not for us, retransmitting...\n");
2180 (void) GCC_send_prebuilt_message (&msg->header, 0,
2181 zero,
2182 c,
2183 fwd,
2184 GNUNET_YES, NULL, NULL);
2185 }
2186 GCC_check_connections ();
2187} 539}
2188 540
2189 541
2190/** 542/**
2191 * Handler for notifications of broken connections. 543 * Handle KX_AUTH message.
2192 * 544 *
2193 * @param peer Message sender (neighbor). 545 * @param cc connection that received encrypted message
2194 * @param msg Message itself. 546 * @param msg the key exchange message
2195 */ 547 */
2196void 548void
2197GCC_handle_broken (struct CadetPeer *peer, 549GCC_handle_kx_auth (struct CadetConnection *cc,
2198 const struct GNUNET_CADET_ConnectionBrokenMessage *msg) 550 const struct GNUNET_CADET_TunnelKeyExchangeAuthMessage *msg)
2199{ 551{
2200 static struct CadetEncryptedMessageIdentifier zero; 552 if (CADET_CONNECTION_SENT == cc->state)
2201 struct CadetConnection *c;
2202 struct CadetTunnel *t;
2203 int fwd;
2204
2205 GCC_check_connections ();
2206 log_message (&msg->header, peer, &msg->cid);
2207 LOG (GNUNET_ERROR_TYPE_DEBUG, " regarding %s\n", GNUNET_i2s (&msg->peer1));
2208 LOG (GNUNET_ERROR_TYPE_DEBUG, " regarding %s\n", GNUNET_i2s (&msg->peer2));
2209 c = connection_get (&msg->cid);
2210 if (NULL == c)
2211 {
2212 LOG (GNUNET_ERROR_TYPE_DEBUG, " duplicate CONNECTION_BROKEN\n");
2213 GNUNET_STATISTICS_update (stats, "# duplicate CONNECTION_BROKEN",
2214 1, GNUNET_NO);
2215 GCC_check_connections ();
2216 return;
2217 }
2218
2219 t = c->t;
2220
2221 fwd = is_fwd (c, peer);
2222 if (GNUNET_SYSERR == fwd)
2223 {
2224 GNUNET_break_op (0);
2225 GCC_check_connections ();
2226 return;
2227 }
2228 mark_destroyed (c);
2229 if (GCC_is_terminal (c, fwd))
2230 {
2231 struct CadetPeer *endpoint;
2232
2233 if (NULL == t)
2234 {
2235 /* A terminal connection should not have 't' set to NULL. */
2236 GNUNET_break (0);
2237 GCC_debug (c, GNUNET_ERROR_TYPE_ERROR);
2238 return;
2239 }
2240 endpoint = GCP_get_short (c->path->peers[c->path->length - 1], GNUNET_YES);
2241 if (2 < c->path->length)
2242 path_invalidate (c->path);
2243 GCP_notify_broken_link (endpoint, &msg->peer1, &msg->peer2);
2244
2245 connection_change_state (c, CADET_CONNECTION_BROKEN);
2246 GCT_remove_connection (t, c);
2247 c->t = NULL;
2248
2249 GCC_destroy (c);
2250 }
2251 else
2252 { 553 {
2253 (void) GCC_send_prebuilt_message (&msg->header, 0, 554 /* We didn't get the CADET_CONNECTION_CREATE_ACK, but instead got payload. That's fine,
2254 zero, c, fwd, 555 clearly something is working, so pretend we got an ACK. */
2255 GNUNET_YES, NULL, NULL); 556 LOG (GNUNET_ERROR_TYPE_DEBUG,
2256 connection_cancel_queues (c, !fwd); 557 "Faking connection CADET_CONNECTION_CREATE_ACK for %s due to KX\n",
558 GCC_2s (cc));
559 GCC_handle_connection_create_ack (cc);
2257 } 560 }
2258 GCC_check_connections (); 561 GCT_handle_kx_auth (cc->ct,
2259 return; 562 msg);
2260} 563}
2261 564
2262 565
2263/** 566/**
2264 * Handler for notifications of destroyed connections. 567 * Handle encrypted message.
2265 * 568 *
2266 * @param peer Message sender (neighbor). 569 * @param cc connection that received encrypted message
2267 * @param msg Message itself. 570 * @param msg the encrypted message to decrypt
2268 */ 571 */
2269void 572void
2270GCC_handle_destroy (struct CadetPeer *peer, 573GCC_handle_encrypted (struct CadetConnection *cc,
2271 const struct GNUNET_CADET_ConnectionDestroyMessage *msg) 574 const struct GNUNET_CADET_TunnelEncryptedMessage *msg)
2272{ 575{
2273 static struct CadetEncryptedMessageIdentifier zero; 576 if (CADET_CONNECTION_SENT == cc->state)
2274 struct CadetConnection *c;
2275 int fwd;
2276
2277 GCC_check_connections ();
2278 log_message (&msg->header, peer, &msg->cid);
2279 c = connection_get (&msg->cid);
2280 if (NULL == c)
2281 { 577 {
2282 /* Probably already got the message from another path, 578 /* We didn't get the CREATE_ACK, but instead got payload. That's fine,
2283 * destroyed the tunnel and retransmitted to children. 579 clearly something is working, so pretend we got an ACK. */
2284 * Safe to ignore.
2285 */
2286 GNUNET_STATISTICS_update (stats,
2287 "# control on unknown connection",
2288 1, GNUNET_NO);
2289 LOG (GNUNET_ERROR_TYPE_DEBUG, 580 LOG (GNUNET_ERROR_TYPE_DEBUG,
2290 " connection unknown destroyed: previously destroyed?\n"); 581 "Faking connection ACK for %s due to ENCRYPTED payload\n",
2291 GCC_check_connections (); 582 GCC_2s (cc));
2292 return; 583 GCC_handle_connection_create_ack (cc);
2293 }
2294
2295 fwd = is_fwd (c, peer);
2296 if (GNUNET_SYSERR == fwd)
2297 {
2298 GNUNET_break_op (0);
2299 GCC_check_connections ();
2300 return;
2301 }
2302
2303 if (GNUNET_NO == GCC_is_terminal (c, fwd))
2304 {
2305 (void) GCC_send_prebuilt_message (&msg->header, 0,
2306 zero, c, fwd,
2307 GNUNET_YES, NULL, NULL);
2308 } 584 }
2309 else if (0 == c->pending_messages) 585 cc->metrics.last_use = GNUNET_TIME_absolute_get ();
2310 { 586 GCT_handle_encrypted (cc->ct,
2311 LOG (GNUNET_ERROR_TYPE_DEBUG, " directly destroying connection!\n"); 587 msg);
2312 GCC_destroy (c);
2313 GCC_check_connections ();
2314 return;
2315 }
2316 mark_destroyed (c);
2317 if (NULL != c->t)
2318 {
2319 GCT_remove_connection (c->t, c);
2320 c->t = NULL;
2321 }
2322 GCC_check_connections ();
2323 return;
2324} 588}
2325 589
2326 590
2327/** 591/**
2328 * Handler for cadet network traffic hop-by-hop acks. 592 * Send a #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE message to the
593 * first hop.
2329 * 594 *
2330 * @param peer Message sender (neighbor). 595 * @param cls the `struct CadetConnection` to initiate
2331 * @param msg Message itself.
2332 */ 596 */
2333void 597static void
2334GCC_handle_ack (struct CadetPeer *peer, 598send_create (void *cls)
2335 const struct GNUNET_CADET_ConnectionEncryptedAckMessage *msg) 599{
2336{ 600 struct CadetConnection *cc = cls;
2337 struct CadetConnection *c; 601 struct GNUNET_CADET_ConnectionCreateMessage *create_msg;
2338 struct CadetFlowControl *fc; 602 struct GNUNET_PeerIdentity *pids;
2339 struct CadetEncryptedMessageIdentifier ack; 603 struct GNUNET_MQ_Envelope *env;
2340 int fwd; 604 unsigned int path_length;
2341 605
2342 GCC_check_connections (); 606 cc->task = NULL;
2343 log_message (&msg->header, peer, &msg->cid); 607 GNUNET_assert (GNUNET_YES == cc->mqm_ready);
2344 c = connection_get (&msg->cid); 608 path_length = GCPP_get_length (cc->path);
2345 if (NULL == c) 609 env = GNUNET_MQ_msg_extra (create_msg,
2346 { 610 (1 + path_length) * sizeof (struct GNUNET_PeerIdentity),
2347 GNUNET_STATISTICS_update (stats, 611 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE);
2348 "# ack on unknown connection", 612 create_msg->options = htonl ((uint32_t) cc->options);
2349 1, 613 create_msg->cid = cc->cid;
2350 GNUNET_NO); 614 pids = (struct GNUNET_PeerIdentity *) &create_msg[1];
2351 send_broken_unknown (&msg->cid, 615 pids[0] = my_full_id;
2352 &my_full_id, 616 for (unsigned int i=0;i<path_length;i++)
2353 NULL, 617 pids[i + 1] = *GCP_get_id (GCPP_get_peer_at_offset (cc->path,
2354 peer); 618 i));
2355 GCC_check_connections (); 619 LOG (GNUNET_ERROR_TYPE_DEBUG,
2356 return; 620 "Sending CADET_CONNECTION_CREATE message for %s\n",
2357 } 621 GCC_2s (cc));
2358 622 cc->env = env;
2359 /* Is this a forward or backward ACK? */ 623 update_state (cc,
2360 if (get_next_hop (c) == peer) 624 CADET_CONNECTION_SENT,
2361 { 625 GNUNET_NO);
2362 fc = &c->fwd_fc; 626 GCP_send (cc->mq_man,
2363 fwd = GNUNET_YES; 627 env);
2364 }
2365 else if (get_prev_hop (c) == peer)
2366 {
2367 fc = &c->bck_fc;
2368 fwd = GNUNET_NO;
2369 }
2370 else
2371 {
2372 GNUNET_break_op (0);
2373 return;
2374 }
2375
2376 ack = msg->cemi_max;
2377 LOG (GNUNET_ERROR_TYPE_DEBUG, " %s ACK %u (was %u)\n",
2378 GC_f2s (fwd),
2379 ntohl (ack.pid),
2380 ntohl (fc->last_ack_recv.pid));
2381 if (GC_is_pid_bigger (ntohl (ack.pid),
2382 ntohl (fc->last_ack_recv.pid)))
2383 fc->last_ack_recv = ack;
2384
2385 /* Cancel polling if the ACK is big enough. */
2386 if ( (NULL != fc->poll_task) &
2387 GC_is_pid_bigger (ntohl (fc->last_ack_recv.pid),
2388 ntohl (fc->last_pid_sent.pid)))
2389 {
2390 LOG (GNUNET_ERROR_TYPE_DEBUG, " Cancel poll\n");
2391 GNUNET_SCHEDULER_cancel (fc->poll_task);
2392 fc->poll_task = NULL;
2393 fc->poll_time = GNUNET_TIME_UNIT_SECONDS;
2394 }
2395
2396 GCC_check_connections ();
2397} 628}
2398 629
2399 630
2400/** 631/**
2401 * Handler for cadet network traffic hop-by-hop data counter polls. 632 * Send a CREATE_ACK message towards the origin.
2402 * 633 *
2403 * @param peer Message sender (neighbor). 634 * @param cls the `struct CadetConnection` to initiate
2404 * @param msg Message itself.
2405 */ 635 */
2406void 636static void
2407GCC_handle_poll (struct CadetPeer *peer, 637send_create_ack (void *cls)
2408 const struct GNUNET_CADET_ConnectionHopByHopPollMessage *msg)
2409{ 638{
2410 struct CadetConnection *c; 639 struct CadetConnection *cc = cls;
2411 struct CadetFlowControl *fc; 640 struct GNUNET_CADET_ConnectionCreateAckMessage *ack_msg;
2412 struct CadetEncryptedMessageIdentifier pid; 641 struct GNUNET_MQ_Envelope *env;
2413 int fwd;
2414
2415 GCC_check_connections ();
2416 log_message (&msg->header, peer, &msg->cid);
2417 c = connection_get (&msg->cid);
2418 if (NULL == c)
2419 {
2420 GNUNET_STATISTICS_update (stats, "# poll on unknown connection", 1,
2421 GNUNET_NO);
2422 LOG (GNUNET_ERROR_TYPE_DEBUG,
2423 "POLL message on unknown connection %s!\n",
2424 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
2425 send_broken_unknown (&msg->cid,
2426 &my_full_id,
2427 NULL,
2428 peer);
2429 GCC_check_connections ();
2430 return;
2431 }
2432
2433 /* Is this a forward or backward ACK?
2434 * Note: a poll should never be needed in a loopback case,
2435 * since there is no possiblility of packet loss there, so
2436 * this way of discerining FWD/BCK should not be a problem.
2437 */
2438 if (get_next_hop (c) == peer)
2439 {
2440 LOG (GNUNET_ERROR_TYPE_DEBUG, " FWD FC\n");
2441 fc = &c->fwd_fc;
2442 }
2443 else if (get_prev_hop (c) == peer)
2444 {
2445 LOG (GNUNET_ERROR_TYPE_DEBUG, " BCK FC\n");
2446 fc = &c->bck_fc;
2447 }
2448 else
2449 {
2450 GNUNET_break_op (0);
2451 return;
2452 }
2453 642
2454 pid = msg->cemi; 643 cc->task = NULL;
644 GNUNET_assert (CADET_CONNECTION_CREATE_RECEIVED == cc->state);
2455 LOG (GNUNET_ERROR_TYPE_DEBUG, 645 LOG (GNUNET_ERROR_TYPE_DEBUG,
2456 " PID %u, OLD %u\n", 646 "Sending CONNECTION_CREATE_ACK message for %s\n",
2457 ntohl (pid.pid), 647 GCC_2s (cc));
2458 ntohl (fc->last_pid_recv.pid)); 648 GNUNET_assert (GNUNET_YES == cc->mqm_ready);
2459 fc->last_pid_recv = pid; 649 env = GNUNET_MQ_msg (ack_msg,
2460 fwd = fc == &c->bck_fc; 650 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK);
2461 GCC_send_ack (c, fwd, GNUNET_YES); 651 ack_msg->cid = cc->cid;
2462 GCC_check_connections (); 652 cc->env = env;
653 update_state (cc,
654 CADET_CONNECTION_READY,
655 GNUNET_NO);
656 GCP_send (cc->mq_man,
657 env);
2463} 658}
2464 659
2465 660
2466/** 661/**
2467 * Check the message against internal state and test if it goes FWD or BCK. 662 * We got a #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE for a
2468 * 663 * connection that we already have. Either our ACK got lost
2469 * Updates the PID, state and timeout values for the connection. 664 * or something is fishy. Consider retransmitting the ACK.
2470 *
2471 * @param message Message to check. It must belong to an existing connection.
2472 * @param cid Connection ID (even if @a c is NULL, the ID is still needed).
2473 * @param c Connection this message should belong. If NULL, check fails.
2474 * @param sender Neighbor that sent the message.
2475 * 665 *
2476 * @return #GNUNET_YES if the message goes FWD. 666 * @param cc connection that got the duplicate CREATE
2477 * #GNUNET_NO if it goes BCK.
2478 * #GNUNET_SYSERR if there is an error (unauthorized sender, ...).
2479 */ 667 */
2480static int 668void
2481check_message (const struct GNUNET_MessageHeader *message, 669GCC_handle_duplicate_create (struct CadetConnection *cc)
2482 const struct GNUNET_CADET_ConnectionTunnelIdentifier* cid,
2483 struct CadetConnection *c,
2484 struct CadetPeer *sender,
2485 struct CadetEncryptedMessageIdentifier pid)
2486{ 670{
2487 struct CadetFlowControl *fc; 671 if (GNUNET_YES == cc->mqm_ready)
2488 struct CadetPeer *hop;
2489 int fwd;
2490 uint16_t type;
2491
2492 /* Check connection */
2493 if (NULL == c)
2494 { 672 {
2495 GNUNET_STATISTICS_update (stats,
2496 "# unknown connection",
2497 1, GNUNET_NO);
2498 LOG (GNUNET_ERROR_TYPE_DEBUG, 673 LOG (GNUNET_ERROR_TYPE_DEBUG,
2499 "%s on unknown connection %s\n", 674 "Got duplicate CREATE for %s, scheduling another ACK (%s)\n",
2500 GC_m2s (ntohs (message->type)), 675 GCC_2s (cc),
2501 GNUNET_sh2s (&cid->connection_of_tunnel)); 676 (GNUNET_YES == cc->mqm_ready) ? "MQM ready" : "MQM busy");
2502 GNUNET_break_op (0); 677 /* Revert back to the state of having only received the 'CREATE',
2503 send_broken_unknown (cid, 678 and immediately proceed to send the CREATE_ACK. */
2504 &my_full_id, 679 update_state (cc,
2505 NULL, 680 CADET_CONNECTION_CREATE_RECEIVED,
2506 sender); 681 cc->mqm_ready);
2507 return GNUNET_SYSERR; 682 if (NULL != cc->task)
2508 } 683 GNUNET_SCHEDULER_cancel (cc->task);
2509 684 cc->task = GNUNET_SCHEDULER_add_now (&send_create_ack,
2510 /* Check if origin is as expected */ 685 cc);
2511 hop = get_prev_hop (c);
2512 if (sender == hop)
2513 {
2514 fwd = GNUNET_YES;
2515 } 686 }
2516 else 687 else
2517 { 688 {
2518 hop = get_next_hop (c); 689 /* We are currently sending something else back, which
2519 GNUNET_break (hop == c->next_peer); 690 can only be an ACK or payload, either of which would
2520 if (sender == hop) 691 do. So actually no need to do anything. */
2521 { 692 LOG (GNUNET_ERROR_TYPE_DEBUG,
2522 fwd = GNUNET_NO; 693 "Got duplicate CREATE for %s. MQ is busy, not queueing another ACK\n",
2523 } 694 GCC_2s (cc));
2524 else
2525 {
2526 /* Unexpected peer sending traffic on a connection. */
2527 GNUNET_break_op (0);
2528 return GNUNET_SYSERR;
2529 }
2530 }
2531
2532 /* Check PID for payload messages */
2533 type = ntohs (message->type);
2534 if (GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED == type)
2535 {
2536 fc = fwd ? &c->bck_fc : &c->fwd_fc;
2537 LOG (GNUNET_ERROR_TYPE_DEBUG, " PID %u (expected in interval [%u,%u])\n",
2538 ntohl (pid.pid),
2539 ntohl (fc->last_pid_recv.pid) + 1,
2540 ntohl (fc->last_ack_sent.pid));
2541 if (GC_is_pid_bigger (ntohl (pid.pid),
2542 ntohl (fc->last_ack_sent.pid)))
2543 {
2544 GNUNET_STATISTICS_update (stats,
2545 "# unsolicited message",
2546 1,
2547 GNUNET_NO);
2548 LOG (GNUNET_ERROR_TYPE_WARNING,
2549 "Received PID %u, (prev %u), ACK %u\n",
2550 pid, fc->last_pid_recv, fc->last_ack_sent);
2551 return GNUNET_SYSERR;
2552 }
2553 if (GC_is_pid_bigger (ntohl (pid.pid),
2554 ntohl (fc->last_pid_recv.pid)))
2555 {
2556 unsigned int delta;
2557
2558 delta = ntohl (pid.pid) - ntohl (fc->last_pid_recv.pid);
2559 fc->last_pid_recv = pid;
2560 fc->recv_bitmap <<= delta;
2561 fc->recv_bitmap |= 1;
2562 }
2563 else
2564 {
2565 GNUNET_STATISTICS_update (stats,
2566 "# out of order PID",
2567 1,
2568 GNUNET_NO);
2569 if (GNUNET_NO == is_ooo_ok (fc->last_pid_recv,
2570 pid,
2571 fc->recv_bitmap))
2572 {
2573 LOG (GNUNET_ERROR_TYPE_WARNING,
2574 "PID %u unexpected (%u+), dropping!\n",
2575 ntohl (pid.pid),
2576 ntohl (fc->last_pid_recv.pid) - 31);
2577 return GNUNET_SYSERR;
2578 }
2579 fc->recv_bitmap |= get_recv_bitmask (fc->last_pid_recv,
2580 pid);
2581 }
2582 }
2583
2584 /* Count as connection confirmation. */
2585 if ( (CADET_CONNECTION_SENT == c->state) ||
2586 (CADET_CONNECTION_ACK == c->state) )
2587 {
2588 connection_change_state (c, CADET_CONNECTION_READY);
2589 if (NULL != c->t)
2590 {
2591 if (CADET_TUNNEL_WAITING == GCT_get_cstate (c->t))
2592 GCT_change_cstate (c->t, CADET_TUNNEL_READY);
2593 }
2594 } 695 }
2595 connection_reset_timeout (c, fwd);
2596
2597 return fwd;
2598} 696}
2599 697
2600 698
2601/** 699/**
2602 * Handler for key exchange traffic (Axolotl KX). 700 * There has been a change in the message queue existence for our
701 * peer at the first hop. Adjust accordingly.
2603 * 702 *
2604 * @param peer Message sender (neighbor). 703 * @param cls the `struct CadetConnection`
2605 * @param msg Message itself. 704 * @param available #GNUNET_YES if sending is now possible,
705 * #GNUNET_NO if sending is no longer possible
706 * #GNUNET_SYSERR if sending is no longer possible
707 * and the last envelope was discarded
2606 */ 708 */
2607void 709static void
2608GCC_handle_kx (struct CadetPeer *peer, 710manage_first_hop_mq (void *cls,
2609 const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg) 711 int available)
2610{ 712{
2611 static struct CadetEncryptedMessageIdentifier zero; 713 struct CadetConnection *cc = cls;
2612 const struct GNUNET_CADET_ConnectionTunnelIdentifier* cid;
2613 struct CadetConnection *c;
2614 int fwd;
2615
2616 GCC_check_connections ();
2617 cid = &msg->cid;
2618 log_message (&msg->header, peer, cid);
2619
2620 c = connection_get (cid);
2621 fwd = check_message (&msg->header,
2622 cid,
2623 c,
2624 peer,
2625 zero);
2626
2627 /* If something went wrong, discard message. */
2628 if (GNUNET_SYSERR == fwd)
2629 {
2630 GNUNET_break_op (0);
2631 GCC_check_connections ();
2632 return;
2633 }
2634 714
2635 /* Is this message for us? */ 715 if (GNUNET_YES != available)
2636 if (GCC_is_terminal (c, fwd))
2637 { 716 {
2638 LOG (GNUNET_ERROR_TYPE_DEBUG, " message for us!\n"); 717 /* Connection is down, for now... */
2639 GNUNET_STATISTICS_update (stats, "# received KX", 1, GNUNET_NO); 718 LOG (GNUNET_ERROR_TYPE_DEBUG,
2640 if (NULL == c->t) 719 "Core MQ for %s went down\n",
720 GCC_2s (cc));
721 update_state (cc,
722 CADET_CONNECTION_NEW,
723 GNUNET_NO);
724 cc->retry_delay = GNUNET_TIME_UNIT_ZERO;
725 if (NULL != cc->task)
2641 { 726 {
2642 GNUNET_break (0); 727 GNUNET_SCHEDULER_cancel (cc->task);
2643 return; 728 cc->task = NULL;
2644 } 729 }
2645 GCT_handle_kx (c->t, msg);
2646 GCC_check_connections ();
2647 return;
2648 }
2649
2650 /* Message not for us: forward to next hop */
2651 LOG (GNUNET_ERROR_TYPE_DEBUG, " not for us, retransmitting...\n");
2652 GNUNET_STATISTICS_update (stats, "# messages forwarded", 1, GNUNET_NO);
2653 (void) GCC_send_prebuilt_message (&msg->header, 0,
2654 zero, c, fwd,
2655 GNUNET_NO, NULL, NULL);
2656 GCC_check_connections ();
2657}
2658
2659
2660/**
2661 * Handler for encrypted cadet network traffic (channel mgmt, data).
2662 *
2663 * @param peer Message sender (neighbor).
2664 * @param msg Message itself.
2665 */
2666void
2667GCC_handle_encrypted (struct CadetPeer *peer,
2668 const struct GNUNET_CADET_TunnelEncryptedMessage *msg)
2669{
2670 static struct CadetEncryptedMessageIdentifier zero;
2671 const struct GNUNET_CADET_ConnectionTunnelIdentifier* cid;
2672 struct CadetConnection *c;
2673 struct CadetEncryptedMessageIdentifier pid;
2674 int fwd;
2675
2676 GCC_check_connections ();
2677 cid = &msg->cid;
2678 pid = msg->cemi;
2679 log_message (&msg->header, peer, cid);
2680
2681 c = connection_get (cid);
2682 fwd = check_message (&msg->header,
2683 cid,
2684 c,
2685 peer,
2686 pid);
2687
2688 /* If something went wrong, discard message. */
2689 if (GNUNET_SYSERR == fwd)
2690 {
2691 GCC_check_connections ();
2692 return; 730 return;
2693 } 731 }
2694 732
2695 /* Is this message for us? */ 733 update_state (cc,
2696 if (GCC_is_terminal (c, fwd)) 734 cc->state,
2697 { 735 GNUNET_YES);
2698 GNUNET_STATISTICS_update (stats, "# received encrypted", 1, GNUNET_NO); 736 LOG (GNUNET_ERROR_TYPE_DEBUG,
2699 737 "Core MQ for %s became available in state %d\n",
2700 if (NULL == c->t) 738 GCC_2s (cc),
739 cc->state);
740 switch (cc->state)
741 {
742 case CADET_CONNECTION_NEW:
743 /* Transmit immediately */
744 cc->task = GNUNET_SCHEDULER_add_now (&send_create,
745 cc);
746 break;
747 case CADET_CONNECTION_SENDING_CREATE:
748 /* Should not be possible to be called in this state. */
749 GNUNET_assert (0);
750 break;
751 case CADET_CONNECTION_SENT:
752 /* Retry a bit later... */
753 cc->retry_delay = GNUNET_TIME_STD_BACKOFF (cc->retry_delay);
754 cc->task = GNUNET_SCHEDULER_add_delayed (cc->retry_delay,
755 &send_create,
756 cc);
757 break;
758 case CADET_CONNECTION_CREATE_RECEIVED:
759 /* We got the 'CREATE' (incoming connection), should send the CREATE_ACK */
760 cc->metrics.age = GNUNET_TIME_absolute_get ();
761 cc->task = GNUNET_SCHEDULER_add_now (&send_create_ack,
762 cc);
763 break;
764 case CADET_CONNECTION_READY:
765 if ( (NULL == cc->keepalive_qe) &&
766 (GNUNET_YES == cc->mqm_ready) &&
767 (NULL == cc->task) )
2701 { 768 {
2702 GNUNET_break (GNUNET_NO != c->destroy); 769 LOG (GNUNET_ERROR_TYPE_DEBUG,
2703 return; 770 "Scheduling keepalive for %s in %s\n",
771 GCC_2s (cc),
772 GNUNET_STRINGS_relative_time_to_string (keepalive_period,
773 GNUNET_YES));
774 cc->task = GNUNET_SCHEDULER_add_delayed (keepalive_period,
775 &send_keepalive,
776 cc);
2704 } 777 }
2705 GCT_handle_encrypted (c->t, msg); 778 break;
2706 GCC_send_ack (c, fwd, GNUNET_NO);
2707 GCC_check_connections ();
2708 return;
2709 } 779 }
2710
2711 /* Message not for us: forward to next hop */
2712 LOG (GNUNET_ERROR_TYPE_DEBUG, " not for us, retransmitting...\n");
2713 GNUNET_STATISTICS_update (stats, "# messages forwarded", 1, GNUNET_NO);
2714 (void) GCC_send_prebuilt_message (&msg->header, 0,
2715 zero, c, fwd,
2716 GNUNET_NO, NULL, NULL);
2717 GCC_check_connections ();
2718} 780}
2719 781
2720 782
2721/** 783/**
2722 * Initialize the connections subsystem 784 * Create a connection to @a destination via @a path and notify @a cb
785 * whenever we are ready for more data. Shared logic independent of
786 * who is initiating the connection.
2723 * 787 *
2724 * @param c Configuration handle. 788 * @param destination where to go
789 * @param path which path to take (may not be the full path)
790 * @param off offset of @a destination on @a path
791 * @param options options for the connection
792 * @param ct which tunnel uses this connection
793 * @param init_state initial state for the connection
794 * @param ready_cb function to call when ready to transmit
795 * @param ready_cb_cls closure for @a cb
796 * @return handle to the connection
2725 */ 797 */
2726void 798static struct CadetConnection *
2727GCC_init (const struct GNUNET_CONFIGURATION_Handle *c) 799connection_create (struct CadetPeer *destination,
2728{ 800 struct CadetPeerPath *path,
2729 LOG (GNUNET_ERROR_TYPE_DEBUG, "init\n"); 801 unsigned int off,
2730 if (GNUNET_OK != 802 enum GNUNET_CADET_ChannelOption options,
2731 GNUNET_CONFIGURATION_get_value_number (c, "CADET", "MAX_MSGS_QUEUE", 803 struct CadetTConnection *ct,
2732 &max_msgs_queue)) 804 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
2733 { 805 enum CadetConnectionState init_state,
2734 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, 806 GCC_ReadyCallback ready_cb,
2735 "CADET", "MAX_MSGS_QUEUE", "MISSING"); 807 void *ready_cb_cls)
2736 GNUNET_SCHEDULER_shutdown (); 808{
2737 return; 809 struct CadetConnection *cc;
2738 } 810 struct CadetPeer *first_hop;
2739 811
2740 if (GNUNET_OK != 812 cc = GNUNET_new (struct CadetConnection);
2741 GNUNET_CONFIGURATION_get_value_number (c, "CADET", "MAX_CONNECTIONS", 813 cc->options = options;
2742 &max_connections)) 814 cc->state = init_state;
2743 { 815 cc->ct = ct;
2744 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, 816 cc->cid = *cid;
2745 "CADET", "MAX_CONNECTIONS", "MISSING");
2746 GNUNET_SCHEDULER_shutdown ();
2747 return;
2748 }
2749
2750 if (GNUNET_OK !=
2751 GNUNET_CONFIGURATION_get_value_time (c, "CADET", "REFRESH_CONNECTION_TIME",
2752 &refresh_connection_time))
2753 {
2754 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
2755 "CADET", "REFRESH_CONNECTION_TIME", "MISSING");
2756 GNUNET_SCHEDULER_shutdown ();
2757 return;
2758 }
2759 create_connection_time = GNUNET_TIME_relative_min (GNUNET_TIME_UNIT_SECONDS,
2760 refresh_connection_time);
2761 connections = GNUNET_CONTAINER_multishortmap_create (1024,
2762 GNUNET_YES);
2763}
2764
2765
2766/**
2767 * Destroy each connection on shutdown.
2768 *
2769 * @param cls Closure (unused).
2770 * @param key Current key code (CID, unused).
2771 * @param value Value in the hash map (`struct CadetConnection`)
2772 *
2773 * @return #GNUNET_YES, because we should continue to iterate
2774 */
2775static int
2776shutdown_iterator (void *cls,
2777 const struct GNUNET_ShortHashCode *key,
2778 void *value)
2779{
2780 struct CadetConnection *c = value;
2781
2782 c->state = CADET_CONNECTION_DESTROYED;
2783 GCC_destroy (c);
2784 return GNUNET_YES;
2785}
2786
2787
2788/**
2789 * Shut down the connections subsystem.
2790 */
2791void
2792GCC_shutdown (void)
2793{
2794 LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down connections\n");
2795 GCC_check_connections ();
2796 GNUNET_CONTAINER_multishortmap_iterate (connections,
2797 &shutdown_iterator,
2798 NULL);
2799 GNUNET_CONTAINER_multishortmap_destroy (connections);
2800 connections = NULL;
2801}
2802
2803
2804/**
2805 * Create a connection.
2806 *
2807 * @param cid Connection ID (either created locally or imposed remotely).
2808 * @param t Tunnel this connection belongs to (or NULL for transit connections);
2809 * @param path Path this connection has to use (copy is made).
2810 * @param own_pos Own position in the @c path path.
2811 *
2812 * @return Newly created connection.
2813 * NULL in case of error: own id not in path, wrong neighbors, ...
2814*/
2815struct CadetConnection *
2816GCC_new (const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
2817 struct CadetTunnel *t,
2818 struct CadetPeerPath *path,
2819 unsigned int own_pos)
2820{
2821 struct CadetConnection *c;
2822 struct CadetPeerPath *cpath;
2823
2824 GCC_check_connections ();
2825 cpath = path_duplicate (path);
2826 GNUNET_assert (NULL != cpath);
2827 c = GNUNET_new (struct CadetConnection);
2828 c->id = *cid;
2829 GNUNET_assert (GNUNET_OK == 817 GNUNET_assert (GNUNET_OK ==
2830 GNUNET_CONTAINER_multishortmap_put (connections, 818 GNUNET_CONTAINER_multishortmap_put (connections,
2831 &c->id.connection_of_tunnel, 819 &GCC_get_id (cc)->connection_of_tunnel,
2832 c, 820 cc,
2833 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 821 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
2834 fc_init (&c->fwd_fc); 822 cc->ready_cb = ready_cb;
2835 fc_init (&c->bck_fc); 823 cc->ready_cb_cls = ready_cb_cls;
2836 c->fwd_fc.c = c; 824 cc->path = path;
2837 c->bck_fc.c = c; 825 cc->off = off;
2838
2839 c->t = t;
2840 GNUNET_assert (own_pos <= cpath->length - 1);
2841 c->own_pos = own_pos;
2842 c->path = cpath;
2843 cpath->c = c;
2844 if (GNUNET_OK != register_neighbors (c))
2845 {
2846 if (0 == own_pos)
2847 {
2848 /* We were the origin of this request, this means we have invalid
2849 * info about the paths to reach the destination. We must invalidate
2850 * the *original* path to avoid trying it again in the next minute.
2851 */
2852 if (2 < path->length)
2853 path_invalidate (path);
2854 else
2855 {
2856 GNUNET_break (0);
2857 GCT_debug(t, GNUNET_ERROR_TYPE_WARNING);
2858 }
2859 c->t = NULL;
2860 }
2861 path_destroy (c->path);
2862 c->path = NULL;
2863 GCC_destroy (c);
2864 return NULL;
2865 }
2866 LOG (GNUNET_ERROR_TYPE_INFO, "New connection %s\n", GCC_2s (c));
2867 GCC_check_connections ();
2868 return c;
2869}
2870
2871
2872/**
2873 * Connection is no longer needed: destroy it.
2874 *
2875 * Cancels all pending traffic (including possible DESTROY messages), all
2876 * maintenance tasks and removes the connection from neighbor peers and tunnel.
2877 *
2878 * @param c Connection to destroy.
2879 */
2880void
2881GCC_destroy (struct CadetConnection *c)
2882{
2883 GCC_check_connections ();
2884 if (NULL == c)
2885 {
2886 GNUNET_break (0);
2887 return;
2888 }
2889
2890 if (2 == c->destroy) /* cancel queues -> GCP_queue_cancel -> q_destroy -> */
2891 return; /* -> message_sent -> GCC_destroy. Don't loop. */
2892 c->destroy = 2;
2893
2894 LOG (GNUNET_ERROR_TYPE_DEBUG,
2895 "destroying connection %s\n",
2896 GCC_2s (c));
2897 LOG (GNUNET_ERROR_TYPE_DEBUG,
2898 " fc's f: %p, b: %p\n",
2899 &c->fwd_fc, &c->bck_fc);
2900 LOG (GNUNET_ERROR_TYPE_DEBUG,
2901 " fc tasks f: %u, b: %u\n",
2902 c->fwd_fc.poll_task,
2903 c->bck_fc.poll_task);
2904
2905 /* Cancel all traffic */
2906 if (NULL != c->path)
2907 {
2908 connection_cancel_queues (c, GNUNET_YES);
2909 connection_cancel_queues (c, GNUNET_NO);
2910 if (NULL != c->maintenance_q)
2911 {
2912 GCP_send_cancel (c->maintenance_q);
2913 c->maintenance_q = NULL;
2914 }
2915 }
2916 unregister_neighbors (c);
2917 path_destroy (c->path);
2918 c->path = NULL;
2919
2920 /* Delete from tunnel */
2921 if (NULL != c->t)
2922 GCT_remove_connection (c->t, c);
2923
2924 if (NULL != c->check_duplicates_task)
2925 GNUNET_SCHEDULER_cancel (c->check_duplicates_task);
2926 if (NULL != c->fwd_maintenance_task)
2927 GNUNET_SCHEDULER_cancel (c->fwd_maintenance_task);
2928 if (NULL != c->bck_maintenance_task)
2929 GNUNET_SCHEDULER_cancel (c->bck_maintenance_task);
2930
2931 if (GNUNET_NO == c->was_removed)
2932 {
2933 GNUNET_break (GNUNET_YES ==
2934 GNUNET_CONTAINER_multishortmap_remove (connections,
2935 &c->id.connection_of_tunnel,
2936 c));
2937 }
2938 GNUNET_STATISTICS_update (stats,
2939 "# connections",
2940 -1,
2941 GNUNET_NO);
2942 GNUNET_free (c);
2943 GCC_check_connections ();
2944}
2945
2946
2947/**
2948 * Get the connection ID.
2949 *
2950 * @param c Connection to get the ID from.
2951 *
2952 * @return ID of the connection.
2953 */
2954const struct GNUNET_CADET_ConnectionTunnelIdentifier *
2955GCC_get_id (const struct CadetConnection *c)
2956{
2957 return &c->id;
2958}
2959
2960
2961/**
2962 * Get the connection path.
2963 *
2964 * @param c Connection to get the path from.
2965 *
2966 * @return path used by the connection.
2967 */
2968const struct CadetPeerPath *
2969GCC_get_path (const struct CadetConnection *c)
2970{
2971 if (GNUNET_NO == c->destroy)
2972 return c->path;
2973 return NULL;
2974}
2975
2976
2977/**
2978 * Get the connection state.
2979 *
2980 * @param c Connection to get the state from.
2981 *
2982 * @return state of the connection.
2983 */
2984enum CadetConnectionState
2985GCC_get_state (const struct CadetConnection *c)
2986{
2987 return c->state;
2988}
2989
2990/**
2991 * Get the connection tunnel.
2992 *
2993 * @param c Connection to get the tunnel from.
2994 *
2995 * @return tunnel of the connection.
2996 */
2997struct CadetTunnel *
2998GCC_get_tunnel (const struct CadetConnection *c)
2999{
3000 return c->t;
3001}
3002
3003
3004/**
3005 * Get free buffer space in a connection.
3006 *
3007 * @param c Connection.
3008 * @param fwd Is query about FWD traffic?
3009 *
3010 * @return Free buffer space [0 - max_msgs_queue/max_connections]
3011 */
3012unsigned int
3013GCC_get_buffer (struct CadetConnection *c, int fwd)
3014{
3015 struct CadetFlowControl *fc;
3016
3017 fc = fwd ? &c->fwd_fc : &c->bck_fc;
3018
3019 LOG (GNUNET_ERROR_TYPE_DEBUG, " Get %s buffer on %s: %u - %u\n",
3020 GC_f2s (fwd), GCC_2s (c), fc->queue_max, fc->queue_n);
3021 GCC_debug (c, GNUNET_ERROR_TYPE_DEBUG);
3022
3023 return (fc->queue_max - fc->queue_n);
3024}
3025
3026
3027/**
3028 * Get how many messages have we allowed to send to us from a direction.
3029 *
3030 * @param c Connection.
3031 * @param fwd Are we asking about traffic from FWD (BCK messages)?
3032 *
3033 * @return last_ack_sent - last_pid_recv
3034 */
3035unsigned int
3036GCC_get_allowed (struct CadetConnection *c, int fwd)
3037{
3038 struct CadetFlowControl *fc;
3039
3040 fc = fwd ? &c->fwd_fc : &c->bck_fc;
3041 if ( (CADET_CONNECTION_READY != c->state) ||
3042 GC_is_pid_bigger (ntohl (fc->last_pid_recv.pid),
3043 ntohl (fc->last_ack_sent.pid)) )
3044 {
3045 return 0;
3046 }
3047 return (ntohl (fc->last_ack_sent.pid) - ntohl (fc->last_pid_recv.pid));
3048}
3049
3050
3051/**
3052 * Get messages queued in a connection.
3053 *
3054 * @param c Connection.
3055 * @param fwd Is query about FWD traffic?
3056 *
3057 * @return Number of messages queued.
3058 */
3059unsigned int
3060GCC_get_qn (struct CadetConnection *c, int fwd)
3061{
3062 struct CadetFlowControl *fc;
3063
3064 fc = fwd ? &c->fwd_fc : &c->bck_fc;
3065
3066 return fc->queue_n;
3067}
3068
3069
3070/**
3071 * Get next PID to use.
3072 *
3073 * @param c Connection.
3074 * @param fwd Is query about FWD traffic?
3075 * @return Next PID to use.
3076 */
3077struct CadetEncryptedMessageIdentifier
3078GCC_get_pid (struct CadetConnection *c, int fwd)
3079{
3080 struct CadetFlowControl *fc;
3081 struct CadetEncryptedMessageIdentifier pid;
3082
3083 fc = fwd ? &c->fwd_fc : &c->bck_fc;
3084 pid = fc->next_pid;
3085 fc->next_pid.pid = htonl (1 + ntohl (pid.pid));
3086 return pid;
3087}
3088
3089
3090/**
3091 * Allow the connection to advertise a buffer of the given size.
3092 *
3093 * The connection will send an @c fwd ACK message (so: in direction !fwd)
3094 * allowing up to last_pid_recv + buffer.
3095 *
3096 * @param c Connection.
3097 * @param buffer How many more messages the connection can accept.
3098 * @param fwd Is this about FWD traffic? (The ack will go dest->root).
3099 */
3100void
3101GCC_allow (struct CadetConnection *c, unsigned int buffer, int fwd)
3102{
3103 LOG (GNUNET_ERROR_TYPE_DEBUG, " allowing %s %u messages %s\n",
3104 GCC_2s (c), buffer, GC_f2s (fwd));
3105 send_ack (c, buffer, fwd, GNUNET_NO);
3106}
3107
3108
3109/**
3110 * Notify other peers on a connection of a broken link. Mark connections
3111 * to destroy after all traffic has been sent.
3112 *
3113 * @param c Connection on which there has been a disconnection.
3114 * @param peer Peer that disconnected.
3115 */
3116void
3117GCC_neighbor_disconnected (struct CadetConnection *c, struct CadetPeer *peer)
3118{
3119 struct CadetFlowControl *fc;
3120 char peer_name[16];
3121 int fwd;
3122
3123 GCC_check_connections ();
3124 strncpy (peer_name, GCP_2s (peer), 16);
3125 peer_name[15] = '\0';
3126 LOG (GNUNET_ERROR_TYPE_DEBUG, 826 LOG (GNUNET_ERROR_TYPE_DEBUG,
3127 "shutting down %s, %s disconnected\n", 827 "Creating %s using path %s\n",
3128 GCC_2s (c), peer_name); 828 GCC_2s (cc),
3129 829 GCPP_2s (path));
3130 invalidate_paths (c, peer); 830 GCPP_add_connection (path,
3131 831 off,
3132 fwd = is_fwd (c, peer); 832 cc);
3133 if (GNUNET_SYSERR == fwd) 833 for (unsigned int i=0;i<off;i++)
3134 { 834 GCP_add_connection (GCPP_get_peer_at_offset (path,
3135 GNUNET_break (0); 835 i),
3136 return; 836 cc);
3137 } 837
3138 if ( (GNUNET_YES == GCC_is_terminal (c, fwd)) || 838 first_hop = GCPP_get_peer_at_offset (path,
3139 (GNUNET_NO != c->destroy) ) 839 0);
3140 { 840 cc->mq_man = GCP_request_mq (first_hop,
3141 /* Local shutdown, or other peer already down (hence 'c->destroy'); 841 &manage_first_hop_mq,
3142 so there is no one to notify about this, just clean up. */ 842 cc);
3143 GCC_destroy (c); 843 return cc;
3144 GCC_check_connections (); 844}
3145 return; 845
3146 } 846
3147 /* Mark FlowControl towards the peer as unavaliable. */ 847/**
3148 fc = fwd ? &c->bck_fc : &c->fwd_fc; 848 * Create a connection to @a destination via @a path and
3149 fc->queue_max = 0; 849 * notify @a cb whenever we are ready for more data. This
3150 850 * is an inbound tunnel, so we must use the existing @a cid
3151 send_broken (c, &my_full_id, GCP_get_id (peer), fwd); 851 *
3152 852 * @param destination where to go
3153 /* Connection will have at least one pending message 853 * @param path which path to take (may not be the full path)
3154 * (the one we just scheduled), so delay destruction 854 * @param options options for the connection
3155 * and remove from map so we don't use accidentally. */ 855 * @param ct which tunnel uses this connection
3156 mark_destroyed (c); 856 * @param ready_cb function to call when ready to transmit
3157 GNUNET_assert (GNUNET_NO == c->was_removed); 857 * @param ready_cb_cls closure for @a cb
3158 c->was_removed = GNUNET_YES; 858 * @return handle to the connection, NULL if we already have
3159 GNUNET_break (GNUNET_YES == 859 * a connection that takes precedence on @a path
3160 GNUNET_CONTAINER_multishortmap_remove (connections,
3161 &c->id.connection_of_tunnel,
3162 c));
3163 /* Cancel queue in the direction that just died. */
3164 connection_cancel_queues (c, ! fwd);
3165 GCC_stop_poll (c, ! fwd);
3166 unregister_neighbors (c);
3167 GCC_check_connections ();
3168}
3169
3170
3171/**
3172 * Is this peer the first one on the connection?
3173 *
3174 * @param c Connection.
3175 * @param fwd Is this about fwd traffic?
3176 *
3177 * @return #GNUNET_YES if origin, #GNUNET_NO if relay/terminal.
3178 */ 860 */
3179int 861struct CadetConnection *
3180GCC_is_origin (struct CadetConnection *c, int fwd) 862GCC_create_inbound (struct CadetPeer *destination,
3181{ 863 struct CadetPeerPath *path,
3182 if (!fwd && c->path->length - 1 == c->own_pos ) 864 enum GNUNET_CADET_ChannelOption options,
3183 return GNUNET_YES; 865 struct CadetTConnection *ct,
3184 if (fwd && 0 == c->own_pos) 866 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
3185 return GNUNET_YES; 867 GCC_ReadyCallback ready_cb,
3186 return GNUNET_NO; 868 void *ready_cb_cls)
3187} 869{
3188 870 struct CadetConnection *cc;
3189 871 unsigned int off;
3190/** 872
3191 * Is this peer the last one on the connection? 873 off = GCPP_find_peer (path,
3192 * 874 destination);
3193 * @param c Connection. 875 GNUNET_assert (UINT_MAX != off);
3194 * @param fwd Is this about fwd traffic? 876 cc = GCPP_get_connection (path,
3195 * Note that the ROOT is the terminal for BCK traffic! 877 destination,
3196 * 878 off);
3197 * @return #GNUNET_YES if terminal, #GNUNET_NO if relay/origin. 879 if (NULL != cc)
3198 */ 880 {
3199int 881 int cmp;
3200GCC_is_terminal (struct CadetConnection *c, int fwd) 882
3201{ 883 cmp = memcmp (cid,
3202 return GCC_is_origin (c, ! fwd); 884 &cc->cid,
3203} 885 sizeof (*cid));
3204 886 if (0 == cmp)
3205 887 {
3206/** 888 /* Two peers picked the SAME random connection identifier at the
3207 * See if we are allowed to send by the next hop in the given direction. 889 same time for the same path? Must be malicious. Drop
3208 * 890 connection (existing and inbound), even if it is the only
3209 * @param c Connection. 891 one. */
3210 * @param fwd Is this about fwd traffic? 892 GNUNET_break_op (0);
3211 * 893 GCT_connection_lost (cc->ct);
3212 * @return #GNUNET_YES in case it's OK to send. 894 GCC_destroy_without_tunnel (cc);
3213 */
3214int
3215GCC_is_sendable (struct CadetConnection *c, int fwd)
3216{
3217 struct CadetFlowControl *fc;
3218
3219 LOG (GNUNET_ERROR_TYPE_DEBUG,
3220 " checking sendability of %s traffic on %s\n",
3221 GC_f2s (fwd), GCC_2s (c));
3222 if (NULL == c)
3223 {
3224 GNUNET_break (0);
3225 return GNUNET_YES;
3226 }
3227 fc = fwd ? &c->fwd_fc : &c->bck_fc;
3228 LOG (GNUNET_ERROR_TYPE_DEBUG,
3229 " last ack recv: %u, last pid sent: %u\n",
3230 ntohl (fc->last_ack_recv.pid),
3231 ntohl (fc->last_pid_sent.pid));
3232 if (GC_is_pid_bigger (ntohl (fc->last_ack_recv.pid),
3233 ntohl (fc->last_pid_sent.pid)))
3234 {
3235 LOG (GNUNET_ERROR_TYPE_DEBUG, " sendable\n");
3236 return GNUNET_YES;
3237 }
3238 LOG (GNUNET_ERROR_TYPE_DEBUG, " not sendable\n");
3239 return GNUNET_NO;
3240}
3241
3242
3243/**
3244 * Check if this connection is a direct one (never trim a direct connection).
3245 *
3246 * @param c Connection.
3247 *
3248 * @return #GNUNET_YES in case it's a direct connection, #GNUNET_NO otherwise.
3249 */
3250int
3251GCC_is_direct (struct CadetConnection *c)
3252{
3253 return (c->path->length == 2) ? GNUNET_YES : GNUNET_NO;
3254}
3255
3256
3257/**
3258 * Sends a completely built message on a connection, properly registering
3259 * all used resources.
3260 *
3261 * @param message Message to send.
3262 * @param payload_type Type of payload, in case the message is encrypted.
3263 * 0 for restransmissions (when type is no longer known)
3264 * UINT16_MAX when not applicable.
3265 * @param payload_id ID of the payload (PID, ACK, ...).
3266 * @param c Connection on which this message is transmitted.
3267 * @param fwd Is this a fwd message?
3268 * @param force Force the connection to accept the message (buffer overfill).
3269 * @param cont Continuation called once message is sent. Can be NULL.
3270 * @param cont_cls Closure for @c cont.
3271 *
3272 * @return Handle to cancel the message before it's sent.
3273 * NULL on error.
3274 * Invalid on @c cont call.
3275 */
3276struct CadetConnectionQueue *
3277GCC_send_prebuilt_message (const struct GNUNET_MessageHeader *message,
3278 uint16_t payload_type,
3279 struct CadetEncryptedMessageIdentifier payload_id,
3280 struct CadetConnection *c, int fwd, int force,
3281 GCC_sent cont, void *cont_cls)
3282{
3283 struct CadetFlowControl *fc;
3284 struct CadetConnectionQueue *q;
3285 uint16_t size;
3286 uint16_t type;
3287
3288 size = ntohs (message->size);
3289 type = ntohs (message->type);
3290
3291 GCC_check_connections ();
3292 fc = fwd ? &c->fwd_fc : &c->bck_fc;
3293 if (0 == fc->queue_max)
3294 {
3295 GNUNET_break (0);
3296 return NULL;
3297 }
3298
3299 LOG (GNUNET_ERROR_TYPE_INFO,
3300 "--> %s (%s %4u) on conn %s (%p) %s [%5u]\n",
3301 GC_m2s (type), GC_m2s (payload_type), payload_id, GCC_2s (c), c,
3302 GC_f2s(fwd), size);
3303 switch (type)
3304 {
3305 case GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED:
3306 LOG (GNUNET_ERROR_TYPE_DEBUG, " Q_N+ %p %u, PIDsnt: %u, ACKrcv: %u\n",
3307 fc,
3308 fc->queue_n,
3309 ntohl (fc->last_pid_sent.pid),
3310 ntohl (fc->last_ack_recv.pid));
3311 if (GNUNET_NO == force)
3312 {
3313 fc->queue_n++;
3314 }
3315 break;
3316
3317 case GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX:
3318 /* nothing to do here */
3319 break;
3320
3321 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE:
3322 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK:
3323 /* Should've only be used for restransmissions. */
3324 GNUNET_break (0 == payload_type);
3325 break;
3326
3327 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_HOP_BY_HOP_ENCRYPTED_ACK:
3328 case GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED_POLL:
3329 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY:
3330 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN:
3331 GNUNET_assert (GNUNET_YES == force);
3332 break;
3333
3334 default:
3335 GNUNET_break (0);
3336 return NULL; 895 return NULL;
3337 } 896 }
3338 897 if (0 < cmp)
3339 if (fc->queue_n > fc->queue_max && GNUNET_NO == force)
3340 {
3341 GNUNET_STATISTICS_update (stats, "# messages dropped (buffer full)",
3342 1, GNUNET_NO);
3343 GNUNET_break (0);
3344 LOG (GNUNET_ERROR_TYPE_DEBUG, "queue full: %u/%u\n",
3345 fc->queue_n, fc->queue_max);
3346 if (GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED == type)
3347 { 898 {
3348 fc->queue_n--; 899 /* drop existing */
900 LOG (GNUNET_ERROR_TYPE_DEBUG,
901 "Got two connections on %s, dropping my existing %s\n",
902 GCPP_2s (path),
903 GCC_2s (cc));
904 GCT_connection_lost (cc->ct);
905 GCC_destroy_without_tunnel (cc);
3349 } 906 }
3350 return NULL; /* Drop this message */ 907 else
3351 }
3352
3353 LOG (GNUNET_ERROR_TYPE_DEBUG, " C_P+ %s %u\n",
3354 GCC_2s (c), c->pending_messages);
3355 c->pending_messages++;
3356
3357 q = GNUNET_new (struct CadetConnectionQueue);
3358 q->cont = cont;
3359 q->cont_cls = cont_cls;
3360 q->forced = force;
3361 GNUNET_CONTAINER_DLL_insert (fc->q_head, fc->q_tail, q);
3362 q->peer_q = GCP_send (get_hop (c, fwd),
3363 message,
3364 payload_type,
3365 payload_id,
3366 c,
3367 fwd,
3368 &conn_message_sent, q);
3369 if (NULL == q->peer_q)
3370 {
3371 LOG (GNUNET_ERROR_TYPE_DEBUG, "dropping msg on %s, NULL q\n", GCC_2s (c));
3372 GNUNET_CONTAINER_DLL_remove (fc->q_head, fc->q_tail, q);
3373 GNUNET_free (q);
3374 GCC_check_connections ();
3375 return NULL;
3376 }
3377 GCC_check_connections ();
3378 return q;
3379}
3380
3381
3382/**
3383 * Cancel a previously sent message while it's in the queue.
3384 *
3385 * ONLY can be called before the continuation given to the send function
3386 * is called. Once the continuation is called, the message is no longer in the
3387 * queue.
3388 *
3389 * @param q Handle to the queue.
3390 */
3391void
3392GCC_cancel (struct CadetConnectionQueue *q)
3393{
3394 LOG (GNUNET_ERROR_TYPE_DEBUG, "! GCC cancel message\n");
3395
3396 /* send_cancel calls message_sent, which calls q->cont and frees q */
3397 GCP_send_cancel (q->peer_q);
3398 GCC_check_connections ();
3399}
3400
3401
3402/**
3403 * Sends a CREATE CONNECTION message for a path to a peer.
3404 * Changes the connection and tunnel states if necessary.
3405 *
3406 * @param c Connection to create.
3407 */
3408void
3409GCC_send_create (struct CadetConnection *c)
3410{
3411 static struct CadetEncryptedMessageIdentifier zero;
3412 enum CadetTunnelCState state;
3413 size_t size;
3414
3415 GCC_check_connections ();
3416 size = sizeof (struct GNUNET_CADET_ConnectionCreateMessage);
3417 size += c->path->length * sizeof (struct GNUNET_PeerIdentity);
3418 {
3419 /* Allocate message on the stack */
3420 unsigned char cbuf[size];
3421 struct GNUNET_CADET_ConnectionCreateMessage *msg;
3422 struct GNUNET_PeerIdentity *peers;
3423
3424
3425 msg = (struct GNUNET_CADET_ConnectionCreateMessage *) cbuf;
3426 msg->header.size = htons (size);
3427 msg->header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE);
3428 msg->reserved = htonl (0);
3429 msg->cid = *GCC_get_id (c);
3430 peers = (struct GNUNET_PeerIdentity *) &msg[1];
3431 for (int i = 0; i < c->path->length; i++)
3432 { 908 {
3433 GNUNET_PEER_resolve (c->path->peers[i], peers++); 909 /* keep existing */
910 LOG (GNUNET_ERROR_TYPE_DEBUG,
911 "Got two connections on %s, keeping my existing %s\n",
912 GCPP_2s (path),
913 GCC_2s (cc));
914 return NULL;
3434 } 915 }
3435 GNUNET_assert (NULL == c->maintenance_q);
3436 c->maintenance_q = GCP_send (get_next_hop (c),
3437 &msg->header,
3438 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE,
3439 zero,
3440 c, GNUNET_YES,
3441 &conn_message_sent, NULL);
3442 } 916 }
3443 917
3444 LOG (GNUNET_ERROR_TYPE_INFO, "==> %s %19s on conn %s (%p) FWD [%5u]\n", 918 return connection_create (destination,
3445 GC_m2s (GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE), "", 919 path,
3446 GCC_2s (c), c, size); 920 off,
3447 LOG (GNUNET_ERROR_TYPE_DEBUG, " C_P+ %p %u (create)\n", 921 options,
3448 c, c->pending_messages); 922 ct,
3449 c->pending_messages++; 923 cid,
3450 924 CADET_CONNECTION_CREATE_RECEIVED,
3451 state = GCT_get_cstate (c->t); 925 ready_cb,
3452 if (CADET_TUNNEL_SEARCHING == state || CADET_TUNNEL_NEW == state) 926 ready_cb_cls);
3453 GCT_change_cstate (c->t, CADET_TUNNEL_WAITING);
3454 if (CADET_CONNECTION_NEW == c->state)
3455 connection_change_state (c, CADET_CONNECTION_SENT);
3456 GCC_check_connections ();
3457} 927}
3458 928
3459 929
3460/** 930/**
3461 * Send an ACK on the appropriate connection/channel, depending on 931 * Create a connection to @a destination via @a path and
3462 * the direction and the position of the peer. 932 * notify @a cb whenever we are ready for more data.
3463 * 933 *
3464 * @param c Which connection to send the hop-by-hop ACK. 934 * @param destination where to go
3465 * @param fwd Is this a fwd ACK? (will go dest->root). 935 * @param path which path to take (may not be the full path)
3466 * @param force Send the ACK even if suboptimal (e.g. requested by POLL). 936 * @param off offset of @a destination on @a path
937 * @param options options for the connection
938 * @param ct tunnel that uses the connection
939 * @param ready_cb function to call when ready to transmit
940 * @param ready_cb_cls closure for @a cb
941 * @return handle to the connection
3467 */ 942 */
3468void 943struct CadetConnection *
3469GCC_send_ack (struct CadetConnection *c, int fwd, int force) 944GCC_create (struct CadetPeer *destination,
945 struct CadetPeerPath *path,
946 unsigned int off,
947 enum GNUNET_CADET_ChannelOption options,
948 struct CadetTConnection *ct,
949 GCC_ReadyCallback ready_cb,
950 void *ready_cb_cls)
3470{ 951{
3471 unsigned int buffer; 952 struct GNUNET_CADET_ConnectionTunnelIdentifier cid;
3472
3473 GCC_check_connections ();
3474 LOG (GNUNET_ERROR_TYPE_DEBUG, "GCC send %s ACK on %s\n",
3475 GC_f2s (fwd), GCC_2s (c));
3476
3477 if (NULL == c)
3478 {
3479 GNUNET_break (0);
3480 return;
3481 }
3482 953
3483 if (GNUNET_NO != c->destroy) 954 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
3484 { 955 &cid,
3485 LOG (GNUNET_ERROR_TYPE_DEBUG, " being destroyed, why bother...\n"); 956 sizeof (cid));
3486 GCC_check_connections (); 957 return connection_create (destination,
3487 return; 958 path,
3488 } 959 off,
3489 960 options,
3490 /* Get available buffer space */ 961 ct,
3491 if (GCC_is_terminal (c, fwd)) 962 &cid,
3492 { 963 CADET_CONNECTION_NEW,
3493 LOG (GNUNET_ERROR_TYPE_DEBUG, " getting from all channels\n"); 964 ready_cb,
3494 buffer = GCT_get_channels_buffer (c->t); 965 ready_cb_cls);
3495 }
3496 else
3497 {
3498 LOG (GNUNET_ERROR_TYPE_DEBUG, " getting from one connection\n");
3499 buffer = GCC_get_buffer (c, fwd);
3500 }
3501 LOG (GNUNET_ERROR_TYPE_DEBUG, " buffer available: %u\n", buffer);
3502 if (0 == buffer && GNUNET_NO == force)
3503 {
3504 GCC_check_connections ();
3505 return;
3506 }
3507
3508 /* Send available buffer space */
3509 if (GNUNET_YES == GCC_is_origin (c, fwd))
3510 {
3511 GNUNET_assert (NULL != c->t);
3512 LOG (GNUNET_ERROR_TYPE_DEBUG, " sending on channels...\n");
3513 GCT_unchoke_channels (c->t);
3514 }
3515 else
3516 {
3517 LOG (GNUNET_ERROR_TYPE_DEBUG, " sending on connection\n");
3518 send_ack (c, buffer, fwd, force);
3519 }
3520 GCC_check_connections ();
3521} 966}
3522 967
3523 968
3524/** 969/**
3525 * Send a message to all peers in this connection that the connection 970 * Transmit message @a msg via connection @a cc. Must only be called
3526 * is no longer valid. 971 * (once) after the connection has signalled that it is ready via the
972 * `ready_cb`. Clients can also use #GCC_is_ready() to check if the
973 * connection is right now ready for transmission.
3527 * 974 *
3528 * If some peer should not receive the message, it should be zero'ed out 975 * @param cc connection identification
3529 * before calling this function. 976 * @param env envelope with message to transmit; must NOT
3530 * 977 * yet have a #GNUNET_MQ_notify_sent() callback attached to it
3531 * @param c The connection whose peers to notify.
3532 */ 978 */
3533void 979void
3534GCC_send_destroy (struct CadetConnection *c) 980GCC_transmit (struct CadetConnection *cc,
981 struct GNUNET_MQ_Envelope *env)
3535{ 982{
3536 static struct CadetEncryptedMessageIdentifier zero;
3537 struct GNUNET_CADET_ConnectionDestroyMessage msg;
3538
3539 if (GNUNET_YES == c->destroy)
3540 return;
3541 GCC_check_connections ();
3542 msg.header.size = htons (sizeof (msg));
3543 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY);
3544 msg.cid = c->id;
3545 msg.reserved = htonl (0);
3546 LOG (GNUNET_ERROR_TYPE_DEBUG, 983 LOG (GNUNET_ERROR_TYPE_DEBUG,
3547 " sending connection destroy for connection %s\n", 984 "Scheduling message for transmission on %s\n",
3548 GCC_2s (c)); 985 GCC_2s (cc));
3549 986 GNUNET_assert (GNUNET_YES == cc->mqm_ready);
3550 if (GNUNET_NO == GCC_is_terminal (c, GNUNET_YES)) 987 GNUNET_assert (CADET_CONNECTION_READY == cc->state);
3551 (void) GCC_send_prebuilt_message (&msg.header, 988 cc->metrics.last_use = GNUNET_TIME_absolute_get ();
3552 UINT16_MAX, 989 cc->mqm_ready = GNUNET_NO;
3553 zero, 990 if (NULL != cc->task)
3554 c, 991 {
3555 GNUNET_YES, GNUNET_YES, NULL, NULL); 992 GNUNET_SCHEDULER_cancel (cc->task);
3556 if (GNUNET_NO == GCC_is_terminal (c, GNUNET_NO)) 993 cc->task = NULL;
3557 (void) GCC_send_prebuilt_message (&msg.header, 994 }
3558 UINT16_MAX, 995 GCP_send (cc->mq_man,
3559 zero, 996 env);
3560 c,
3561 GNUNET_NO, GNUNET_YES, NULL, NULL);
3562 mark_destroyed (c);
3563 GCC_check_connections ();
3564} 997}
3565 998
3566 999
3567/** 1000/**
3568 * @brief Start a polling timer for the connection. 1001 * Obtain the path used by this connection.
3569 *
3570 * When a neighbor does not accept more traffic on the connection it could be
3571 * caused by a simple congestion or by a lost ACK. Polling enables to check
3572 * for the lastest ACK status for a connection.
3573 * 1002 *
3574 * @param c Connection. 1003 * @param cc connection
3575 * @param fwd Should we poll in the FWD direction? 1004 * @return path to @a cc
3576 */ 1005 */
3577void 1006struct CadetPeerPath *
3578GCC_start_poll (struct CadetConnection *c, int fwd) 1007GCC_get_path (struct CadetConnection *cc)
3579{ 1008{
3580 struct CadetFlowControl *fc; 1009 return cc->path;
3581
3582 fc = fwd ? &c->fwd_fc : &c->bck_fc;
3583 LOG (GNUNET_ERROR_TYPE_DEBUG, "POLL %s requested\n",
3584 GC_f2s (fwd));
3585 if (NULL != fc->poll_task || NULL != fc->poll_msg)
3586 {
3587 LOG (GNUNET_ERROR_TYPE_DEBUG, " POLL already in progress (t: %p, m: %p)\n",
3588 fc->poll_task, fc->poll_msg);
3589 return;
3590 }
3591 if (0 == fc->queue_max)
3592 {
3593 /* Should not be needed, traffic should've been cancelled. */
3594 GNUNET_break (0);
3595 LOG (GNUNET_ERROR_TYPE_DEBUG, " POLL not possible, peer disconnected\n");
3596 return;
3597 }
3598 LOG (GNUNET_ERROR_TYPE_DEBUG, "POLL started on request\n");
3599 fc->poll_task = GNUNET_SCHEDULER_add_delayed (fc->poll_time, &send_poll, fc);
3600} 1010}
3601 1011
3602 1012
3603/** 1013/**
3604 * @brief Stop polling a connection for ACKs. 1014 * Obtain unique ID for the connection.
3605 * 1015 *
3606 * Once we have enough ACKs for future traffic, polls are no longer necessary. 1016 * @param cc connection.
3607 * 1017 * @return unique number of the connection
3608 * @param c Connection.
3609 * @param fwd Should we stop the poll in the FWD direction?
3610 */ 1018 */
3611void 1019const struct GNUNET_CADET_ConnectionTunnelIdentifier *
3612GCC_stop_poll (struct CadetConnection *c, int fwd) 1020GCC_get_id (struct CadetConnection *cc)
3613{ 1021{
3614 struct CadetFlowControl *fc; 1022 return &cc->cid;
3615
3616 fc = fwd ? &c->fwd_fc : &c->bck_fc;
3617 if (NULL != fc->poll_task)
3618 {
3619 GNUNET_SCHEDULER_cancel (fc->poll_task);
3620 fc->poll_task = NULL;
3621 }
3622 if (NULL != fc->poll_msg)
3623 {
3624 GCC_cancel (fc->poll_msg);
3625 fc->poll_msg = NULL;
3626 }
3627} 1023}
3628 1024
3629 1025
3630/** 1026/**
3631 * Get a (static) string for a connection. 1027 * Get a (static) string for a connection.
3632 * 1028 *
3633 * @param c Connection. 1029 * @param cc Connection.
3634 */ 1030 */
3635const char * 1031const char *
3636GCC_2s (const struct CadetConnection *c) 1032GCC_2s (const struct CadetConnection *cc)
3637{ 1033{
3638 if (NULL == c) 1034 static char buf[128];
3639 return "NULL";
3640 1035
3641 if (NULL != c->t) 1036 if (NULL == cc)
3642 { 1037 return "Connection(NULL)";
3643 static char buf[128];
3644 1038
3645 SPRINTF (buf, "%s (->%s)", 1039 if (NULL != cc->ct)
3646 GNUNET_sh2s (&GCC_get_id (c)->connection_of_tunnel), 1040 {
3647 GCT_2s (c->t)); 1041 GNUNET_snprintf (buf,
1042 sizeof (buf),
1043 "Connection %s (%s)",
1044 GNUNET_sh2s (&cc->cid.connection_of_tunnel),
1045 GCT_2s (cc->ct->t));
3648 return buf; 1046 return buf;
3649 } 1047 }
3650 return GNUNET_sh2s (&c->id.connection_of_tunnel); 1048 GNUNET_snprintf (buf,
1049 sizeof (buf),
1050 "Connection %s",
1051 GNUNET_sh2s (&cc->cid.connection_of_tunnel));
1052 return buf;
3651} 1053}
3652 1054
3653 1055
1056#define LOG2(level, ...) GNUNET_log_from_nocheck(level,"cadet-con",__VA_ARGS__)
1057
1058
3654/** 1059/**
3655 * Log all possible info about the connection state. 1060 * Log connection info.
3656 * 1061 *
3657 * @param c Connection to debug. 1062 * @param cc connection
3658 * @param level Debug level to use. 1063 * @param level Debug level to use.
3659 */ 1064 */
3660void 1065void
3661GCC_debug (const struct CadetConnection *c, enum GNUNET_ErrorType level) 1066GCC_debug (struct CadetConnection *cc,
1067 enum GNUNET_ErrorType level)
3662{ 1068{
3663 int do_log; 1069 int do_log;
3664 char *s;
3665 1070
3666 do_log = GNUNET_get_log_call_status (level & (~GNUNET_ERROR_TYPE_BULK), 1071 do_log = GNUNET_get_log_call_status (level & (~GNUNET_ERROR_TYPE_BULK),
3667 "cadet-con", 1072 "cadet-con",
3668 __FILE__, __FUNCTION__, __LINE__); 1073 __FILE__, __FUNCTION__, __LINE__);
3669 if (0 == do_log) 1074 if (0 == do_log)
3670 return; 1075 return;
3671 1076 if (NULL == cc)
3672 if (NULL == c)
3673 { 1077 {
3674 LOG2 (level, "CCC DEBUG NULL CONNECTION\n"); 1078 LOG2 (level,
1079 "Connection (NULL)\n");
3675 return; 1080 return;
3676 } 1081 }
3677 1082 LOG2 (level,
3678 LOG2 (level, "CCC DEBUG CONNECTION %s\n", GCC_2s (c)); 1083 "%s to %s via path %s in state %d is %s\n",
3679 s = path_2s (c->path); 1084 GCC_2s (cc),
3680 LOG2 (level, "CCC path %s, own pos: %u\n", s, c->own_pos); 1085 GCP_2s (cc->destination),
3681 GNUNET_free (s); 1086 GCPP_2s (cc->path),
3682 LOG2 (level, "CCC state: %s, destroy: %u\n", 1087 cc->state,
3683 GCC_state2s (c->state), c->destroy); 1088 (GNUNET_YES == cc->mqm_ready) ? "ready" : "busy");
3684 LOG2 (level, "CCC pending messages: %u\n", c->pending_messages);
3685 if (NULL != c->perf)
3686 LOG2 (level, "CCC us/byte: %f\n", c->perf->avg);
3687
3688 LOG2 (level, "CCC FWD flow control:\n");
3689 LOG2 (level, "CCC queue: %u/%u\n", c->fwd_fc.queue_n, c->fwd_fc.queue_max);
3690 LOG2 (level, "CCC last PID sent: %5u, recv: %5u\n",
3691 ntohl (c->fwd_fc.last_pid_sent.pid),
3692 ntohl (c->fwd_fc.last_pid_recv.pid));
3693 LOG2 (level, "CCC last ACK sent: %5u, recv: %5u\n",
3694 ntohl (c->fwd_fc.last_ack_sent.pid),
3695 ntohl (c->fwd_fc.last_ack_recv.pid));
3696 LOG2 (level, "CCC recv PID bitmap: %X\n", c->fwd_fc.recv_bitmap);
3697 LOG2 (level, "CCC poll: task %d, msg %p, msg_ack %p)\n",
3698 c->fwd_fc.poll_task, c->fwd_fc.poll_msg, c->fwd_fc.ack_msg);
3699
3700 LOG2 (level, "CCC BCK flow control:\n");
3701 LOG2 (level, "CCC queue: %u/%u\n", c->bck_fc.queue_n, c->bck_fc.queue_max);
3702 LOG2 (level, "CCC last PID sent: %5u, recv: %5u\n",
3703 ntohl (c->bck_fc.last_pid_sent.pid),
3704 ntohl (c->bck_fc.last_pid_recv.pid));
3705 LOG2 (level, "CCC last ACK sent: %5u, recv: %5u\n",
3706 ntohl (c->bck_fc.last_ack_sent.pid),
3707 ntohl (c->bck_fc.last_ack_recv.pid));
3708 LOG2 (level, "CCC recv PID bitmap: %X\n", c->bck_fc.recv_bitmap);
3709 LOG2 (level, "CCC poll: task %d, msg %p, msg_ack %p)\n",
3710 c->bck_fc.poll_task, c->bck_fc.poll_msg, c->bck_fc.ack_msg);
3711
3712 LOG2 (level, "CCC DEBUG CONNECTION END\n");
3713} 1089}
1090
1091/* end of gnunet-service-cadet-new_connection.c */
diff --git a/src/cadet/gnunet-service-cadet_connection.h b/src/cadet/gnunet-service-cadet_connection.h
index 307cb42c2..fdb184366 100644
--- a/src/cadet/gnunet-service-cadet_connection.h
+++ b/src/cadet/gnunet-service-cadet_connection.h
@@ -1,6 +1,7 @@
1
1/* 2/*
2 This file is part of GNUnet. 3 This file is part of GNUnet.
3 Copyright (C) 2013 GNUnet e.V. 4 Copyright (C) 2001-2017 GNUnet e.V.
4 5
5 GNUnet is free software; you can redistribute it and/or modify 6 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 7 it under the terms of the GNU General Public License as published
@@ -20,557 +21,319 @@
20 21
21/** 22/**
22 * @file cadet/gnunet-service-cadet_connection.h 23 * @file cadet/gnunet-service-cadet_connection.h
23 * @brief cadet service; dealing with connections 24 * @brief A connection is a live end-to-end messaging mechanism
25 * where the peers are identified by a path and know how
26 * to forward along the route using a connection identifier
27 * for routing the data.
24 * @author Bartlomiej Polot 28 * @author Bartlomiej Polot
25 * 29 * @author Christian Grothoff
26 * All functions in this file use the prefix GCC (GNUnet Cadet Connection)
27 */ 30 */
28
29#ifndef GNUNET_SERVICE_CADET_CONNECTION_H 31#ifndef GNUNET_SERVICE_CADET_CONNECTION_H
30#define GNUNET_SERVICE_CADET_CONNECTION_H 32#define GNUNET_SERVICE_CADET_CONNECTION_H
31 33
32#ifdef __cplusplus
33extern "C"
34{
35#if 0 /* keep Emacsens' auto-indent happy */
36}
37#endif
38#endif
39
40#include "gnunet_util_lib.h" 34#include "gnunet_util_lib.h"
41 35#include "gnunet-service-cadet.h"
42
43/**
44 * All the states a connection can be in.
45 */
46enum CadetConnectionState
47{
48 /**
49 * Uninitialized status, should never appear in operation.
50 */
51 CADET_CONNECTION_NEW,
52
53 /**
54 * Connection create message sent, waiting for ACK.
55 */
56 CADET_CONNECTION_SENT,
57
58 /**
59 * Connection ACK sent, waiting for ACK.
60 */
61 CADET_CONNECTION_ACK,
62
63 /**
64 * Connection confirmed, ready to carry traffic.
65 */
66 CADET_CONNECTION_READY,
67
68 /**
69 * Connection to be destroyed, just waiting to empty queues.
70 */
71 CADET_CONNECTION_DESTROYED,
72
73 /**
74 * Connection to be destroyed because of a distant peer, same as DESTROYED.
75 */
76 CADET_CONNECTION_BROKEN,
77};
78
79
80/**
81 * Struct containing all information regarding a connection to a peer.
82 */
83struct CadetConnection;
84
85/**
86 * Handle for messages queued but not yet sent.
87 */
88struct CadetConnectionQueue;
89
90#include "cadet_path.h"
91#include "gnunet-service-cadet_channel.h"
92#include "gnunet-service-cadet_peer.h" 36#include "gnunet-service-cadet_peer.h"
37#include "cadet_protocol.h"
93 38
94 39
95/** 40/**
96 * Check invariants for all connections using #check_neighbours(). 41 * Function called to notify tunnel about change in our readyness.
97 */
98void
99GCC_check_connections (void);
100
101
102/**
103 * Callback called when a queued message is sent.
104 * 42 *
105 * @param cls Closure. 43 * @param cls closure
106 * @param c Connection this message was on. 44 * @param is_ready #GNUNET_YES if the connection is now ready for transmission,
107 * @param type Type of message sent. 45 * #GNUNET_NO if the connection is no longer ready for transmission
108 * @param fwd Was this a FWD going message?
109 * @param size Size of the message.
110 */ 46 */
111typedef void 47typedef void
112(*GCC_sent) (void *cls, 48(*GCC_ReadyCallback)(void *cls,
113 struct CadetConnection *c, 49 int is_ready);
114 struct CadetConnectionQueue *q,
115 uint16_t type,
116 int fwd,
117 size_t size);
118 50
119 51
120/** 52/**
121 * Handler for connection creation. 53 * Destroy a connection, called when the CORE layer is already done
54 * (i.e. has received a BROKEN message), but if we still have to
55 * communicate the destruction of the connection to the tunnel (if one
56 * exists).
122 * 57 *
123 * @param peer Message sender (neighbor). 58 * @param cc connection to destroy
124 * @param msg Message itself.
125 */ 59 */
126void 60void
127GCC_handle_create (struct CadetPeer *peer, 61GCC_destroy_without_core (struct CadetConnection *cc);
128 const struct GNUNET_CADET_ConnectionCreateMessage *msg);
129 62
130 63
131/** 64/**
132 * Handler for connection confirmations. 65 * Destroy a connection, called if the tunnel association with the
66 * connection was already broken, but we still need to notify the CORE
67 * layer about the breakage.
133 * 68 *
134 * @param peer Message sender (neighbor). 69 * @param cc connection to destroy
135 * @param msg Message itself.
136 */ 70 */
137void 71void
138GCC_handle_confirm (struct CadetPeer *peer, 72GCC_destroy_without_tunnel (struct CadetConnection *cc);
139 const struct GNUNET_CADET_ConnectionCreateAckMessage *msg);
140 73
141 74
142/** 75/**
143 * Handler for notifications of broken connections. 76 * Lookup a connection by its identifier.
144 * 77 *
145 * @param peer Message sender (neighbor). 78 * @param cid identifier to resolve
146 * @param msg Message itself. 79 * @return NULL if connection was not found
147 */ 80 */
148void 81struct CadetConnection *
149GCC_handle_broken (struct CadetPeer *peer, 82GCC_lookup (const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid);
150 const struct GNUNET_CADET_ConnectionBrokenMessage *msg);
151 83
152/**
153 * Handler for notifications of destroyed connections.
154 *
155 * @param peer Message sender (neighbor).
156 * @param msg Message itself.
157 */
158void
159GCC_handle_destroy (struct CadetPeer *peer,
160 const struct GNUNET_CADET_ConnectionDestroyMessage *msg);
161 84
162/** 85/**
163 * Handler for cadet network traffic hop-by-hop acks. 86 * Create a connection to @a destination via @a path and
87 * notify @a cb whenever we are ready for more data.
164 * 88 *
165 * @param peer Message sender (neighbor). 89 * @param destination where to go
166 * @param msg Message itself. 90 * @param path which path to take (may not be the full path)
91 * @param off offset of @a destination on @a path
92 * @param options options for the connection
93 * @param ct which tunnel uses this connection
94 * @param ready_cb function to call when ready to transmit
95 * @param ready_cb_cls closure for @a cb
96 * @return handle to the connection
167 */ 97 */
168void 98struct CadetConnection *
169GCC_handle_ack (struct CadetPeer *peer, 99GCC_create (struct CadetPeer *destination,
170 const struct GNUNET_CADET_ConnectionEncryptedAckMessage *msg); 100 struct CadetPeerPath *path,
101 unsigned int off,
102 enum GNUNET_CADET_ChannelOption options,
103 struct CadetTConnection *ct,
104 GCC_ReadyCallback ready_cb,
105 void *ready_cb_cls);
171 106
172/**
173 * Handler for cadet network traffic hop-by-hop data counter polls.
174 *
175 * @param peer Message sender (neighbor).
176 * @param msg Message itself.
177 */
178void
179GCC_handle_poll (struct CadetPeer *peer,
180 const struct GNUNET_CADET_ConnectionHopByHopPollMessage *msg);
181 107
182/** 108/**
183 * Handler for key exchange traffic (Axolotl KX). 109 * Create a connection to @a destination via @a path and
110 * notify @a cb whenever we are ready for more data. This
111 * is an inbound tunnel, so we must use the existing @a cid
184 * 112 *
185 * @param peer Message sender (neighbor). 113 * @param destination where to go
186 * @param msg Message itself. 114 * @param path which path to take (may not be the full path)
115 * @param options options for the connection
116 * @param ct which tunnel uses this connection
117 * @param ready_cb function to call when ready to transmit
118 * @param ready_cb_cls closure for @a cb
119 * @return handle to the connection, NULL if we already have
120 * a connection that takes precedence on @a path
187 */ 121 */
188void 122struct CadetConnection *
189GCC_handle_kx (struct CadetPeer *peer, 123GCC_create_inbound (struct CadetPeer *destination,
190 const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg); 124 struct CadetPeerPath *path,
125 enum GNUNET_CADET_ChannelOption options,
126 struct CadetTConnection *ct,
127 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
128 GCC_ReadyCallback ready_cb,
129 void *ready_cb_cls);
130
191 131
192/** 132/**
193 * Handler for encrypted cadet network traffic (channel mgmt, data). 133 * Transmit message @a msg via connection @a cc. Must only be called
134 * (once) after the connection has signalled that it is ready via the
135 * `ready_cb`. Clients can also use #GCC_is_ready() to check if the
136 * connection is right now ready for transmission.
194 * 137 *
195 * @param peer Message sender (neighbor). 138 * @param cc connection identification
196 * @param msg Message itself. 139 * @param env envelope with message to transmit;
140 * the #GNUNET_MQ_notify_send() must not have yet been used
141 * for the envelope. Also, the message better match the
142 * connection identifier of this connection...
197 */ 143 */
198void 144void
199GCC_handle_encrypted (struct CadetPeer *peer, 145GCC_transmit (struct CadetConnection *cc,
200 const struct GNUNET_CADET_TunnelEncryptedMessage *msg); 146 struct GNUNET_MQ_Envelope *env);
201 147
202/**
203 * Core handler for axolotl key exchange traffic.
204 *
205 * @param cls Closure (unused).
206 * @param message Message received.
207 * @param peer Neighbor who sent the message.
208 *
209 * @return GNUNET_OK, to keep the connection open.
210 */
211int
212GCC_handle_ax_kx (void *cls, const struct GNUNET_PeerIdentity *peer,
213 const struct GNUNET_MessageHeader *message);
214 148
215/** 149/**
216 * Core handler for axolotl encrypted cadet network traffic. 150 * A CREATE_ACK was received for this connection, process it.
217 * 151 *
218 * @param cls Closure (unused). 152 * @param cc the connection that got the ACK.
219 * @param message Message received.
220 * @param peer Neighbor who sent the message.
221 *
222 * @return GNUNET_OK, to keep the connection open.
223 */ 153 */
224int 154void
225GCC_handle_ax (void *cls, const struct GNUNET_PeerIdentity *peer, 155GCC_handle_connection_create_ack (struct CadetConnection *cc);
226 struct GNUNET_MessageHeader *message);
227 156
228/**
229 * Core handler for cadet keepalives.
230 *
231 * @param cls closure
232 * @param message message
233 * @param peer peer identity this notification is about
234 * @return GNUNET_OK to keep the connection open,
235 * GNUNET_SYSERR to close it (signal serious error)
236 *
237 * TODO: Check who we got this from, to validate route.
238 */
239int
240GCC_handle_keepalive (void *cls, const struct GNUNET_PeerIdentity *peer,
241 const struct GNUNET_MessageHeader *message);
242 157
243/** 158/**
244 * Send an ACK on the appropriate connection/channel, depending on 159 * We got a #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE for a
245 * the direction and the position of the peer. 160 * connection that we already have. Either our ACK got lost
161 * or something is fishy. Consider retransmitting the ACK.
246 * 162 *
247 * @param c Which connection to send the hop-by-hop ACK. 163 * @param cc connection that got the duplicate CREATE
248 * @param fwd Is this a fwd ACK? (will go dest->root).
249 * @param force Send the ACK even if suboptimal (e.g. requested by POLL).
250 */ 164 */
251void 165void
252GCC_send_ack (struct CadetConnection *c, int fwd, int force); 166GCC_handle_duplicate_create (struct CadetConnection *cc);
253 167
254/**
255 * Initialize the connections subsystem
256 *
257 * @param c Configuration handle.
258 */
259void
260GCC_init (const struct GNUNET_CONFIGURATION_Handle *c);
261 168
262/** 169/**
263 * Shut down the connections subsystem. 170 * Handle KX message.
171 *
172 * @param cc connection that received encrypted message
173 * @param msg the key exchange message
264 */ 174 */
265void 175void
266GCC_shutdown (void); 176GCC_handle_kx (struct CadetConnection *cc,
177 const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg);
267 178
268/**
269 * Create a connection.
270 *
271 * @param cid Connection ID (either created locally or imposed remotely).
272 * @param t Tunnel this connection belongs to (or NULL for transit connections);
273 * @param path Path this connection has to use (copy is made).
274 * @param own_pos Own position in the @c path path.
275 *
276 * @return Newly created connection.
277 * NULL in case of error: own id not in path, wrong neighbors, ...
278 */
279struct CadetConnection *
280GCC_new (const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
281 struct CadetTunnel *t,
282 struct CadetPeerPath *path,
283 unsigned int own_pos);
284 179
285/** 180/**
286 * Connection is no longer needed: destroy it. 181 * Handle KX_AUTH message.
287 *
288 * Cancels all pending traffic (including possible DESTROY messages), all
289 * maintenance tasks and removes the connection from neighbor peers and tunnel.
290 * 182 *
291 * @param c Connection to destroy. 183 * @param cc connection that received encrypted message
184 * @param msg the key exchange message
292 */ 185 */
293void 186void
294GCC_destroy (struct CadetConnection *c); 187GCC_handle_kx_auth (struct CadetConnection *cc,
295 188 const struct GNUNET_CADET_TunnelKeyExchangeAuthMessage *msg);
296/**
297 * Get the connection ID.
298 *
299 * @param c Connection to get the ID from.
300 *
301 * @return ID of the connection.
302 */
303const struct GNUNET_CADET_ConnectionTunnelIdentifier *
304GCC_get_id (const struct CadetConnection *c);
305 189
306 190
307/** 191/**
308 * Get the connection path. 192 * Performance metrics for a connection.
309 *
310 * @param c Connection to get the path from.
311 *
312 * @return path used by the connection.
313 */ 193 */
314const struct CadetPeerPath * 194struct CadetConnectionMetrics
315GCC_get_path (const struct CadetConnection *c); 195{
316 196
317/** 197 /**
318 * Get the connection state. 198 * Our current best estimate of the latency, based on a weighted
319 * 199 * average of at least @a latency_datapoints values.
320 * @param c Connection to get the state from. 200 */
321 * 201 struct GNUNET_TIME_Relative aged_latency;
322 * @return state of the connection.
323 */
324enum CadetConnectionState
325GCC_get_state (const struct CadetConnection *c);
326 202
327/** 203 /**
328 * Get the connection tunnel. 204 * When was this connection first established? (by us sending or
329 * 205 * receiving the CREATE_ACK for the first time)
330 * @param c Connection to get the tunnel from. 206 */
331 * 207 struct GNUNET_TIME_Absolute age;
332 * @return tunnel of the connection.
333 */
334struct CadetTunnel *
335GCC_get_tunnel (const struct CadetConnection *c);
336 208
337/** 209 /**
338 * Get free buffer space in a connection. 210 * When was this connection last used? (by us sending or
339 * 211 * receiving a PAYLOAD message on it)
340 * @param c Connection. 212 */
341 * @param fwd Is query about FWD traffic? 213 struct GNUNET_TIME_Absolute last_use;
342 *
343 * @return Free buffer space [0 - max_msgs_queue/max_connections]
344 */
345unsigned int
346GCC_get_buffer (struct CadetConnection *c, int fwd);
347 214
348/** 215 /**
349 * Get how many messages have we allowed to send to us from a direction. 216 * How many packets that ought to generate an ACK did we send via
350 * 217 * this connection?
351 * @param c Connection. 218 */
352 * @param fwd Are we asking about traffic from FWD (BCK messages)? 219 unsigned long long num_acked_transmissions;
353 *
354 * @return last_ack_sent - last_pid_recv
355 */
356unsigned int
357GCC_get_allowed (struct CadetConnection *c, int fwd);
358 220
359/** 221 /**
360 * Get messages queued in a connection. 222 * Number of packets that were sent via this connection did actually
361 * 223 * receive an ACK? (Note: ACKs may be transmitted and lost via
362 * @param c Connection. 224 * other connections, so this value should only be interpreted
363 * @param fwd Is query about FWD traffic? 225 * relative to @e num_acked_transmissions and in relation to other
364 * 226 * connections.)
365 * @return Number of messages queued. 227 */
366 */ 228 unsigned long long num_successes;
367unsigned int
368GCC_get_qn (struct CadetConnection *c, int fwd);
369 229
370/** 230};
371 * Get next PID to use.
372 *
373 * @param c Connection.
374 * @param fwd Is query about FWD traffic?
375 * @return Next PID to use.
376 */
377struct CadetEncryptedMessageIdentifier
378GCC_get_pid (struct CadetConnection *c, int fwd);
379 231
380/**
381 * Allow the connection to advertise a buffer of the given size.
382 *
383 * The connection will send an @c fwd ACK message (so: in direction !fwd)
384 * allowing up to last_pid_recv + buffer.
385 *
386 * @param c Connection.
387 * @param buffer How many more messages the connection can accept.
388 * @param fwd Is this about FWD traffic? (The ack will go dest->root).
389 */
390void
391GCC_allow (struct CadetConnection *c, unsigned int buffer, int fwd);
392 232
393/** 233/**
394 * Send FWD keepalive packets for a connection. 234 * Obtain performance @a metrics from @a cc.
395 * 235 *
396 * @param cls Closure (connection for which to send the keepalive). 236 * @param cc connection to query
397 * @param tc Notification context. 237 * @return the metrics
398 */ 238 */
399void 239const struct CadetConnectionMetrics *
400GCC_fwd_keepalive (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); 240GCC_get_metrics (struct CadetConnection *cc);
241
401 242
402/** 243/**
403 * Send BCK keepalive packets for a connection. 244 * Handle encrypted message.
404 * 245 *
405 * @param cls Closure (connection for which to send the keepalive). 246 * @param cc connection that received encrypted message
406 * @param tc Notification context. 247 * @param msg the encrypted message to decrypt
407 */ 248 */
408void 249void
409GCC_bck_keepalive (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); 250GCC_handle_encrypted (struct CadetConnection *cc,
251 const struct GNUNET_CADET_TunnelEncryptedMessage *msg);
410 252
411 253
412/** 254/**
413 * Notify other peers on a connection of a broken link. Mark connections 255 * We sent a message for which we expect to receive an ACK via
414 * to destroy after all traffic has been sent. 256 * the connection identified by @a cti.
415 * 257 *
416 * @param c Connection on which there has been a disconnection. 258 * @param cid connection identifier where we expect an ACK
417 * @param peer Peer that disconnected.
418 */ 259 */
419void 260void
420GCC_neighbor_disconnected (struct CadetConnection *c, struct CadetPeer *peer); 261GCC_ack_expected (const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid);
421 262
422/**
423 * Is this peer the first one on the connection?
424 *
425 * @param c Connection.
426 * @param fwd Is this about fwd traffic?
427 *
428 * @return #GNUNET_YES if origin, #GNUNET_NO if relay/terminal.
429 */
430int
431GCC_is_origin (struct CadetConnection *c, int fwd);
432 263
433/** 264/**
434 * Is this peer the last one on the connection? 265 * We observed an ACK for a message that was originally sent via
435 * 266 * the connection identified by @a cti.
436 * @param c Connection.
437 * @param fwd Is this about fwd traffic?
438 * Note that the ROOT is the terminal for BCK traffic!
439 * 267 *
440 * @return #GNUNET_YES if terminal, #GNUNET_NO if relay/origin. 268 * @param cid connection identifier where we got an ACK for a message
269 * that was originally sent via this connection (the ACK
270 * may have gotten back to us via a different connection).
441 */ 271 */
442int 272void
443GCC_is_terminal (struct CadetConnection *c, int fwd); 273GCC_ack_observed (const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid);
444
445/**
446 * See if we are allowed to send by the next hop in the given direction.
447 *
448 * @param c Connection.
449 * @param fwd Is this about fwd traffic?
450 *
451 * @return #GNUNET_YES in case it's OK to send.
452 */
453int
454GCC_is_sendable (struct CadetConnection *c, int fwd);
455 274
456/**
457 * Check if this connection is a direct one (never trim a direct connection).
458 *
459 * @param c Connection.
460 *
461 * @return #GNUNET_YES in case it's a direct connection, #GNUNET_NO otherwise.
462 */
463int
464GCC_is_direct (struct CadetConnection *c);
465 275
466/** 276/**
467 * Cancel a previously sent message while it's in the queue. 277 * We observed some the given @a latency on the connection
278 * identified by @a cti. (The same connection was taken
279 * in both directions.)
468 * 280 *
469 * ONLY can be called before the continuation given to the send function 281 * @param cti connection identifier where we measured latency
470 * is called. Once the continuation is called, the message is no longer in the 282 * @param latency the observed latency
471 * queue.
472 *
473 * @param q Handle to the queue.
474 */ 283 */
475void 284void
476GCC_cancel (struct CadetConnectionQueue *q); 285GCC_latency_observed (const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti,
286 struct GNUNET_TIME_Relative latency);
477 287
478/**
479 * Sends an already built message on a connection, properly registering
480 * all used resources.
481 *
482 * @param message Message to send.
483 * @param payload_type Type of payload, in case the message is encrypted.
484 * 0 for restransmissions (when type is no longer known)
485 * UINT16_MAX when not applicable.
486 * @param payload_id ID of the payload (PID, ACK, ...).
487 * @param c Connection on which this message is transmitted.
488 * @param fwd Is this a fwd message?
489 * @param force Force the connection to accept the message (buffer overfill).
490 * @param cont Continuation called once message is sent. Can be NULL.
491 * @param cont_cls Closure for @c cont.
492 *
493 * @return Handle to cancel the message before it's sent.
494 * NULL on error.
495 * Invalid on @c cont call.
496 */
497struct CadetConnectionQueue *
498GCC_send_prebuilt_message (const struct GNUNET_MessageHeader *message,
499 uint16_t payload_type,
500 struct CadetEncryptedMessageIdentifier payload_id,
501 struct CadetConnection *c, int fwd, int force,
502 GCC_sent cont, void *cont_cls);
503 288
504/** 289/**
505 * Sends a CREATE CONNECTION message for a path to a peer. 290 * Return the tunnel associated with this connection.
506 * Changes the connection and tunnel states if necessary.
507 * 291 *
508 * @param connection Connection to create. 292 * @param cc connection to query
293 * @return corresponding entry in the tunnel's connection list
509 */ 294 */
510void 295struct CadetTConnection *
511GCC_send_create (struct CadetConnection *connection); 296GCC_get_ct (struct CadetConnection *cc);
512 297
513/**
514 * Send a message to all peers in this connection that the connection
515 * is no longer valid.
516 *
517 * If some peer should not receive the message, it should be zero'ed out
518 * before calling this function.
519 *
520 * @param c The connection whose peers to notify.
521 */
522void
523GCC_send_destroy (struct CadetConnection *c);
524 298
525/** 299/**
526 * @brief Start a polling timer for the connection. 300 * Obtain the path used by this connection.
527 * 301 *
528 * When a neighbor does not accept more traffic on the connection it could be 302 * @param cc connection
529 * caused by a simple congestion or by a lost ACK. Polling enables to check 303 * @return path to @a cc
530 * for the lastest ACK status for a connection.
531 *
532 * @param c Connection.
533 * @param fwd Should we poll in the FWD direction?
534 */ 304 */
535void 305struct CadetPeerPath *
536GCC_start_poll (struct CadetConnection *c, int fwd); 306GCC_get_path (struct CadetConnection *cc);
537 307
538 308
539/** 309/**
540 * @brief Stop polling a connection for ACKs. 310 * Obtain unique ID for the connection.
541 *
542 * Once we have enough ACKs for future traffic, polls are no longer necessary.
543 * 311 *
544 * @param c Connection. 312 * @param cc connection.
545 * @param fwd Should we stop the poll in the FWD direction? 313 * @return unique number of the connection
546 */ 314 */
547void 315const struct GNUNET_CADET_ConnectionTunnelIdentifier *
548GCC_stop_poll (struct CadetConnection *c, int fwd); 316GCC_get_id (struct CadetConnection *cc);
317
549 318
550/** 319/**
551 * Get a (static) string for a connection. 320 * Get a (static) string for a connection.
552 * 321 *
553 * @param c Connection. 322 * @param cc Connection.
554 */ 323 */
555const char * 324const char *
556GCC_2s (const struct CadetConnection *c); 325GCC_2s (const struct CadetConnection *cc);
326
557 327
558/** 328/**
559 * Log all possible info about the connection state. 329 * Log connection info.
560 * 330 *
561 * @param c Connection to debug. 331 * @param cc connection
562 * @param level Debug level to use. 332 * @param level Debug level to use.
563 */ 333 */
564void 334void
565GCC_debug (const struct CadetConnection *c, enum GNUNET_ErrorType level); 335GCC_debug (struct CadetConnection *cc,
336 enum GNUNET_ErrorType level);
566 337
567#if 0 /* keep Emacsens' auto-indent happy */
568{
569#endif
570#ifdef __cplusplus
571}
572#endif
573 338
574/* ifndef GNUNET_SERVICE_CADET_CONNECTION_H */
575#endif 339#endif
576/* end of gnunet-service-cadet_connection.h */
diff --git a/src/cadet/gnunet-service-cadet-new_core.c b/src/cadet/gnunet-service-cadet_core.c
index 4a4ead05b..ae03b4f35 100644
--- a/src/cadet/gnunet-service-cadet-new_core.c
+++ b/src/cadet/gnunet-service-cadet_core.c
@@ -30,22 +30,64 @@
30 * - Optimization: given BROKEN messages, destroy paths (?) 30 * - Optimization: given BROKEN messages, destroy paths (?)
31 */ 31 */
32#include "platform.h" 32#include "platform.h"
33#include "gnunet-service-cadet-new_core.h" 33#include "gnunet-service-cadet_core.h"
34#include "gnunet-service-cadet-new_paths.h" 34#include "gnunet-service-cadet_paths.h"
35#include "gnunet-service-cadet-new_peer.h" 35#include "gnunet-service-cadet_peer.h"
36#include "gnunet-service-cadet-new_connection.h" 36#include "gnunet-service-cadet_connection.h"
37#include "gnunet-service-cadet-new_tunnels.h" 37#include "gnunet-service-cadet_tunnels.h"
38#include "gnunet_core_service.h" 38#include "gnunet_core_service.h"
39#include "gnunet_statistics_service.h"
39#include "cadet_protocol.h" 40#include "cadet_protocol.h"
40 41
41 42
42#define LOG(level, ...) GNUNET_log_from(level,"cadet-cor",__VA_ARGS__) 43#define LOG(level, ...) GNUNET_log_from(level,"cadet-cor",__VA_ARGS__)
43 44
45/**
46 * Information we keep per direction for a route.
47 */
48struct RouteDirection;
49
44 50
45/** 51/**
46 * Number of messages we are willing to buffer per route. 52 * Set of CadetRoutes that have exactly the same number of messages
53 * in their buffer. Used so we can efficiently find all of those
54 * routes that have the current maximum of messages in the buffer (in
55 * case we have to purge).
47 */ 56 */
48#define ROUTE_BUFFER_SIZE 8 57struct Rung
58{
59
60 /**
61 * Rung of RouteDirections with one more buffer entry each.
62 */
63 struct Rung *next;
64
65 /**
66 * Rung of RouteDirections with one less buffer entry each.
67 */
68 struct Rung *prev;
69
70 /**
71 * DLL of route directions with a number of buffer entries matching this rung.
72 */
73 struct RouteDirection *rd_head;
74
75 /**
76 * DLL of route directions with a number of buffer entries matching this rung.
77 */
78 struct RouteDirection *rd_tail;
79
80 /**
81 * Total number of route directions in this rung.
82 */
83 unsigned int num_routes;
84
85 /**
86 * Number of messages route directions at this rung have
87 * in their buffer.
88 */
89 unsigned int rung_off;
90};
49 91
50 92
51/** 93/**
@@ -53,35 +95,46 @@
53 */ 95 */
54struct RouteDirection 96struct RouteDirection
55{ 97{
98
56 /** 99 /**
57 * Target peer. 100 * DLL of other route directions within the same `struct Rung`.
58 */ 101 */
59 struct CadetPeer *hop; 102 struct RouteDirection *prev;
60 103
61 /** 104 /**
62 * Route this direction is part of. 105 * DLL of other route directions within the same `struct Rung`.
63 */ 106 */
64 struct CadetRoute *my_route; 107 struct RouteDirection *next;
65 108
66 /** 109 /**
67 * Message queue manager for @e hop. 110 * Rung of this route direction (matches length of the buffer DLL).
68 */ 111 */
69 struct GCP_MessageQueueManager *mqm; 112 struct Rung *rung;
113
114 /**
115 * Head of DLL of envelopes we have in the buffer for this direction.
116 */
117 struct GNUNET_MQ_Envelope *env_head;
70 118
71 /** 119 /**
72 * Cyclic message buffer to @e hop. 120 * Tail of DLL of envelopes we have in the buffer for this direction.
73 */ 121 */
74 struct GNUNET_MQ_Envelope *out_buffer[ROUTE_BUFFER_SIZE]; 122 struct GNUNET_MQ_Envelope *env_tail;
75 123
76 /** 124 /**
77 * Next write offset to use to append messages to @e out_buffer. 125 * Target peer.
126 */
127 struct CadetPeer *hop;
128
129 /**
130 * Route this direction is part of.
78 */ 131 */
79 unsigned int out_wpos; 132 struct CadetRoute *my_route;
80 133
81 /** 134 /**
82 * Next read offset to use to retrieve messages from @e out_buffer. 135 * Message queue manager for @e hop.
83 */ 136 */
84 unsigned int out_rpos; 137 struct GCP_MessageQueueManager *mqm;
85 138
86 /** 139 /**
87 * Is @e mqm currently ready for transmission? 140 * Is @e mqm currently ready for transmission?
@@ -122,6 +175,15 @@ struct CadetRoute
122 */ 175 */
123 struct GNUNET_TIME_Absolute last_use; 176 struct GNUNET_TIME_Absolute last_use;
124 177
178 /**
179 * Position of this route in the #route_heap.
180 */
181 struct GNUNET_CONTAINER_HeapNode *hn;
182
183 /**
184 * Options for the route, control buffering.
185 */
186 enum GNUNET_CADET_ChannelOption options;
125}; 187};
126 188
127 189
@@ -135,6 +197,47 @@ static struct GNUNET_CORE_Handle *core;
135 */ 197 */
136static struct GNUNET_CONTAINER_MultiShortmap *routes; 198static struct GNUNET_CONTAINER_MultiShortmap *routes;
137 199
200/**
201 * Heap of routes, MIN-sorted by last activity.
202 */
203static struct GNUNET_CONTAINER_Heap *route_heap;
204
205/**
206 * Rung zero (always pointed to by #rung_head).
207 */
208static struct Rung rung_zero;
209
210/**
211 * DLL of rungs, with the head always point to a rung of
212 * route directions with no messages in the queue.
213 */
214static struct Rung *rung_head = &rung_zero;
215
216/**
217 * Tail of the #rung_head DLL.
218 */
219static struct Rung *rung_tail = &rung_zero;
220
221/**
222 * Maximum number of concurrent routes this peer will support.
223 */
224static unsigned long long max_routes;
225
226/**
227 * Maximum number of envelopes we will buffer at this peer.
228 */
229static unsigned long long max_buffers;
230
231/**
232 * Current number of envelopes we have buffered at this peer.
233 */
234static unsigned long long cur_buffers;
235
236/**
237 * Task to timeout routes.
238 */
239static struct GNUNET_SCHEDULER_Task *timeout_task;
240
138 241
139/** 242/**
140 * Get the route corresponding to a hash. 243 * Get the route corresponding to a hash.
@@ -150,6 +253,91 @@ get_route (const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
150 253
151 254
152/** 255/**
256 * Lower the rung in which @a dir is by 1.
257 *
258 * @param dir direction to lower in rung.
259 */
260static void
261lower_rung (struct RouteDirection *dir)
262{
263 struct Rung *rung = dir->rung;
264 struct Rung *prev;
265
266 GNUNET_CONTAINER_DLL_remove (rung->rd_head,
267 rung->rd_tail,
268 dir);
269 prev = rung->prev;
270 GNUNET_assert (NULL != prev);
271 if (prev->rung_off != rung->rung_off - 1)
272 {
273 prev = GNUNET_new (struct Rung);
274 prev->rung_off = rung->rung_off - 1;
275 GNUNET_CONTAINER_DLL_insert_after (rung_head,
276 rung_tail,
277 rung->prev,
278 prev);
279 }
280 GNUNET_assert (NULL != prev);
281 GNUNET_CONTAINER_DLL_insert (prev->rd_head,
282 prev->rd_tail,
283 dir);
284 dir->rung = prev;
285}
286
287
288/**
289 * Discard the buffer @a env from the route direction @a dir and
290 * move @a dir down a rung.
291 *
292 * @param dir direction that contains the @a env in the buffer
293 * @param env envelope to discard
294 */
295static void
296discard_buffer (struct RouteDirection *dir,
297 struct GNUNET_MQ_Envelope *env)
298{
299 GNUNET_MQ_dll_remove (&dir->env_head,
300 &dir->env_tail,
301 env);
302 cur_buffers--;
303 GNUNET_MQ_discard (env);
304 lower_rung (dir);
305 GNUNET_STATISTICS_set (stats,
306 "# buffer use",
307 cur_buffers,
308 GNUNET_NO);
309}
310
311
312/**
313 * Discard all messages from the highest rung, to make space.
314 */
315static void
316discard_all_from_rung_tail ()
317{
318 struct Rung *tail = rung_tail;
319 struct RouteDirection *dir;
320
321 while (NULL != (dir = tail->rd_head))
322 {
323 LOG (GNUNET_ERROR_TYPE_DEBUG,
324 "Queue full due new message %s on connection %s, dropping old message\n",
325 GNUNET_sh2s (&dir->my_route->cid.connection_of_tunnel));
326 GNUNET_STATISTICS_update (stats,
327 "# messages dropped due to full buffer",
328 1,
329 GNUNET_NO);
330 discard_buffer (dir,
331 dir->env_head);
332 }
333 GNUNET_CONTAINER_DLL_remove (rung_head,
334 rung_tail,
335 tail);
336 GNUNET_free (tail);
337}
338
339
340/**
153 * We message @a msg from @a prev. Find its route by @a cid and 341 * We message @a msg from @a prev. Find its route by @a cid and
154 * forward to the next hop. Drop and signal broken route if we do not 342 * forward to the next hop. Drop and signal broken route if we do not
155 * have a route. 343 * have a route.
@@ -165,6 +353,8 @@ route_message (struct CadetPeer *prev,
165{ 353{
166 struct CadetRoute *route; 354 struct CadetRoute *route;
167 struct RouteDirection *dir; 355 struct RouteDirection *dir;
356 struct Rung *rung;
357 struct Rung *nxt;
168 struct GNUNET_MQ_Envelope *env; 358 struct GNUNET_MQ_Envelope *env;
169 359
170 route = get_route (cid); 360 route = get_route (cid);
@@ -178,6 +368,13 @@ route_message (struct CadetPeer *prev,
178 ntohs (msg->type), 368 ntohs (msg->type),
179 GCP_2s (prev), 369 GCP_2s (prev),
180 GNUNET_sh2s (&cid->connection_of_tunnel)); 370 GNUNET_sh2s (&cid->connection_of_tunnel));
371 switch (ntohs (msg->type))
372 {
373 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY:
374 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN:
375 /* No need to respond to these! */
376 return;
377 }
181 env = GNUNET_MQ_msg (bm, 378 env = GNUNET_MQ_msg (bm,
182 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN); 379 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN);
183 bm->cid = *cid; 380 bm->cid = *cid;
@@ -186,6 +383,9 @@ route_message (struct CadetPeer *prev,
186 env); 383 env);
187 return; 384 return;
188 } 385 }
386 route->last_use = GNUNET_TIME_absolute_get ();
387 GNUNET_CONTAINER_heap_update_cost (route->hn,
388 route->last_use.abs_value_us);
189 dir = (prev == route->prev.hop) ? &route->next : &route->prev; 389 dir = (prev == route->prev.hop) ? &route->next : &route->prev;
190 if (GNUNET_YES == dir->is_ready) 390 if (GNUNET_YES == dir->is_ready)
191 { 391 {
@@ -200,22 +400,59 @@ route_message (struct CadetPeer *prev,
200 GNUNET_MQ_msg_copy (msg)); 400 GNUNET_MQ_msg_copy (msg));
201 return; 401 return;
202 } 402 }
203 env = dir->out_buffer[dir->out_wpos]; 403 /* Check if buffering is disallowed, and if so, make sure we only queue
204 if (NULL != env) 404 one message per direction. */
405 if ( (0 != (route->options & GNUNET_CADET_OPTION_NOBUFFER)) &&
406 (NULL != dir->env_head) )
407 discard_buffer (dir,
408 dir->env_head);
409 rung = dir->rung;
410 if (cur_buffers == max_buffers)
205 { 411 {
206 /* Queue full, drop earliest message in queue */ 412 /* Need to make room. */
207 LOG (GNUNET_ERROR_TYPE_DEBUG, 413 if (NULL != rung->next)
208 "Queue full due to new message of type %u from %s to %s on connection %s, dropping old message\n", 414 {
209 ntohs (msg->type), 415 /* Easy case, drop messages from route directions in highest rung */
210 GCP_2s (prev), 416 discard_all_from_rung_tail ();
211 GNUNET_i2s (GCP_get_id (dir->hop)), 417 }
212 GNUNET_sh2s (&cid->connection_of_tunnel)); 418 else
213 GNUNET_assert (dir->out_rpos == dir->out_wpos); 419 {
214 GNUNET_MQ_discard (env); 420 /* We are in the highest rung, drop our own! */
215 dir->out_rpos++; 421 LOG (GNUNET_ERROR_TYPE_DEBUG,
216 if (ROUTE_BUFFER_SIZE == dir->out_rpos) 422 "Queue full due new message %s on connection %s, dropping old message\n",
217 dir->out_rpos = 0; 423 GNUNET_sh2s (&dir->my_route->cid.connection_of_tunnel));
424 GNUNET_STATISTICS_update (stats,
425 "# messages dropped due to full buffer",
426 1,
427 GNUNET_NO);
428 discard_buffer (dir,
429 dir->env_head);
430 rung = dir->rung;
431 }
432 }
433 /* remove 'dir' from current rung */
434 GNUNET_CONTAINER_DLL_remove (rung->rd_head,
435 rung->rd_tail,
436 dir);
437 /* make 'nxt' point to the next higher rung, creat if necessary */
438 nxt = rung->next;
439 if ( (NULL == nxt) ||
440 (rung->rung_off + 1 != nxt->rung_off) )
441 {
442 nxt = GNUNET_new (struct Rung);
443 nxt->rung_off = rung->rung_off + 1;
444 GNUNET_CONTAINER_DLL_insert_after (rung_head,
445 rung_tail,
446 rung,
447 nxt);
218 } 448 }
449 /* insert 'dir' into next higher rung */
450 GNUNET_CONTAINER_DLL_insert (nxt->rd_head,
451 nxt->rd_tail,
452 dir);
453 dir->rung = nxt;
454
455 /* add message into 'dir' buffer */
219 LOG (GNUNET_ERROR_TYPE_DEBUG, 456 LOG (GNUNET_ERROR_TYPE_DEBUG,
220 "Queueing new message of type %u from %s to %s on connection %s\n", 457 "Queueing new message of type %u from %s to %s on connection %s\n",
221 ntohs (msg->type), 458 ntohs (msg->type),
@@ -223,10 +460,23 @@ route_message (struct CadetPeer *prev,
223 GNUNET_i2s (GCP_get_id (dir->hop)), 460 GNUNET_i2s (GCP_get_id (dir->hop)),
224 GNUNET_sh2s (&cid->connection_of_tunnel)); 461 GNUNET_sh2s (&cid->connection_of_tunnel));
225 env = GNUNET_MQ_msg_copy (msg); 462 env = GNUNET_MQ_msg_copy (msg);
226 dir->out_buffer[dir->out_wpos] = env; 463 GNUNET_MQ_dll_insert_tail (&dir->env_head,
227 dir->out_wpos++; 464 &dir->env_tail,
228 if (ROUTE_BUFFER_SIZE == dir->out_wpos) 465 env);
229 dir->out_wpos = 0; 466 cur_buffers++;
467 GNUNET_STATISTICS_set (stats,
468 "# buffer use",
469 cur_buffers,
470 GNUNET_NO);
471 /* Clean up 'rung' if now empty (and not head) */
472 if ( (NULL == rung->rd_head) &&
473 (rung != rung_head) )
474 {
475 GNUNET_CONTAINER_DLL_remove (rung_head,
476 rung_tail,
477 rung);
478 GNUNET_free (rung);
479 }
230} 480}
231 481
232 482
@@ -261,18 +511,26 @@ check_connection_create (void *cls,
261static void 511static void
262destroy_direction (struct RouteDirection *dir) 512destroy_direction (struct RouteDirection *dir)
263{ 513{
264 for (unsigned int i=0;i<ROUTE_BUFFER_SIZE;i++) 514 struct GNUNET_MQ_Envelope *env;
265 if (NULL != dir->out_buffer[i]) 515
266 { 516 while (NULL != (env = dir->env_head))
267 GNUNET_MQ_discard (dir->out_buffer[i]); 517 {
268 dir->out_buffer[i] = NULL; 518 GNUNET_STATISTICS_update (stats,
269 } 519 "# messages dropped due to route destruction",
520 1,
521 GNUNET_NO);
522 discard_buffer (dir,
523 env);
524 }
270 if (NULL != dir->mqm) 525 if (NULL != dir->mqm)
271 { 526 {
272 GCP_request_mq_cancel (dir->mqm, 527 GCP_request_mq_cancel (dir->mqm,
273 NULL); 528 NULL);
274 dir->mqm = NULL; 529 dir->mqm = NULL;
275 } 530 }
531 GNUNET_CONTAINER_DLL_remove (rung_head->rd_head,
532 rung_head->rd_tail,
533 dir);
276} 534}
277 535
278 536
@@ -289,6 +547,16 @@ destroy_route (struct CadetRoute *route)
289 GNUNET_i2s (GCP_get_id (route->prev.hop)), 547 GNUNET_i2s (GCP_get_id (route->prev.hop)),
290 GNUNET_i2s2 (GCP_get_id (route->next.hop)), 548 GNUNET_i2s2 (GCP_get_id (route->next.hop)),
291 GNUNET_sh2s (&route->cid.connection_of_tunnel)); 549 GNUNET_sh2s (&route->cid.connection_of_tunnel));
550 GNUNET_assert (route ==
551 GNUNET_CONTAINER_heap_remove_node (route->hn));
552 GNUNET_assert (GNUNET_YES ==
553 GNUNET_CONTAINER_multishortmap_remove (routes,
554 &route->cid.connection_of_tunnel,
555 route));
556 GNUNET_STATISTICS_set (stats,
557 "# routes",
558 GNUNET_CONTAINER_multishortmap_size (routes),
559 GNUNET_NO);
292 destroy_direction (&route->prev); 560 destroy_direction (&route->prev);
293 destroy_direction (&route->next); 561 destroy_direction (&route->next);
294 GNUNET_free (route); 562 GNUNET_free (route);
@@ -328,7 +596,6 @@ send_broken (struct RouteDirection *target,
328 bm->peer1 = *peer1; 596 bm->peer1 = *peer1;
329 if (NULL != peer2) 597 if (NULL != peer2)
330 bm->peer2 = *peer2; 598 bm->peer2 = *peer2;
331
332 GCP_request_mq_cancel (target->mqm, 599 GCP_request_mq_cancel (target->mqm,
333 env); 600 env);
334 target->mqm = NULL; 601 target->mqm = NULL;
@@ -336,6 +603,49 @@ send_broken (struct RouteDirection *target,
336 603
337 604
338/** 605/**
606 * Function called to check if any routes have timed out, and if
607 * so, to clean them up. Finally, schedules itself again at the
608 * earliest time where there might be more work.
609 *
610 * @param cls NULL
611 */
612static void
613timeout_cb (void *cls)
614{
615 struct CadetRoute *r;
616 struct GNUNET_TIME_Relative linger;
617 struct GNUNET_TIME_Absolute exp;
618
619 timeout_task = NULL;
620 linger = GNUNET_TIME_relative_multiply (keepalive_period,
621 3);
622 while (NULL != (r = GNUNET_CONTAINER_heap_peek (route_heap)))
623 {
624 exp = GNUNET_TIME_absolute_add (r->last_use,
625 linger);
626 if (0 != GNUNET_TIME_absolute_get_duration (exp).rel_value_us)
627 {
628 /* Route not yet timed out, wait until it does. */
629 timeout_task = GNUNET_SCHEDULER_add_at (exp,
630 &timeout_cb,
631 NULL);
632 return;
633 }
634 send_broken (&r->prev,
635 &r->cid,
636 NULL,
637 NULL);
638 send_broken (&r->next,
639 &r->cid,
640 NULL,
641 NULL);
642 destroy_route (r);
643 }
644 /* No more routes left, so no need for a #timeout_task */
645}
646
647
648/**
339 * Function called when the message queue to the previous hop 649 * Function called when the message queue to the previous hop
340 * becomes available/unavailable. We expect this function to 650 * becomes available/unavailable. We expect this function to
341 * be called immediately when we register, and then again 651 * be called immediately when we register, and then again
@@ -360,12 +670,17 @@ dir_ready_cb (void *cls,
360 struct GNUNET_MQ_Envelope *env; 670 struct GNUNET_MQ_Envelope *env;
361 671
362 dir->is_ready = GNUNET_YES; 672 dir->is_ready = GNUNET_YES;
363 if (NULL != (env = dir->out_buffer[dir->out_rpos])) 673 if (NULL != (env = dir->env_head))
364 { 674 {
365 dir->out_buffer[dir->out_rpos] = NULL; 675 GNUNET_MQ_dll_remove (&dir->env_head,
366 dir->out_rpos++; 676 &dir->env_tail,
367 if (ROUTE_BUFFER_SIZE == dir->out_rpos) 677 env);
368 dir->out_rpos = 0; 678 cur_buffers--;
679 GNUNET_STATISTICS_set (stats,
680 "# buffer use",
681 cur_buffers,
682 GNUNET_NO);
683 lower_rung (dir);
369 dir->is_ready = GNUNET_NO; 684 dir->is_ready = GNUNET_NO;
370 GCP_send (dir->mqm, 685 GCP_send (dir->mqm,
371 env); 686 env);
@@ -398,11 +713,44 @@ dir_init (struct RouteDirection *dir,
398 dir->mqm = GCP_request_mq (hop, 713 dir->mqm = GCP_request_mq (hop,
399 &dir_ready_cb, 714 &dir_ready_cb,
400 dir); 715 dir);
716 GNUNET_CONTAINER_DLL_insert (rung_head->rd_head,
717 rung_head->rd_tail,
718 dir);
719 dir->rung = rung_head;
401 GNUNET_assert (GNUNET_YES == dir->is_ready); 720 GNUNET_assert (GNUNET_YES == dir->is_ready);
402} 721}
403 722
404 723
405/** 724/**
725 * We could not create the desired route. Send a
726 * #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN
727 * message to @a target.
728 *
729 * @param target who should receive the message
730 * @param cid identifier of the connection/route that failed
731 * @param failure_at neighbour with which we failed to route,
732 * or NULL.
733 */
734static void
735send_broken_without_mqm (struct CadetPeer *target,
736 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
737 const struct GNUNET_PeerIdentity *failure_at)
738{
739 struct GNUNET_MQ_Envelope *env;
740 struct GNUNET_CADET_ConnectionBrokenMessage *bm;
741
742 env = GNUNET_MQ_msg (bm,
743 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN);
744 bm->cid = *cid;
745 bm->peer1 = my_full_id;
746 if (NULL != failure_at)
747 bm->peer2 = *failure_at;
748 GCP_send_ooo (target,
749 env);
750}
751
752
753/**
406 * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE 754 * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE
407 * 755 *
408 * @param cls Closure (CadetPeer for neighbor that sent the message). 756 * @param cls Closure (CadetPeer for neighbor that sent the message).
@@ -419,7 +767,9 @@ handle_connection_create (void *cls,
419 uint16_t size = ntohs (msg->header.size) - sizeof (*msg); 767 uint16_t size = ntohs (msg->header.size) - sizeof (*msg);
420 unsigned int path_length; 768 unsigned int path_length;
421 unsigned int off; 769 unsigned int off;
770 enum GNUNET_CADET_ChannelOption options;
422 771
772 options = (enum GNUNET_CADET_ChannelOption) ntohl (msg->options);
423 path_length = size / sizeof (struct GNUNET_PeerIdentity); 773 path_length = size / sizeof (struct GNUNET_PeerIdentity);
424 /* Initiator is at offset 0. */ 774 /* Initiator is at offset 0. */
425 for (off=1;off<path_length;off++) 775 for (off=1;off<path_length;off++)
@@ -460,8 +810,7 @@ handle_connection_create (void *cls,
460 struct CadetPeerPath *path; 810 struct CadetPeerPath *path;
461 struct CadetPeer *origin; 811 struct CadetPeer *origin;
462 812
463 cc = GNUNET_CONTAINER_multishortmap_get (connections, 813 cc = GCC_lookup (&msg->cid);
464 &msg->cid.connection_of_tunnel);
465 if (NULL != cc) 814 if (NULL != cc)
466 { 815 {
467 LOG (GNUNET_ERROR_TYPE_DEBUG, 816 LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -479,10 +828,25 @@ handle_connection_create (void *cls,
479 GNUNET_sh2s (&msg->cid.connection_of_tunnel)); 828 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
480 path = GCPP_get_path_from_route (path_length - 1, 829 path = GCPP_get_path_from_route (path_length - 1,
481 pids); 830 pids);
482 GCT_add_inbound_connection (GCP_get_tunnel (origin, 831 if (GNUNET_OK !=
483 GNUNET_YES), 832 GCT_add_inbound_connection (GCP_get_tunnel (origin,
484 &msg->cid, 833 GNUNET_YES),
485 path); 834 &msg->cid,
835 (enum GNUNET_CADET_ChannelOption) ntohl (msg->options),
836 path))
837 {
838 /* Send back BROKEN: duplicate connection on the same path,
839 we will use the other one. */
840 LOG (GNUNET_ERROR_TYPE_DEBUG,
841 "Received CADET_CONNECTION_CREATE from %s for %s, but %s already has a connection. Sending BROKEN\n",
842 GCP_2s (sender),
843 GNUNET_sh2s (&msg->cid.connection_of_tunnel),
844 GCPP_2s (path));
845 send_broken_without_mqm (sender,
846 &msg->cid,
847 NULL);
848 return;
849 }
486 return; 850 return;
487 } 851 }
488 /* We are merely a hop on the way, check if we can support the route */ 852 /* We are merely a hop on the way, check if we can support the route */
@@ -492,22 +856,26 @@ handle_connection_create (void *cls,
492 (GNUNET_NO == GCP_has_core_connection (next)) ) 856 (GNUNET_NO == GCP_has_core_connection (next)) )
493 { 857 {
494 /* unworkable, send back BROKEN notification */ 858 /* unworkable, send back BROKEN notification */
495 struct GNUNET_MQ_Envelope *env;
496 struct GNUNET_CADET_ConnectionBrokenMessage *bm;
497
498 LOG (GNUNET_ERROR_TYPE_DEBUG, 859 LOG (GNUNET_ERROR_TYPE_DEBUG,
499 "Received CADET_CONNECTION_CREATE from %s for %s. Next hop %s:%u is down. Sending BROKEN\n", 860 "Received CADET_CONNECTION_CREATE from %s for %s. Next hop %s:%u is down. Sending BROKEN\n",
500 GCP_2s (sender), 861 GCP_2s (sender),
501 GNUNET_sh2s (&msg->cid.connection_of_tunnel), 862 GNUNET_sh2s (&msg->cid.connection_of_tunnel),
502 GNUNET_i2s (&pids[off + 1]), 863 GNUNET_i2s (&pids[off + 1]),
503 off + 1); 864 off + 1);
504 env = GNUNET_MQ_msg (bm, 865 send_broken_without_mqm (sender,
505 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN); 866 &msg->cid,
506 bm->cid = msg->cid; 867 &pids[off + 1]);
507 bm->peer1 = pids[off + 1]; 868 return;
508 bm->peer2 = my_full_id; 869 }
509 GCP_send_ooo (sender, 870 if (max_routes <= GNUNET_CONTAINER_multishortmap_size (routes))
510 env); 871 {
872 LOG (GNUNET_ERROR_TYPE_DEBUG,
873 "Received CADET_CONNECTION_CREATE from %s for %s. We have reached our route limit. Sending BROKEN\n",
874 GCP_2s (sender),
875 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
876 send_broken_without_mqm (sender,
877 &msg->cid,
878 &pids[off - 1]);
511 return; 879 return;
512 } 880 }
513 881
@@ -519,7 +887,9 @@ handle_connection_create (void *cls,
519 GNUNET_i2s (&pids[off + 1]), 887 GNUNET_i2s (&pids[off + 1]),
520 off + 1); 888 off + 1);
521 route = GNUNET_new (struct CadetRoute); 889 route = GNUNET_new (struct CadetRoute);
890 route->options = options;
522 route->cid = msg->cid; 891 route->cid = msg->cid;
892 route->last_use = GNUNET_TIME_absolute_get ();
523 dir_init (&route->prev, 893 dir_init (&route->prev,
524 route, 894 route,
525 sender); 895 sender);
@@ -531,6 +901,18 @@ handle_connection_create (void *cls,
531 &route->cid.connection_of_tunnel, 901 &route->cid.connection_of_tunnel,
532 route, 902 route,
533 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 903 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
904 GNUNET_STATISTICS_set (stats,
905 "# routes",
906 GNUNET_CONTAINER_multishortmap_size (routes),
907 GNUNET_NO);
908 route->hn = GNUNET_CONTAINER_heap_insert (route_heap,
909 route,
910 route->last_use.abs_value_us);
911 if (NULL == timeout_task)
912 timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (keepalive_period,
913 3),
914 &timeout_cb,
915 NULL);
534} 916}
535 917
536 918
@@ -548,8 +930,7 @@ handle_connection_create_ack (void *cls,
548 struct CadetConnection *cc; 930 struct CadetConnection *cc;
549 931
550 /* First, check if ACK belongs to a connection that ends here. */ 932 /* First, check if ACK belongs to a connection that ends here. */
551 cc = GNUNET_CONTAINER_multishortmap_get (connections, 933 cc = GCC_lookup (&msg->cid);
552 &msg->cid.connection_of_tunnel);
553 if (NULL != cc) 934 if (NULL != cc)
554 { 935 {
555 /* verify ACK came from the right direction */ 936 /* verify ACK came from the right direction */
@@ -593,8 +974,7 @@ handle_connection_broken (void *cls,
593 struct CadetRoute *route; 974 struct CadetRoute *route;
594 975
595 /* First, check if message belongs to a connection that ends here. */ 976 /* First, check if message belongs to a connection that ends here. */
596 cc = GNUNET_CONTAINER_multishortmap_get (connections, 977 cc = GCC_lookup (&msg->cid);
597 &msg->cid.connection_of_tunnel);
598 if (NULL != cc) 978 if (NULL != cc)
599 { 979 {
600 /* verify message came from the right direction */ 980 /* verify message came from the right direction */
@@ -611,18 +991,19 @@ handle_connection_broken (void *cls,
611 LOG (GNUNET_ERROR_TYPE_DEBUG, 991 LOG (GNUNET_ERROR_TYPE_DEBUG,
612 "Received CONNECTION_BROKEN for connection %s. Destroying it.\n", 992 "Received CONNECTION_BROKEN for connection %s. Destroying it.\n",
613 GNUNET_sh2s (&msg->cid.connection_of_tunnel)); 993 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
614 GCC_destroy (cc); 994 GCC_destroy_without_core (cc);
615 995
616 /* FIXME: also destroy the path up to the specified link! */ 996 /* FIXME: also destroy the path up to the specified link! */
617 return; 997 return;
618 } 998 }
619 999
620 /* We're just an intermediary peer, route the message along its path */ 1000 /* We're just an intermediary peer, route the message along its path */
621 route = get_route (&msg->cid);
622 route_message (peer, 1001 route_message (peer,
623 &msg->cid, 1002 &msg->cid,
624 &msg->header); 1003 &msg->header);
625 destroy_route (route); 1004 route = get_route (&msg->cid);
1005 if (NULL != route)
1006 destroy_route (route);
626 /* FIXME: also destroy paths we MAY have up to the specified link! */ 1007 /* FIXME: also destroy paths we MAY have up to the specified link! */
627} 1008}
628 1009
@@ -642,8 +1023,7 @@ handle_connection_destroy (void *cls,
642 struct CadetRoute *route; 1023 struct CadetRoute *route;
643 1024
644 /* First, check if message belongs to a connection that ends here. */ 1025 /* First, check if message belongs to a connection that ends here. */
645 cc = GNUNET_CONTAINER_multishortmap_get (connections, 1026 cc = GCC_lookup (&msg->cid);
646 &msg->cid.connection_of_tunnel);
647 if (NULL != cc) 1027 if (NULL != cc)
648 { 1028 {
649 /* verify message came from the right direction */ 1029 /* verify message came from the right direction */
@@ -661,7 +1041,7 @@ handle_connection_destroy (void *cls,
661 "Received CONNECTION_DESTROY for connection %s. Destroying connection.\n", 1041 "Received CONNECTION_DESTROY for connection %s. Destroying connection.\n",
662 GNUNET_sh2s (&msg->cid.connection_of_tunnel)); 1042 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
663 1043
664 GCC_destroy (cc); 1044 GCC_destroy_without_core (cc);
665 return; 1045 return;
666 } 1046 }
667 1047
@@ -669,11 +1049,12 @@ handle_connection_destroy (void *cls,
669 LOG (GNUNET_ERROR_TYPE_DEBUG, 1049 LOG (GNUNET_ERROR_TYPE_DEBUG,
670 "Received CONNECTION_DESTROY for connection %s. Destroying route.\n", 1050 "Received CONNECTION_DESTROY for connection %s. Destroying route.\n",
671 GNUNET_sh2s (&msg->cid.connection_of_tunnel)); 1051 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
672 route = get_route (&msg->cid);
673 route_message (peer, 1052 route_message (peer,
674 &msg->cid, 1053 &msg->cid,
675 &msg->header); 1054 &msg->header);
676 destroy_route (route); 1055 route = get_route (&msg->cid);
1056 if (NULL != route)
1057 destroy_route (route);
677} 1058}
678 1059
679 1060
@@ -691,8 +1072,7 @@ handle_tunnel_kx (void *cls,
691 struct CadetConnection *cc; 1072 struct CadetConnection *cc;
692 1073
693 /* First, check if message belongs to a connection that ends here. */ 1074 /* First, check if message belongs to a connection that ends here. */
694 cc = GNUNET_CONTAINER_multishortmap_get (connections, 1075 cc = GCC_lookup (&msg->cid);
695 &msg->cid.connection_of_tunnel);
696 if (NULL != cc) 1076 if (NULL != cc)
697 { 1077 {
698 /* verify message came from the right direction */ 1078 /* verify message came from the right direction */
@@ -719,6 +1099,46 @@ handle_tunnel_kx (void *cls,
719 1099
720 1100
721/** 1101/**
1102 * Handle for #GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX_AUTH
1103 *
1104 * @param cls Closure (CadetPeer for neighbor that sent the message).
1105 * @param msg Message itself.
1106 */
1107static void
1108handle_tunnel_kx_auth (void *cls,
1109 const struct GNUNET_CADET_TunnelKeyExchangeAuthMessage *msg)
1110{
1111 struct CadetPeer *peer = cls;
1112 struct CadetConnection *cc;
1113
1114 /* First, check if message belongs to a connection that ends here. */
1115 cc = GCC_lookup (&msg->kx.cid);
1116 if (NULL != cc)
1117 {
1118 /* verify message came from the right direction */
1119 struct CadetPeerPath *path = GCC_get_path (cc);
1120
1121 if (peer !=
1122 GCPP_get_peer_at_offset (path,
1123 0))
1124 {
1125 /* received message from unexpected direction, ignore! */
1126 GNUNET_break_op (0);
1127 return;
1128 }
1129 GCC_handle_kx_auth (cc,
1130 msg);
1131 return;
1132 }
1133
1134 /* We're just an intermediary peer, route the message along its path */
1135 route_message (peer,
1136 &msg->kx.cid,
1137 &msg->kx.header);
1138}
1139
1140
1141/**
722 * Check if the encrypted message has the appropriate size. 1142 * Check if the encrypted message has the appropriate size.
723 * 1143 *
724 * @param cls Closure (unused). 1144 * @param cls Closure (unused).
@@ -748,8 +1168,7 @@ handle_tunnel_encrypted (void *cls,
748 struct CadetConnection *cc; 1168 struct CadetConnection *cc;
749 1169
750 /* First, check if message belongs to a connection that ends here. */ 1170 /* First, check if message belongs to a connection that ends here. */
751 cc = GNUNET_CONTAINER_multishortmap_get (connections, 1171 cc = GCC_lookup (&msg->cid);
752 &msg->cid.connection_of_tunnel);
753 if (NULL != cc) 1172 if (NULL != cc)
754 { 1173 {
755 /* verify message came from the right direction */ 1174 /* verify message came from the right direction */
@@ -876,6 +1295,10 @@ GCO_init (const struct GNUNET_CONFIGURATION_Handle *c)
876 GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX, 1295 GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX,
877 struct GNUNET_CADET_TunnelKeyExchangeMessage, 1296 struct GNUNET_CADET_TunnelKeyExchangeMessage,
878 NULL), 1297 NULL),
1298 GNUNET_MQ_hd_fixed_size (tunnel_kx_auth,
1299 GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX_AUTH,
1300 struct GNUNET_CADET_TunnelKeyExchangeAuthMessage,
1301 NULL),
879 GNUNET_MQ_hd_var_size (tunnel_encrypted, 1302 GNUNET_MQ_hd_var_size (tunnel_encrypted,
880 GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED, 1303 GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED,
881 struct GNUNET_CADET_TunnelEncryptedMessage, 1304 struct GNUNET_CADET_TunnelEncryptedMessage,
@@ -883,8 +1306,21 @@ GCO_init (const struct GNUNET_CONFIGURATION_Handle *c)
883 GNUNET_MQ_handler_end () 1306 GNUNET_MQ_handler_end ()
884 }; 1307 };
885 1308
1309 if (GNUNET_OK !=
1310 GNUNET_CONFIGURATION_get_value_number (c,
1311 "CADET",
1312 "MAX_ROUTES",
1313 &max_routes))
1314 max_routes = 5000;
1315 if (GNUNET_OK !=
1316 GNUNET_CONFIGURATION_get_value_number (c,
1317 "CADET",
1318 "MAX_MSGS_QUEUE",
1319 &max_buffers))
1320 max_buffers = 10000;
886 routes = GNUNET_CONTAINER_multishortmap_create (1024, 1321 routes = GNUNET_CONTAINER_multishortmap_create (1024,
887 GNUNET_NO); 1322 GNUNET_NO);
1323 route_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
888 core = GNUNET_CORE_connect (c, 1324 core = GNUNET_CORE_connect (c,
889 NULL, 1325 NULL,
890 &core_init_cb, 1326 &core_init_cb,
@@ -907,6 +1343,14 @@ GCO_shutdown ()
907 } 1343 }
908 GNUNET_assert (0 == GNUNET_CONTAINER_multishortmap_size (routes)); 1344 GNUNET_assert (0 == GNUNET_CONTAINER_multishortmap_size (routes));
909 GNUNET_CONTAINER_multishortmap_destroy (routes); 1345 GNUNET_CONTAINER_multishortmap_destroy (routes);
1346 routes = NULL;
1347 GNUNET_CONTAINER_heap_destroy (route_heap);
1348 route_heap = NULL;
1349 if (NULL != timeout_task)
1350 {
1351 GNUNET_SCHEDULER_cancel (timeout_task);
1352 timeout_task = NULL;
1353 }
910} 1354}
911 1355
912/* end of gnunet-cadet-service_core.c */ 1356/* end of gnunet-cadet-service_core.c */
diff --git a/src/cadet/gnunet-service-cadet-new_core.h b/src/cadet/gnunet-service-cadet_core.h
index 65b0a6ba5..65b0a6ba5 100644
--- a/src/cadet/gnunet-service-cadet-new_core.h
+++ b/src/cadet/gnunet-service-cadet_core.h
diff --git a/src/cadet/gnunet-service-cadet_dht.c b/src/cadet/gnunet-service-cadet_dht.c
index 22673b167..f00c0caf3 100644
--- a/src/cadet/gnunet-service-cadet_dht.c
+++ b/src/cadet/gnunet-service-cadet_dht.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2013 GNUnet e.V. 3 Copyright (C) 2013, 2017 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -17,25 +17,41 @@
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA. 18 Boston, MA 02110-1301, USA.
19*/ 19*/
20 20/**
21 * @file cadet/gnunet-service-cadet_dht.c
22 * @brief Information we track per peer.
23 * @author Bartlomiej Polot
24 * @author Christian Grothoff
25 */
21 26
22#include "platform.h" 27#include "platform.h"
23#include "gnunet_util_lib.h" 28#include "gnunet_util_lib.h"
24
25#include "gnunet_dht_service.h" 29#include "gnunet_dht_service.h"
26#include "gnunet_statistics_service.h" 30#include "gnunet_statistics_service.h"
27 31#include "gnunet-service-cadet.h"
28#include "cadet_path.h"
29#include "gnunet-service-cadet_dht.h" 32#include "gnunet-service-cadet_dht.h"
30#include "gnunet-service-cadet_peer.h"
31#include "gnunet-service-cadet_hello.h" 33#include "gnunet-service-cadet_hello.h"
34#include "gnunet-service-cadet_peer.h"
35#include "gnunet-service-cadet_paths.h"
32 36
33#define LOG(level, ...) GNUNET_log_from (level,"cadet-dht",__VA_ARGS__) 37/**
38 * How long do we wait before first announcing our presence to the DHT.
39 * Used to wait for our HELLO to be available. Note that we also get
40 * notifications when our HELLO is ready, so this is just the maximum
41 * we wait for the first notification.
42 */
43#define STARTUP_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 500)
34 44
45/**
46 * How long do we wait after we get an updated HELLO before publishing?
47 * Allows for the HELLO to be updated again quickly, for example in
48 * case multiple addresses changed and we got a partial update.
49 */
50#define CHANGE_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 100)
51
52
53#define LOG(level, ...) GNUNET_log_from (level,"cadet-dht",__VA_ARGS__)
35 54
36/******************************************************************************/
37/******************************** STRUCTS **********************************/
38/******************************************************************************/
39 55
40/** 56/**
41 * Handle for DHT searches. 57 * Handle for DHT searches.
@@ -47,42 +63,9 @@ struct GCD_search_handle
47 */ 63 */
48 struct GNUNET_DHT_GetHandle *dhtget; 64 struct GNUNET_DHT_GetHandle *dhtget;
49 65
50 /**
51 * Provided callback to call when a path is found.
52 */
53 GCD_search_callback callback;
54
55 /**
56 * Provided closure.
57 */
58 void *cls;
59
60 /**
61 * Peer ID searched for
62 */
63 GNUNET_PEER_Id peer_id;
64}; 66};
65 67
66 68
67/******************************************************************************/
68/******************************* GLOBALS ***********************************/
69/******************************************************************************/
70
71/**
72 * Global handle to the statistics service.
73 */
74extern struct GNUNET_STATISTICS_Handle *stats;
75
76/**
77 * Own ID (short value).
78 */
79extern GNUNET_PEER_Id myid;
80
81/**
82 * Own ID (full value).
83 */
84extern struct GNUNET_PeerIdentity my_full_id;
85
86/** 69/**
87 * Handle to use DHT. 70 * Handle to use DHT.
88 */ 71 */
@@ -94,69 +77,20 @@ static struct GNUNET_DHT_Handle *dht_handle;
94static struct GNUNET_TIME_Relative id_announce_time; 77static struct GNUNET_TIME_Relative id_announce_time;
95 78
96/** 79/**
97 * DHT replication level, see DHT API: GNUNET_DHT_get_start, GNUNET_DHT_put. 80 * DHT replication level, see DHT API: #GNUNET_DHT_get_start(), #GNUNET_DHT_put().
98 */ 81 */
99static unsigned long long dht_replication_level; 82static unsigned long long dht_replication_level;
100 83
101/** 84/**
102 * Task to periodically announce itself in the network. 85 * Task to periodically announce itself in the network.
103 */ 86 */
104static struct GNUNET_SCHEDULER_Task * announce_id_task; 87static struct GNUNET_SCHEDULER_Task *announce_id_task;
105 88
106/** 89/**
107 * Delay for the next ID announce. 90 * Delay for the next ID announce.
108 */ 91 */
109static struct GNUNET_TIME_Relative announce_delay; 92static struct GNUNET_TIME_Relative announce_delay;
110 93
111/**
112 * GET requests to stop on shutdown.
113 */
114static struct GNUNET_CONTAINER_MultiHashMap32 *get_requests;
115
116/******************************************************************************/
117/******************************** STATIC ***********************************/
118/******************************************************************************/
119
120
121/**
122 * Build a PeerPath from the paths returned from the DHT, reversing the paths
123 * to obtain a local peer -> destination path and interning the peer ids.
124 *
125 * @return Newly allocated and created path
126 *
127 * FIXME refactor and use build_path_from_peer_ids
128 */
129static struct CadetPeerPath *
130path_build_from_dht (const struct GNUNET_PeerIdentity *get_path,
131 unsigned int get_path_length,
132 const struct GNUNET_PeerIdentity *put_path,
133 unsigned int put_path_length)
134{
135 size_t size = get_path_length + put_path_length + 1;
136 struct GNUNET_PeerIdentity peers[size];
137 const struct GNUNET_PeerIdentity *peer;
138 struct CadetPeerPath *p;
139 unsigned int own_pos;
140 int i;
141
142 peers[0] = my_full_id;
143 LOG (GNUNET_ERROR_TYPE_DEBUG, " GET has %d hops.\n", get_path_length);
144 for (i = 0 ; i < get_path_length; i++)
145 {
146 peer = &get_path[get_path_length - i - 1];
147 LOG (GNUNET_ERROR_TYPE_DEBUG, " From GET: %s\n", GNUNET_i2s (peer));
148 peers[i + 1] = *peer;
149 }
150 for (i = 0 ; i < put_path_length; i++)
151 {
152 peer = &put_path[put_path_length - i - 1];
153 LOG (GNUNET_ERROR_TYPE_DEBUG, " From PUT: %s\n", GNUNET_i2s (peer));
154 peers[i + get_path_length + 1] = *peer;
155 }
156 p = path_build_from_peer_ids (peers, size, myid, &own_pos);
157 return p;
158}
159
160 94
161/** 95/**
162 * Function to process paths received for a new peer addition. The recorded 96 * Function to process paths received for a new peer addition. The recorded
@@ -176,42 +110,34 @@ path_build_from_dht (const struct GNUNET_PeerIdentity *get_path,
176 */ 110 */
177static void 111static void
178dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp, 112dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp,
179 const struct GNUNET_HashCode * key, 113 const struct GNUNET_HashCode *key,
180 const struct GNUNET_PeerIdentity *get_path, 114 const struct GNUNET_PeerIdentity *get_path,
181 unsigned int get_path_length, 115 unsigned int get_path_length,
182 const struct GNUNET_PeerIdentity *put_path, 116 const struct GNUNET_PeerIdentity *put_path,
183 unsigned int put_path_length, enum GNUNET_BLOCK_Type type, 117 unsigned int put_path_length,
184 size_t size, const void *data) 118 enum GNUNET_BLOCK_Type type,
119 size_t size,
120 const void *data)
185{ 121{
186 struct GCD_search_handle *h = cls; 122 const struct GNUNET_HELLO_Message *hello = data;
187 struct GNUNET_HELLO_Message *hello;
188 struct CadetPeerPath *p;
189 struct CadetPeer *peer; 123 struct CadetPeer *peer;
190 char *s;
191 124
192 p = path_build_from_dht (get_path, get_path_length, 125 GCPP_try_path_from_dht (get_path,
193 put_path, put_path_length); 126 get_path_length,
194 if (NULL == p) 127 put_path,
128 put_path_length);
129 if ( (size >= sizeof (struct GNUNET_HELLO_Message)) &&
130 (ntohs (hello->header.size) == size) &&
131 (size == GNUNET_HELLO_size (hello)) )
195 { 132 {
196 GNUNET_break_op (0); 133 peer = GCP_get (&put_path[0],
197 return; 134 GNUNET_YES);
135 LOG (GNUNET_ERROR_TYPE_DEBUG,
136 "Got HELLO for %s\n",
137 GCP_2s (peer));
138 GCP_set_hello (peer,
139 hello);
198 } 140 }
199
200 s = path_2s (p);
201 LOG (GNUNET_ERROR_TYPE_INFO,
202 "Got path from DHT: %s\n",
203 s);
204 GNUNET_free_non_null (s);
205
206 peer = GCP_get_short (p->peers[p->length - 1], GNUNET_YES);
207 LOG (GNUNET_ERROR_TYPE_DEBUG,
208 "Got HELLO for %s\n",
209 GCP_2s (peer));
210 h->callback (h->cls, p);
211 path_destroy (p);
212 hello = (struct GNUNET_HELLO_Message *) data;
213 GCP_set_hello (peer, hello);
214 GCP_try_connect (peer);
215} 141}
216 142
217 143
@@ -229,19 +155,10 @@ announce_id (void *cls)
229 struct GNUNET_TIME_Absolute expiration; 155 struct GNUNET_TIME_Absolute expiration;
230 struct GNUNET_TIME_Relative next_put; 156 struct GNUNET_TIME_Relative next_put;
231 157
232 announce_id_task = NULL;
233 LOG (GNUNET_ERROR_TYPE_DEBUG, "Announce ID\n");
234 hello = GCH_get_mine (); 158 hello = GCH_get_mine ();
235 size = (NULL != hello) ? GNUNET_HELLO_size (hello) : 0; 159 size = (NULL != hello) ? GNUNET_HELLO_size (hello) : 0;
236 if ( (NULL == hello) || (0 == size) ) 160 if (0 == size)
237 { 161 {
238 /* Peerinfo gave us no hello yet, try again soon. */
239 LOG (GNUNET_ERROR_TYPE_INFO,
240 " no hello, waiting!\n");
241 GNUNET_STATISTICS_update (stats,
242 "# DHT announce skipped (no hello)",
243 1,
244 GNUNET_NO);
245 expiration = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), 162 expiration = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
246 announce_delay); 163 announce_delay);
247 announce_delay = GNUNET_TIME_STD_BACKOFF (announce_delay); 164 announce_delay = GNUNET_TIME_STD_BACKOFF (announce_delay);
@@ -252,71 +169,64 @@ announce_id (void *cls)
252 announce_delay = GNUNET_TIME_UNIT_SECONDS; 169 announce_delay = GNUNET_TIME_UNIT_SECONDS;
253 } 170 }
254 171
255 LOG (GNUNET_ERROR_TYPE_DEBUG,
256 "Hello %p size: %u\n",
257 hello,
258 size);
259 if (NULL != hello)
260 {
261 GNUNET_STATISTICS_update (stats,
262 "# DHT announce",
263 1, GNUNET_NO);
264 memset (&phash,
265 0,
266 sizeof (phash));
267 GNUNET_memcpy (&phash,
268 &my_full_id,
269 sizeof (my_full_id));
270 GNUNET_DHT_put (dht_handle, /* DHT handle */
271 &phash, /* Key to use */
272 dht_replication_level, /* Replication level */
273 GNUNET_DHT_RO_RECORD_ROUTE
274 | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, /* DHT options */
275 GNUNET_BLOCK_TYPE_DHT_HELLO, /* Block type */
276 size, /* Size of the data */
277 (const char *) hello, /* Data itself */
278 expiration, /* Data expiration */
279 NULL, /* Continuation */
280 NULL); /* Continuation closure */
281 }
282 /* Call again in id_announce_time, unless HELLO expires first, 172 /* Call again in id_announce_time, unless HELLO expires first,
283 * but wait at least 1s. */ 173 * but wait at least 1s. */
284 next_put = GNUNET_TIME_absolute_get_remaining (expiration); 174 next_put
285 next_put = GNUNET_TIME_relative_min (next_put, 175 = GNUNET_TIME_absolute_get_remaining (expiration);
286 id_announce_time); 176 next_put
287 next_put = GNUNET_TIME_relative_max (next_put, 177 = GNUNET_TIME_relative_min (next_put,
288 GNUNET_TIME_UNIT_SECONDS); 178 id_announce_time);
289 announce_id_task = GNUNET_SCHEDULER_add_delayed (next_put, 179 next_put
290 &announce_id, 180 = GNUNET_TIME_relative_max (next_put,
291 cls); 181 GNUNET_TIME_UNIT_SECONDS);
182 announce_id_task
183 = GNUNET_SCHEDULER_add_delayed (next_put,
184 &announce_id,
185 cls);
186 GNUNET_STATISTICS_update (stats,
187 "# DHT announce",
188 1,
189 GNUNET_NO);
190 memset (&phash,
191 0,
192 sizeof (phash));
193 GNUNET_memcpy (&phash,
194 &my_full_id,
195 sizeof (my_full_id));
196 LOG (GNUNET_ERROR_TYPE_DEBUG,
197 "Announcing my HELLO (%u bytes) in the DHT\n",
198 size);
199 GNUNET_DHT_put (dht_handle, /* DHT handle */
200 &phash, /* Key to use */
201 dht_replication_level, /* Replication level */
202 GNUNET_DHT_RO_RECORD_ROUTE
203 | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, /* DHT options */
204 GNUNET_BLOCK_TYPE_DHT_HELLO, /* Block type */
205 size, /* Size of the data */
206 (const char *) hello, /* Data itself */
207 expiration, /* Data expiration */
208 NULL, /* Continuation */
209 NULL); /* Continuation closure */
292} 210}
293 211
212
294/** 213/**
295 * Iterator over hash map entries and stop GET requests before disconnecting 214 * Function called by the HELLO subsystem whenever OUR hello
296 * from the DHT. 215 * changes. Re-triggers the DHT PUT immediately.
297 *
298 * @param cls Closure (unused)
299 * @param key Current peer ID.
300 * @param value Value in the hash map (GCD_search_handle).
301 *
302 * @return #GNUNET_YES, we should continue to iterate,
303 */ 216 */
304int 217void
305stop_get (void *cls, 218GCD_hello_update ()
306 uint32_t key,
307 void *value)
308{ 219{
309 struct GCD_search_handle *h = value; 220 if (NULL == announce_id_task)
310 221 return; /* too early */
311 GCD_search_stop (h); 222 GNUNET_SCHEDULER_cancel (announce_id_task);
312 return GNUNET_YES; 223 announce_id_task
224 = GNUNET_SCHEDULER_add_delayed (CHANGE_DELAY,
225 &announce_id,
226 NULL);
313} 227}
314 228
315 229
316/******************************************************************************/
317/******************************** API ***********************************/
318/******************************************************************************/
319
320/** 230/**
321 * Initialize the DHT subsystem. 231 * Initialize the DHT subsystem.
322 * 232 *
@@ -325,36 +235,40 @@ stop_get (void *cls,
325void 235void
326GCD_init (const struct GNUNET_CONFIGURATION_Handle *c) 236GCD_init (const struct GNUNET_CONFIGURATION_Handle *c)
327{ 237{
328 LOG (GNUNET_ERROR_TYPE_DEBUG, "init\n");
329 if (GNUNET_OK != 238 if (GNUNET_OK !=
330 GNUNET_CONFIGURATION_get_value_number (c, "CADET", 239 GNUNET_CONFIGURATION_get_value_number (c,
240 "CADET",
331 "DHT_REPLICATION_LEVEL", 241 "DHT_REPLICATION_LEVEL",
332 &dht_replication_level)) 242 &dht_replication_level))
333 { 243 {
334 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING, "CADET", 244 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
335 "DHT_REPLICATION_LEVEL", "USING DEFAULT"); 245 "CADET",
246 "DHT_REPLICATION_LEVEL",
247 "USING DEFAULT");
336 dht_replication_level = 3; 248 dht_replication_level = 3;
337 } 249 }
338 250
339 if (GNUNET_OK != 251 if (GNUNET_OK !=
340 GNUNET_CONFIGURATION_get_value_time (c, "CADET", "ID_ANNOUNCE_TIME", 252 GNUNET_CONFIGURATION_get_value_time (c,
253 "CADET",
254 "ID_ANNOUNCE_TIME",
341 &id_announce_time)) 255 &id_announce_time))
342 { 256 {
343 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, "CADET", 257 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
344 "ID_ANNOUNCE_TIME", "MISSING"); 258 "CADET",
259 "ID_ANNOUNCE_TIME",
260 "MISSING");
345 GNUNET_SCHEDULER_shutdown (); 261 GNUNET_SCHEDULER_shutdown ();
346 return; 262 return;
347 } 263 }
348 264
349 dht_handle = GNUNET_DHT_connect (c, 64); 265 dht_handle = GNUNET_DHT_connect (c,
350 if (NULL == dht_handle) 266 64);
351 { 267 GNUNET_break (NULL != dht_handle);
352 GNUNET_break (0);
353 }
354
355 announce_delay = GNUNET_TIME_UNIT_SECONDS; 268 announce_delay = GNUNET_TIME_UNIT_SECONDS;
356 announce_id_task = GNUNET_SCHEDULER_add_now (&announce_id, NULL); 269 announce_id_task = GNUNET_SCHEDULER_add_delayed (STARTUP_DELAY,
357 get_requests = GNUNET_CONTAINER_multihashmap32_create (32); 270 &announce_id,
271 NULL);
358} 272}
359 273
360 274
@@ -364,10 +278,7 @@ GCD_init (const struct GNUNET_CONFIGURATION_Handle *c)
364void 278void
365GCD_shutdown (void) 279GCD_shutdown (void)
366{ 280{
367 LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down DHT\n"); 281 if (NULL != dht_handle)
368 GNUNET_CONTAINER_multihashmap32_iterate (get_requests, &stop_get, NULL);
369 GNUNET_CONTAINER_multihashmap32_destroy (get_requests);
370 if (dht_handle != NULL)
371 { 282 {
372 GNUNET_DHT_disconnect (dht_handle); 283 GNUNET_DHT_disconnect (dht_handle);
373 dht_handle = NULL; 284 dht_handle = NULL;
@@ -379,22 +290,31 @@ GCD_shutdown (void)
379 } 290 }
380} 291}
381 292
293
294/**
295 * Search DHT for paths to @a peeR_id
296 *
297 * @param peer_id peer to search for
298 * @return handle to abort search
299 */
382struct GCD_search_handle * 300struct GCD_search_handle *
383GCD_search (const struct GNUNET_PeerIdentity *peer_id, 301GCD_search (const struct GNUNET_PeerIdentity *peer_id)
384 GCD_search_callback callback, void *cls)
385{ 302{
386 struct GNUNET_HashCode phash; 303 struct GNUNET_HashCode phash;
387 struct GCD_search_handle *h; 304 struct GCD_search_handle *h;
388 305
389 LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting DHT GET for peer %s\n", 306 GNUNET_STATISTICS_update (stats,
390 GNUNET_i2s (peer_id)); 307 "# DHT search",
391 GNUNET_STATISTICS_update (stats, "# DHT search", 1, GNUNET_NO); 308 1,
392 memset (&phash, 0, sizeof (phash)); 309 GNUNET_NO);
393 GNUNET_memcpy (&phash, peer_id, sizeof (*peer_id)); 310 memset (&phash,
311 0,
312 sizeof (phash));
313 GNUNET_memcpy (&phash,
314 peer_id,
315 sizeof (*peer_id));
316
394 h = GNUNET_new (struct GCD_search_handle); 317 h = GNUNET_new (struct GCD_search_handle);
395 h->peer_id = GNUNET_PEER_intern (peer_id);
396 h->callback = callback;
397 h->cls = cls;
398 h->dhtget = GNUNET_DHT_get_start (dht_handle, /* handle */ 318 h->dhtget = GNUNET_DHT_get_start (dht_handle, /* handle */
399 GNUNET_BLOCK_TYPE_DHT_HELLO, /* type */ 319 GNUNET_BLOCK_TYPE_DHT_HELLO, /* type */
400 &phash, /* key to search */ 320 &phash, /* key to search */
@@ -405,20 +325,27 @@ GCD_search (const struct GNUNET_PeerIdentity *peer_id,
405 0, /* xquery bits */ 325 0, /* xquery bits */
406 &dht_get_id_handler, 326 &dht_get_id_handler,
407 h); 327 h);
408 GNUNET_CONTAINER_multihashmap32_put (get_requests, 328 LOG (GNUNET_ERROR_TYPE_DEBUG,
409 h->peer_id, 329 "Starting DHT GET for peer %s (%p)\n",
410 h, 330 GNUNET_i2s (peer_id),
411 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); 331 h);
412 return h; 332 return h;
413} 333}
414 334
415 335
336/**
337 * Stop DHT search started with #GCD_search().
338 *
339 * @param h handle to search to stop
340 */
416void 341void
417GCD_search_stop (struct GCD_search_handle *h) 342GCD_search_stop (struct GCD_search_handle *h)
418{ 343{
419 GNUNET_break (GNUNET_OK == 344 LOG (GNUNET_ERROR_TYPE_DEBUG,
420 GNUNET_CONTAINER_multihashmap32_remove (get_requests, 345 "Stopping DHT GET %p\n",
421 h->peer_id, h)); 346 h);
422 GNUNET_DHT_get_stop (h->dhtget); 347 GNUNET_DHT_get_stop (h->dhtget);
423 GNUNET_free (h); 348 GNUNET_free (h);
424} 349}
350
351/* end of gnunet-service-cadet_dht.c */
diff --git a/src/cadet/gnunet-service-cadet_dht.h b/src/cadet/gnunet-service-cadet_dht.h
index b70dfe975..5d7ab29a0 100644
--- a/src/cadet/gnunet-service-cadet_dht.h
+++ b/src/cadet/gnunet-service-cadet_dht.h
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2013 GNUnet e.V. 3 Copyright (C) 2013, 2017 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -22,10 +22,10 @@
22 * @file cadet/gnunet-service-cadet_dht.h 22 * @file cadet/gnunet-service-cadet_dht.h
23 * @brief cadet service; dealing with DHT requests and results 23 * @brief cadet service; dealing with DHT requests and results
24 * @author Bartlomiej Polot 24 * @author Bartlomiej Polot
25 * @author Christian Grothoff
25 * 26 *
26 * All functions in this file should use the prefix GMD (Gnunet Cadet Dht) 27 * All functions in this file should use the prefix GCD (Gnunet Cadet Dht)
27 */ 28 */
28
29#ifndef GNUNET_SERVICE_CADET_DHT_H 29#ifndef GNUNET_SERVICE_CADET_DHT_H
30#define GNUNET_SERVICE_CADET_DHT_H 30#define GNUNET_SERVICE_CADET_DHT_H
31 31
@@ -40,23 +40,11 @@ extern "C"
40#include "platform.h" 40#include "platform.h"
41#include "gnunet_util_lib.h" 41#include "gnunet_util_lib.h"
42 42
43struct GCD_search_handle;
44
45
46/** 43/**
47 * Callback called on each path found over the DHT. 44 * Handle for DHT search operation.
48 *
49 * @param cls Closure.
50 * @param path An unchecked, unoptimized path to the target node.
51 * After callback will no longer be valid!
52 */ 45 */
53typedef void 46struct GCD_search_handle;
54(*GCD_search_callback) (void *cls,
55 const struct CadetPeerPath *path);
56 47
57/******************************************************************************/
58/******************************** API ***********************************/
59/******************************************************************************/
60 48
61/** 49/**
62 * Initialize the DHT subsystem. 50 * Initialize the DHT subsystem.
@@ -66,6 +54,7 @@ typedef void
66void 54void
67GCD_init (const struct GNUNET_CONFIGURATION_Handle *c); 55GCD_init (const struct GNUNET_CONFIGURATION_Handle *c);
68 56
57
69/** 58/**
70 * Shut down the DHT subsystem. 59 * Shut down the DHT subsystem.
71 */ 60 */
@@ -73,14 +62,32 @@ void
73GCD_shutdown (void); 62GCD_shutdown (void);
74 63
75 64
65/**
66 * Function called by the HELLO subsystem whenever OUR hello
67 * changes. Re-triggers the DHT PUT immediately.
68 */
69void
70GCD_hello_update (void);
71
72/**
73 * Search DHT for paths to @a peeR_id
74 *
75 * @param peer_id peer to search for
76 * @return handle to abort search
77 */
76struct GCD_search_handle * 78struct GCD_search_handle *
77GCD_search (const struct GNUNET_PeerIdentity *peer_id, 79GCD_search (const struct GNUNET_PeerIdentity *peer_id);
78 GCD_search_callback callback, void *cls);
79 80
80 81
82/**
83 * Stop DHT search started with #GCD_search().
84 *
85 * @param h handle to search to stop
86 */
81void 87void
82GCD_search_stop (struct GCD_search_handle *h); 88GCD_search_stop (struct GCD_search_handle *h);
83 89
90
84#if 0 /* keep Emacsens' auto-indent happy */ 91#if 0 /* keep Emacsens' auto-indent happy */
85{ 92{
86#endif 93#endif
@@ -88,6 +95,6 @@ GCD_search_stop (struct GCD_search_handle *h);
88} 95}
89#endif 96#endif
90 97
91/* ifndef GNUNET_CADET_SERVICE_LOCAL_H */ 98/* ifndef GNUNET_CADET_SERVICE_DHT_H */
92#endif 99#endif
93/* end of gnunet-cadet-service_LOCAL.h */ 100/* end of gnunet-service-cadet_dht.h */
diff --git a/src/cadet/gnunet-service-cadet_hello.c b/src/cadet/gnunet-service-cadet_hello.c
index 3c63f3551..6d85de39f 100644
--- a/src/cadet/gnunet-service-cadet_hello.c
+++ b/src/cadet/gnunet-service-cadet_hello.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2014 GNUnet e.V. 3 Copyright (C) 2014, 2017 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -17,58 +17,33 @@
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA. 18 Boston, MA 02110-1301, USA.
19*/ 19*/
20 20/**
21 * @file cadet/gnunet-service-cadet_hello.c
22 * @brief spread knowledge about how to contact other peers from PEERINFO
23 * @author Bartlomiej Polot
24 * @author Christian Grothoff
25 *
26 * TODO:
27 * - is most of this necessary/helpful?
28 * - should we not simply restrict this to OUR hello?
29 */
21#include "platform.h" 30#include "platform.h"
22#include "gnunet_util_lib.h" 31#include "gnunet_util_lib.h"
23 32
24#include "gnunet_statistics_service.h" 33#include "gnunet_statistics_service.h"
25#include "gnunet_peerinfo_service.h" 34#include "gnunet_peerinfo_service.h"
26
27#include "cadet_protocol.h" 35#include "cadet_protocol.h"
28#include "cadet_path.h" 36#include "gnunet-service-cadet.h"
29 37#include "gnunet-service-cadet_dht.h"
30#include "gnunet-service-cadet_hello.h" 38#include "gnunet-service-cadet_hello.h"
31#include "gnunet-service-cadet_peer.h" 39#include "gnunet-service-cadet_peer.h"
32 40
33#define LOG(level, ...) GNUNET_log_from(level,"cadet-hll",__VA_ARGS__) 41#define LOG(level, ...) GNUNET_log_from(level,"cadet-hll",__VA_ARGS__)
34 42
35
36/******************************************************************************/
37/******************************** STRUCTS **********************************/
38/******************************************************************************/
39
40
41
42/******************************************************************************/
43/******************************* GLOBALS ***********************************/
44/******************************************************************************/
45
46/**
47 * Global handle to the statistics service.
48 */
49extern struct GNUNET_STATISTICS_Handle *stats;
50
51/**
52 * Local peer own ID (memory efficient handle).
53 */
54extern GNUNET_PEER_Id myid;
55
56/**
57 * Local peer own ID (full value).
58 */
59extern struct GNUNET_PeerIdentity my_full_id;
60
61
62/**
63 * Don't try to recover tunnels if shutting down.
64 */
65extern int shutting_down;
66
67
68/** 43/**
69 * Hello message of local peer. 44 * Hello message of local peer.
70 */ 45 */
71const struct GNUNET_HELLO_Message *mine; 46static struct GNUNET_HELLO_Message *mine;
72 47
73/** 48/**
74 * Handle to peerinfo service. 49 * Handle to peerinfo service.
@@ -78,13 +53,9 @@ static struct GNUNET_PEERINFO_Handle *peerinfo;
78/** 53/**
79 * Iterator context. 54 * Iterator context.
80 */ 55 */
81struct GNUNET_PEERINFO_NotifyContext* nc; 56static struct GNUNET_PEERINFO_NotifyContext *nc;
82 57
83 58
84/******************************************************************************/
85/******************************** STATIC ***********************************/
86/******************************************************************************/
87
88/** 59/**
89 * Process each hello message received from peerinfo. 60 * Process each hello message received from peerinfo.
90 * 61 *
@@ -94,31 +65,37 @@ struct GNUNET_PEERINFO_NotifyContext* nc;
94 * @param err_msg Error message. 65 * @param err_msg Error message.
95 */ 66 */
96static void 67static void
97got_hello (void *cls, const struct GNUNET_PeerIdentity *id, 68got_hello (void *cls,
69 const struct GNUNET_PeerIdentity *id,
98 const struct GNUNET_HELLO_Message *hello, 70 const struct GNUNET_HELLO_Message *hello,
99 const char *err_msg) 71 const char *err_msg)
100{ 72{
101 struct CadetPeer *peer; 73 struct CadetPeer *peer;
102 74
103 if (NULL == id || NULL == hello) 75 if ( (NULL == id) ||
76 (NULL == hello) )
77 return;
78 if (0 == memcmp (id,
79 &my_full_id,
80 sizeof (struct GNUNET_PeerIdentity)))
104 { 81 {
105 LOG (GNUNET_ERROR_TYPE_DEBUG, " hello with id %p and msg %p\n", id, hello); 82 GNUNET_free_non_null (mine);
83 mine = (struct GNUNET_HELLO_Message *) GNUNET_copy_message (&hello->header);
84 GCD_hello_update ();
106 return; 85 return;
107 } 86 }
108 LOG (GNUNET_ERROR_TYPE_DEBUG, " hello for %s (%d bytes), expires on %s\n",
109 GNUNET_i2s (id), GNUNET_HELLO_size (hello),
110 GNUNET_STRINGS_absolute_time_to_string (GNUNET_HELLO_get_last_expiration(hello)));
111 peer = GCP_get (id, GNUNET_YES);
112 GCP_set_hello (peer, hello);
113
114 if (GCP_get_short_id (peer) == myid)
115 mine = GCP_get_hello (peer);
116}
117 87
88 LOG (GNUNET_ERROR_TYPE_DEBUG,
89 "Hello for %s (%d bytes), expires on %s\n",
90 GNUNET_i2s (id),
91 GNUNET_HELLO_size (hello),
92 GNUNET_STRINGS_absolute_time_to_string (GNUNET_HELLO_get_last_expiration (hello)));
93 peer = GCP_get (id,
94 GNUNET_YES);
95 GCP_set_hello (peer,
96 hello);
97}
118 98
119/******************************************************************************/
120/******************************** API ***********************************/
121/******************************************************************************/
122 99
123/** 100/**
124 * Initialize the hello subsystem. 101 * Initialize the hello subsystem.
@@ -128,10 +105,12 @@ got_hello (void *cls, const struct GNUNET_PeerIdentity *id,
128void 105void
129GCH_init (const struct GNUNET_CONFIGURATION_Handle *c) 106GCH_init (const struct GNUNET_CONFIGURATION_Handle *c)
130{ 107{
131 LOG (GNUNET_ERROR_TYPE_DEBUG, "init\n");
132 GNUNET_assert (NULL == nc); 108 GNUNET_assert (NULL == nc);
133 peerinfo = GNUNET_PEERINFO_connect (c); 109 peerinfo = GNUNET_PEERINFO_connect (c);
134 nc = GNUNET_PEERINFO_notify (c, GNUNET_NO, &got_hello, NULL); 110 nc = GNUNET_PEERINFO_notify (c,
111 GNUNET_NO,
112 &got_hello,
113 NULL);
135} 114}
136 115
137 116
@@ -141,7 +120,6 @@ GCH_init (const struct GNUNET_CONFIGURATION_Handle *c)
141void 120void
142GCH_shutdown () 121GCH_shutdown ()
143{ 122{
144 LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down channels\n");
145 if (NULL != nc) 123 if (NULL != nc)
146 { 124 {
147 GNUNET_PEERINFO_notify_cancel (nc); 125 GNUNET_PEERINFO_notify_cancel (nc);
@@ -152,6 +130,11 @@ GCH_shutdown ()
152 GNUNET_PEERINFO_disconnect (peerinfo); 130 GNUNET_PEERINFO_disconnect (peerinfo);
153 peerinfo = NULL; 131 peerinfo = NULL;
154 } 132 }
133 if (NULL != mine)
134 {
135 GNUNET_free (mine);
136 mine = NULL;
137 }
155} 138}
156 139
157 140
@@ -166,35 +149,4 @@ GCH_get_mine (void)
166 return mine; 149 return mine;
167} 150}
168 151
169 152/* end of gnunet-service-cadet-new_hello.c */
170/**
171 * Get another peer's hello message.
172 *
173 * @param id ID of the peer whose hello message is requested.
174 *
175 * @return Hello message, if any (NULL possible).
176 */
177const struct GNUNET_HELLO_Message *
178GCH_get (const struct GNUNET_PeerIdentity *id)
179{
180 struct CadetPeer *p;
181
182 p = GCP_get (id, GNUNET_NO);
183 if (NULL == p)
184 return NULL;
185 return GCP_get_hello (p);
186}
187
188
189/**
190 * Convert a hello message to a string.
191 *
192 * @param h Hello message.
193 */
194char *
195GCH_2s (const struct GNUNET_HELLO_Message *h)
196{
197 return "hello (TODO)";
198}
199
200
diff --git a/src/cadet/gnunet-service-cadet_hello.h b/src/cadet/gnunet-service-cadet_hello.h
index 34121e1e0..4291ae985 100644
--- a/src/cadet/gnunet-service-cadet_hello.h
+++ b/src/cadet/gnunet-service-cadet_hello.h
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2014 GNUnet e.V. 3 Copyright (C) 2014, 2017 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -22,8 +22,9 @@
22 * @file cadet/gnunet-service-cadet_hello.h 22 * @file cadet/gnunet-service-cadet_hello.h
23 * @brief cadet service; dealing with hello messages 23 * @brief cadet service; dealing with hello messages
24 * @author Bartlomiej Polot 24 * @author Bartlomiej Polot
25 * @author Christian Grothoff
25 * 26 *
26 * All functions in this file should use the prefix GMH (Gnunet Cadet Hello) 27 * All functions in this file should use the prefix GCH (Gnunet Cadet Hello)
27 */ 28 */
28 29
29#ifndef GNUNET_SERVICE_CADET_HELLO_H 30#ifndef GNUNET_SERVICE_CADET_HELLO_H
diff --git a/src/cadet/gnunet-service-cadet_local.c b/src/cadet/gnunet-service-cadet_local.c
deleted file mode 100644
index dea6681df..000000000
--- a/src/cadet/gnunet-service-cadet_local.c
+++ /dev/null
@@ -1,1553 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2013 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 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 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21
22#include "platform.h"
23#include "gnunet_util_lib.h"
24
25#include "gnunet_statistics_service.h"
26
27#include "cadet.h"
28#include "cadet_protocol.h" /* GNUNET_CADET_Data is shared */
29
30#include "gnunet-service-cadet_local.h"
31#include "gnunet-service-cadet_channel.h"
32
33/* INFO DEBUG */
34#include "gnunet-service-cadet_tunnel.h"
35#include "gnunet-service-cadet_peer.h"
36
37#define LOG(level, ...) GNUNET_log_from(level,"cadet-loc",__VA_ARGS__)
38
39/******************************************************************************/
40/******************************** STRUCTS **********************************/
41/******************************************************************************/
42
43/**
44 * Struct containing information about a client of the service
45 *
46 * TODO: add a list of 'waiting' ports
47 */
48struct CadetClient
49{
50 /**
51 * Linked list next
52 */
53 struct CadetClient *next;
54
55 /**
56 * Linked list prev
57 */
58 struct CadetClient *prev;
59
60 /**
61 * Tunnels that belong to this client, indexed by local id
62 */
63 struct GNUNET_CONTAINER_MultiHashMap32 *own_channels;
64
65 /**
66 * Tunnels this client has accepted, indexed by incoming local id
67 */
68 struct GNUNET_CONTAINER_MultiHashMap32 *incoming_channels;
69
70 /**
71 * Channel ID for the next incoming channel.
72 */
73 struct GNUNET_CADET_ClientChannelNumber next_ccn;
74
75 /**
76 * Handle to communicate with the client
77 */
78 struct GNUNET_SERVER_Client *handle;
79
80 /**
81 * Ports that this client has declared interest in.
82 * Indexed by port, contains *Client.
83 */
84 struct GNUNET_CONTAINER_MultiHashMap *ports;
85
86 /**
87 * Whether the client is active or shutting down (don't send confirmations
88 * to a client that is shutting down.
89 */
90 int shutting_down;
91
92 /**
93 * ID of the client, mainly for debug messages
94 */
95 unsigned int id;
96};
97
98/******************************************************************************/
99/******************************* GLOBALS ***********************************/
100/******************************************************************************/
101
102/**
103 * Global handle to the statistics service.
104 */
105extern struct GNUNET_STATISTICS_Handle *stats;
106
107/**
108 * Handle to server lib.
109 */
110static struct GNUNET_SERVER_Handle *server_handle;
111
112/**
113 * DLL with all the clients, head.
114 */
115static struct CadetClient *clients_head;
116
117/**
118 * DLL with all the clients, tail.
119 */
120static struct CadetClient *clients_tail;
121
122/**
123 * Next ID to assign to a client.
124 */
125unsigned int next_client_id;
126
127/**
128 * All ports clients of this peer have opened.
129 */
130static struct GNUNET_CONTAINER_MultiHashMap *ports;
131
132/**
133 * Notification context, to send messages to local clients.
134 */
135static struct GNUNET_SERVER_NotificationContext *nc;
136
137
138/******************************************************************************/
139/******************************** STATIC ***********************************/
140/******************************************************************************/
141
142/**
143 * Remove client's ports from the global hashmap on disconnect.
144 *
145 * @param cls Closure (unused).
146 * @param key Port.
147 * @param value Client structure.
148 *
149 * @return #GNUNET_OK, keep iterating.
150 */
151static int
152client_release_ports (void *cls,
153 const struct GNUNET_HashCode *key,
154 void *value)
155{
156 int res;
157
158 res = GNUNET_CONTAINER_multihashmap_remove (ports, key, value);
159 if (GNUNET_YES != res)
160 {
161 GNUNET_break (0);
162 LOG (GNUNET_ERROR_TYPE_WARNING,
163 "Port %s by client %p was not registered.\n",
164 GNUNET_h2s (key), value);
165 }
166 return GNUNET_OK;
167}
168
169
170/**
171 * Iterator for deleting each channel whose client endpoint disconnected.
172 *
173 * @param cls Closure (client that has disconnected).
174 * @param key The local channel id (used to access the hashmap).
175 * @param value The value stored at the key (channel to destroy).
176 *
177 * @return #GNUNET_OK, keep iterating.
178 */
179static int
180channel_destroy_iterator (void *cls,
181 uint32_t key,
182 void *value)
183{
184 struct CadetChannel *ch = value;
185 struct CadetClient *c = cls;
186
187 LOG (GNUNET_ERROR_TYPE_DEBUG,
188 " Channel %s destroy, due to client %s shutdown.\n",
189 GCCH_2s (ch), GML_2s (c));
190
191 GCCH_handle_local_destroy (ch,
192 c,
193 key < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI);
194 return GNUNET_OK;
195}
196
197
198/**
199 * Unregister data and free memory for a client.
200 *
201 * @param c Client to destroy. No longer valid after call.
202 */
203static void
204client_destroy (struct CadetClient *c)
205{
206 LOG (GNUNET_ERROR_TYPE_DEBUG, " client destroy: %p/%u\n", c, c->id);
207 GNUNET_SERVER_client_drop (c->handle);
208 c->shutting_down = GNUNET_YES;
209
210 if (NULL != c->own_channels)
211 {
212 GNUNET_CONTAINER_multihashmap32_iterate (c->own_channels,
213 &channel_destroy_iterator, c);
214 GNUNET_CONTAINER_multihashmap32_destroy (c->own_channels);
215 }
216 if (NULL != c->incoming_channels)
217 {
218 GNUNET_CONTAINER_multihashmap32_iterate (c->incoming_channels,
219 &channel_destroy_iterator, c);
220 GNUNET_CONTAINER_multihashmap32_destroy (c->incoming_channels);
221 }
222 if (NULL != c->ports)
223 {
224 GNUNET_CONTAINER_multihashmap_iterate (c->ports,
225 &client_release_ports, c);
226 GNUNET_CONTAINER_multihashmap_destroy (c->ports);
227 }
228
229 GNUNET_CONTAINER_DLL_remove (clients_head, clients_tail, c);
230 GNUNET_STATISTICS_update (stats, "# clients", -1, GNUNET_NO);
231 GNUNET_SERVER_client_set_user_context (c->handle, NULL);
232 GNUNET_free (c);
233}
234
235
236/**
237 * Create a client record, register data and initialize memory.
238 *
239 * @param client Client's handle.
240 */
241static struct CadetClient *
242client_new (struct GNUNET_SERVER_Client *client)
243{
244 struct CadetClient *c;
245
246 GNUNET_SERVER_client_keep (client);
247 GNUNET_SERVER_notification_context_add (nc, client);
248
249 c = GNUNET_new (struct CadetClient);
250 c->handle = client;
251 c->id = next_client_id++; /* overflow not important: just for debug */
252
253 c->own_channels = GNUNET_CONTAINER_multihashmap32_create (32);
254 c->incoming_channels = GNUNET_CONTAINER_multihashmap32_create (32);
255
256 GNUNET_SERVER_client_set_user_context (client, c);
257 GNUNET_CONTAINER_DLL_insert (clients_head, clients_tail, c);
258 GNUNET_STATISTICS_update (stats, "# clients", +1, GNUNET_NO);
259
260 LOG (GNUNET_ERROR_TYPE_DEBUG, " client created: %p/%u\n", c, c->id);
261
262 return c;
263}
264
265
266/******************************************************************************/
267/******************************** HANDLES ***********************************/
268/******************************************************************************/
269
270/**
271 * Handler for client connection.
272 *
273 * @param cls Closure (unused).
274 * @param client Client handler.
275 */
276static void
277handle_client_connect (void *cls, struct GNUNET_SERVER_Client *client)
278{
279 LOG (GNUNET_ERROR_TYPE_DEBUG, "Client connected: %p\n", client);
280 if (NULL == client)
281 return;
282
283 (void) client_new (client);
284}
285
286
287/**
288 * Handler for client disconnection
289 *
290 * @param cls closure
291 * @param client identification of the client; NULL
292 * for the last call when the server is destroyed
293 */
294static void
295handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
296{
297 struct CadetClient *c;
298
299 LOG (GNUNET_ERROR_TYPE_DEBUG, "Client disconnected: %p\n", client);
300
301 c = GML_client_get (client);
302 if (NULL != c)
303 {
304 LOG (GNUNET_ERROR_TYPE_DEBUG, "matching client found (%u, %p)\n",
305 c->id, c);
306 client_destroy (c);
307 }
308 else
309 {
310 LOG (GNUNET_ERROR_TYPE_DEBUG, " disconnecting client's context NULL\n");
311 }
312 return;
313}
314
315
316/**
317 * Handler for port open requests.
318 *
319 * @param cls Closure.
320 * @param client Identification of the client.
321 * @param message The actual message.
322 */
323static void
324handle_port_open (void *cls, struct GNUNET_SERVER_Client *client,
325 const struct GNUNET_MessageHeader *message)
326{
327 struct CadetClient *c;
328 struct GNUNET_CADET_PortMessage *pmsg;
329
330 LOG (GNUNET_ERROR_TYPE_DEBUG, "open port requested\n");
331
332 /* Sanity check for client registration */
333 if (NULL == (c = GML_client_get (client)))
334 {
335 GNUNET_break (0);
336 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
337 return;
338 }
339 LOG (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
340
341 /* Message size sanity check */
342 if (sizeof (struct GNUNET_CADET_PortMessage) != ntohs (message->size))
343 {
344 GNUNET_break (0);
345 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
346 return;
347 }
348
349 pmsg = (struct GNUNET_CADET_PortMessage *) message;
350 if (NULL == c->ports)
351 {
352 c->ports = GNUNET_CONTAINER_multihashmap_create (4, GNUNET_NO);
353 }
354 /* store in client's hashmap */
355 if (GNUNET_OK !=
356 GNUNET_CONTAINER_multihashmap_put (c->ports, &pmsg->port, c,
357 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
358 {
359 GNUNET_break (0);
360 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
361 return;
362 }
363 /* store in global hashmap */
364 /* FIXME only allow one client to have the port open,
365 * have a backup hashmap with waiting clients */
366 GNUNET_CONTAINER_multihashmap_put (ports, &pmsg->port, c,
367 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
368
369 GNUNET_SERVER_receive_done (client, GNUNET_OK);
370}
371
372
373/**
374 * Handler for port close requests.
375 *
376 * @param cls Closure.
377 * @param client Identification of the client.
378 * @param message The actual message.
379 */
380static void
381handle_port_close (void *cls, struct GNUNET_SERVER_Client *client,
382 const struct GNUNET_MessageHeader *message)
383{
384 struct CadetClient *c;
385 struct GNUNET_CADET_PortMessage *pmsg;
386 int removed;
387
388 LOG (GNUNET_ERROR_TYPE_DEBUG, "close port requested\n");
389
390 /* Sanity check for client registration */
391 if (NULL == (c = GML_client_get (client)))
392 {
393 GNUNET_break (0);
394 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
395 return;
396 }
397 LOG (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
398
399 /* Message size sanity check */
400 if (sizeof (struct GNUNET_CADET_PortMessage) != ntohs (message->size))
401 {
402 GNUNET_break (0);
403 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
404 return;
405 }
406
407 pmsg = (struct GNUNET_CADET_PortMessage *) message;
408 removed = GNUNET_CONTAINER_multihashmap_remove (c->ports, &pmsg->port, c);
409 GNUNET_break_op (GNUNET_YES == removed);
410 removed = GNUNET_CONTAINER_multihashmap_remove (ports, &pmsg->port, c);
411 GNUNET_break_op (GNUNET_YES == removed);
412
413 GNUNET_SERVER_receive_done (client, GNUNET_OK);
414}
415
416
417/**
418 * Handler for requests of new channels.
419 *
420 * @param cls Closure.
421 * @param client Identification of the client.
422 * @param message The actual message.
423 */
424static void
425handle_channel_create (void *cls, struct GNUNET_SERVER_Client *client,
426 const struct GNUNET_MessageHeader *message)
427{
428 struct CadetClient *c;
429
430 LOG (GNUNET_ERROR_TYPE_DEBUG, "\n");
431 LOG (GNUNET_ERROR_TYPE_DEBUG, "new channel requested\n");
432
433 /* Sanity check for client registration */
434 if (NULL == (c = GML_client_get (client)))
435 {
436 GNUNET_break (0);
437 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
438 return;
439 }
440 LOG (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
441
442 /* Message size sanity check */
443 if (sizeof (struct GNUNET_CADET_LocalChannelCreateMessage)
444 != ntohs (message->size))
445 {
446 GNUNET_break (0);
447 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
448 return;
449 }
450
451 if (GNUNET_OK !=
452 GCCH_handle_local_create (c,
453 (struct GNUNET_CADET_LocalChannelCreateMessage *)
454 message))
455 {
456 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
457 return;
458 }
459
460 GNUNET_SERVER_receive_done (client, GNUNET_OK);
461}
462
463
464/**
465 * Handler for requests of deleting tunnels
466 *
467 * @param cls closure
468 * @param client identification of the client
469 * @param message the actual message
470 */
471static void
472handle_channel_destroy (void *cls, struct GNUNET_SERVER_Client *client,
473 const struct GNUNET_MessageHeader *message)
474{
475 const struct GNUNET_CADET_LocalChannelDestroyMessage *msg;
476 struct CadetClient *c;
477 struct CadetChannel *ch;
478 struct GNUNET_CADET_ClientChannelNumber ccn;
479
480 LOG (GNUNET_ERROR_TYPE_DEBUG, "Got a DESTROY CHANNEL from client!\n");
481
482 /* Sanity check for client registration */
483 if (NULL == (c = GML_client_get (client)))
484 {
485 GNUNET_break (0);
486 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
487 return;
488 }
489 LOG (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
490
491 /* Message sanity check */
492 if (sizeof (struct GNUNET_CADET_LocalChannelDestroyMessage)
493 != ntohs (message->size))
494 {
495 GNUNET_break (0);
496 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
497 return;
498 }
499
500 msg = (const struct GNUNET_CADET_LocalChannelDestroyMessage *) message;
501
502 /* Retrieve tunnel */
503 ccn = msg->ccn;
504 ch = GML_channel_get (c, ccn);
505
506 LOG (GNUNET_ERROR_TYPE_INFO, "Client %u is destroying channel %X\n",
507 c->id, ccn);
508
509 if (NULL == ch)
510 {
511 LOG (GNUNET_ERROR_TYPE_WARNING, " channel %X not found\n", ccn);
512 GNUNET_STATISTICS_update (stats,
513 "# client destroy messages on unknown channel",
514 1, GNUNET_NO);
515 GNUNET_SERVER_receive_done (client, GNUNET_OK);
516 return;
517 }
518
519 GCCH_handle_local_destroy (ch,
520 c,
521 ntohl (ccn.channel_of_client) < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI);
522
523 GNUNET_SERVER_receive_done (client, GNUNET_OK);
524}
525
526
527/**
528 * Handler for client traffic
529 *
530 * @param cls closure
531 * @param client identification of the client
532 * @param message the actual message
533 */
534static void
535handle_data (void *cls, struct GNUNET_SERVER_Client *client,
536 const struct GNUNET_MessageHeader *message)
537{
538 const struct GNUNET_MessageHeader *payload;
539 struct GNUNET_CADET_LocalData *msg;
540 struct CadetClient *c;
541 struct CadetChannel *ch;
542 struct GNUNET_CADET_ClientChannelNumber ccn;
543 size_t message_size;
544 size_t payload_size;
545 size_t payload_claimed_size;
546 int fwd;
547
548 LOG (GNUNET_ERROR_TYPE_DEBUG, "\n");
549 LOG (GNUNET_ERROR_TYPE_DEBUG, "\n");
550 LOG (GNUNET_ERROR_TYPE_DEBUG, "Got data from a client\n");
551
552 /* Sanity check for client registration */
553 if (NULL == (c = GML_client_get (client)))
554 {
555 GNUNET_break (0);
556 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
557 return;
558 }
559
560 /* Sanity check for message size */
561 message_size = ntohs (message->size);
562 if (sizeof (struct GNUNET_CADET_LocalData)
563 + sizeof (struct GNUNET_MessageHeader) > message_size
564 || GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE < message_size)
565 {
566 GNUNET_break (0);
567 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
568 return;
569 }
570
571 /* Sanity check for payload size */
572 payload_size = message_size - sizeof (struct GNUNET_CADET_LocalData);
573 msg = (struct GNUNET_CADET_LocalData *) message;
574 payload = (struct GNUNET_MessageHeader *) &msg[1];
575 payload_claimed_size = ntohs (payload->size);
576 if (sizeof (struct GNUNET_MessageHeader) > payload_claimed_size
577 || GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE < payload_claimed_size
578 || payload_claimed_size > payload_size)
579 {
580 LOG (GNUNET_ERROR_TYPE_WARNING,
581 "client claims to send %u bytes in %u payload\n",
582 payload_claimed_size, payload_size);
583 GNUNET_break (0);
584 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
585 return;
586 }
587
588 ccn = msg->ccn;
589 LOG (GNUNET_ERROR_TYPE_DEBUG, " %u bytes (%u payload) by client %u\n",
590 payload_size, payload_claimed_size, c->id);
591
592 /* Channel exists? */
593 fwd = ntohl (ccn.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI;
594 ch = GML_channel_get (c, ccn);
595 if (NULL == ch)
596 {
597 GNUNET_STATISTICS_update (stats,
598 "# client data messages on unknown channel",
599 1, GNUNET_NO);
600 GNUNET_SERVER_receive_done (client, GNUNET_OK);
601 return;
602 }
603
604 if (GNUNET_OK != GCCH_handle_local_data (ch, c, fwd, payload, payload_size))
605 {
606 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
607 return;
608 }
609
610 LOG (GNUNET_ERROR_TYPE_DEBUG, "receive done OK\n");
611 GNUNET_SERVER_receive_done (client, GNUNET_OK);
612
613 return;
614}
615
616
617/**
618 * Handler for client's ACKs for payload traffic.
619 *
620 * @param cls Closure (unused).
621 * @param client Identification of the client.
622 * @param message The actual message.
623 */
624static void
625handle_ack (void *cls, struct GNUNET_SERVER_Client *client,
626 const struct GNUNET_MessageHeader *message)
627{
628 struct GNUNET_CADET_LocalAck *msg;
629 struct CadetChannel *ch;
630 struct CadetClient *c;
631 struct GNUNET_CADET_ClientChannelNumber ccn;
632 int fwd;
633
634 LOG (GNUNET_ERROR_TYPE_DEBUG, "\n");
635 LOG (GNUNET_ERROR_TYPE_DEBUG, "Got a local ACK\n");
636
637 /* Sanity check for client registration */
638 if (NULL == (c = GML_client_get (client)))
639 {
640 GNUNET_break (0);
641 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
642 return;
643 }
644 LOG (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
645
646 msg = (struct GNUNET_CADET_LocalAck *) message;
647
648 /* Channel exists? */
649 ccn = msg->ccn;
650 LOG (GNUNET_ERROR_TYPE_DEBUG, " on channel %X\n",
651 ntohl (ccn.channel_of_client));
652 ch = GML_channel_get (c, ccn);
653 LOG (GNUNET_ERROR_TYPE_DEBUG, " -- ch %p\n", ch);
654 if (NULL == ch)
655 {
656 LOG (GNUNET_ERROR_TYPE_DEBUG,
657 "Channel %X unknown.\n",
658 ntohl (ccn.channel_of_client));
659 LOG (GNUNET_ERROR_TYPE_DEBUG, " for client %u.\n", c->id);
660 GNUNET_STATISTICS_update (stats,
661 "# client ack messages on unknown channel",
662 1, GNUNET_NO);
663 GNUNET_SERVER_receive_done (client, GNUNET_OK);
664 return;
665 }
666
667 /* If client is root, the ACK is going FWD, therefore this is "BCK ACK". */
668 /* If client is dest, the ACK is going BCK, therefore this is "FWD ACK" */
669 fwd = ntohl (ccn.channel_of_client) < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI;
670
671 GCCH_handle_local_ack (ch, fwd);
672 GNUNET_SERVER_receive_done (client, GNUNET_OK);
673}
674
675
676/**
677 * Iterator over all peers to send a monitoring client info about each peer.
678 *
679 * @param cls Closure ().
680 * @param peer Peer ID (tunnel remote peer).
681 * @param value Peer info.
682 *
683 * @return #GNUNET_YES, to keep iterating.
684 */
685static int
686get_all_peers_iterator (void *cls,
687 const struct GNUNET_PeerIdentity * peer,
688 void *value)
689{
690 struct GNUNET_SERVER_Client *client = cls;
691 struct CadetPeer *p = value;
692 struct GNUNET_CADET_LocalInfoPeer msg;
693
694 msg.header.size = htons (sizeof (msg));
695 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS);
696 msg.destination = *peer;
697 msg.paths = htons (GCP_count_paths (p));
698 msg.tunnel = htons (NULL != GCP_get_tunnel (p));
699
700 LOG (GNUNET_ERROR_TYPE_DEBUG, "sending info about peer %s\n",
701 GNUNET_i2s (peer));
702
703 GNUNET_SERVER_notification_context_unicast (nc, client,
704 &msg.header, GNUNET_NO);
705 return GNUNET_YES;
706}
707
708
709/**
710 * Iterator over all peers to dump info for each peer.
711 *
712 * @param cls Closure (unused).
713 * @param peer Peer ID (tunnel remote peer).
714 * @param value Peer info.
715 *
716 * @return #GNUNET_YES, to keep iterating.
717 */
718static int
719show_peer_iterator (void *cls,
720 const struct GNUNET_PeerIdentity * peer,
721 void *value)
722{
723 struct CadetPeer *p = value;
724 struct CadetTunnel *t;
725
726 t = GCP_get_tunnel (p);
727 if (NULL != t)
728 GCT_debug (t, GNUNET_ERROR_TYPE_ERROR);
729
730 LOG (GNUNET_ERROR_TYPE_ERROR, "\n");
731
732 return GNUNET_YES;
733}
734
735
736/**
737 * Iterator over all paths of a peer to build an InfoPeer message.
738 *
739 * Message contains blocks of peers, first not included.
740 *
741 * @param cls Closure (message to build).
742 * @param peer Peer this path is towards.
743 * @param path Path itself
744 * @return #GNUNET_YES if should keep iterating.
745 * #GNUNET_NO otherwise.
746 */
747static int
748path_info_iterator (void *cls,
749 struct CadetPeer *peer,
750 struct CadetPeerPath *path)
751{
752 struct GNUNET_CADET_LocalInfoPeer *resp = cls;
753 struct GNUNET_PeerIdentity *id;
754 uint16_t msg_size;
755 uint16_t path_size;
756 unsigned int i;
757
758 msg_size = ntohs (resp->header.size);
759 path_size = sizeof (struct GNUNET_PeerIdentity) * (path->length - 1);
760
761 LOG (GNUNET_ERROR_TYPE_DEBUG, "Info Path %u\n", path->length);
762 if (msg_size + path_size > UINT16_MAX)
763 {
764 LOG (GNUNET_ERROR_TYPE_WARNING, "path too long for info message\n");
765 return GNUNET_NO;
766 }
767
768 i = msg_size - sizeof (struct GNUNET_CADET_LocalInfoPeer);
769 i = i / sizeof (struct GNUNET_PeerIdentity);
770
771 /* Set id to the address of the first free peer slot. */
772 id = (struct GNUNET_PeerIdentity *) &resp[1];
773 id = &id[i];
774
775 /* Don't copy first peers.
776 * First peer is always the local one.
777 * Last peer is always the destination (leave as 0, EOL).
778 */
779 for (i = 0; i < path->length - 1; i++)
780 {
781 GNUNET_PEER_resolve (path->peers[i + 1], &id[i]);
782 LOG (GNUNET_ERROR_TYPE_DEBUG, " %s\n", GNUNET_i2s (&id[i]));
783 }
784
785 resp->header.size = htons (msg_size + path_size);
786
787 return GNUNET_YES;
788}
789
790
791/**
792 * Handler for client's INFO PEERS request.
793 *
794 * @param cls Closure (unused).
795 * @param client Identification of the client.
796 * @param message The actual message.
797 */
798static void
799handle_get_peers (void *cls, struct GNUNET_SERVER_Client *client,
800 const struct GNUNET_MessageHeader *message)
801{
802 struct CadetClient *c;
803 struct GNUNET_MessageHeader reply;
804
805 /* Sanity check for client registration */
806 if (NULL == (c = GML_client_get (client)))
807 {
808 GNUNET_break (0);
809 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
810 return;
811 }
812
813 LOG (GNUNET_ERROR_TYPE_DEBUG,
814 "Received get peers request from client %u (%p)\n",
815 c->id, client);
816
817 GCP_iterate_all (get_all_peers_iterator, client);
818 reply.size = htons (sizeof (reply));
819 reply.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS);
820 GNUNET_SERVER_notification_context_unicast (nc, client, &reply, GNUNET_NO);
821
822 LOG (GNUNET_ERROR_TYPE_DEBUG,
823 "Get peers request from client %u completed\n", c->id);
824 GNUNET_SERVER_receive_done (client, GNUNET_OK);
825}
826
827
828/**
829 * Handler for client's SHOW_PEER request.
830 *
831 * @param cls Closure (unused).
832 * @param client Identification of the client.
833 * @param message The actual message.
834 */
835void
836handle_show_peer (void *cls, struct GNUNET_SERVER_Client *client,
837 const struct GNUNET_MessageHeader *message)
838{
839 const struct GNUNET_CADET_LocalInfo *msg;
840 struct GNUNET_CADET_LocalInfoPeer *resp;
841 struct CadetPeer *p;
842 struct CadetClient *c;
843 unsigned char cbuf[64 * 1024];
844
845 /* Sanity check for client registration */
846 if (NULL == (c = GML_client_get (client)))
847 {
848 GNUNET_break (0);
849 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
850 return;
851 }
852
853 msg = (struct GNUNET_CADET_LocalInfo *) message;
854 resp = (struct GNUNET_CADET_LocalInfoPeer *) cbuf;
855 LOG (GNUNET_ERROR_TYPE_INFO,
856 "Received peer info request from client %u for peer %s\n",
857 c->id, GNUNET_i2s_full (&msg->peer));
858
859 resp->header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER);
860 resp->header.size = htons (sizeof (struct GNUNET_CADET_LocalInfoPeer));
861 resp->destination = msg->peer;
862 p = GCP_get (&msg->peer, GNUNET_NO);
863 if (NULL == p)
864 {
865 /* We don't know the peer */
866
867 LOG (GNUNET_ERROR_TYPE_INFO, "Peer %s unknown\n",
868 GNUNET_i2s_full (&msg->peer));
869 resp->paths = htons (0);
870 resp->tunnel = htons (NULL != GCP_get_tunnel (p));
871
872 GNUNET_SERVER_notification_context_unicast (nc, client,
873 &resp->header,
874 GNUNET_NO);
875 GNUNET_SERVER_receive_done (client, GNUNET_OK);
876 return;
877 }
878
879 resp->paths = htons (GCP_count_paths (p));
880 resp->tunnel = htons (NULL != GCP_get_tunnel (p));
881 GCP_iterate_paths (p, &path_info_iterator, resp);
882
883 GNUNET_SERVER_notification_context_unicast (nc, c->handle,
884 &resp->header, GNUNET_NO);
885
886 LOG (GNUNET_ERROR_TYPE_INFO, "Show peer from client %u completed.\n", c->id);
887 GNUNET_SERVER_receive_done (client, GNUNET_OK);
888}
889
890
891/**
892 * Iterator over all tunnels to send a monitoring client info about each tunnel.
893 *
894 * @param cls Closure ().
895 * @param peer Peer ID (tunnel remote peer).
896 * @param value Tunnel info.
897 *
898 * @return #GNUNET_YES, to keep iterating.
899 */
900static int
901get_all_tunnels_iterator (void *cls,
902 const struct GNUNET_PeerIdentity * peer,
903 void *value)
904{
905 struct GNUNET_SERVER_Client *client = cls;
906 struct CadetTunnel *t = value;
907 struct GNUNET_CADET_LocalInfoTunnel msg;
908
909 msg.header.size = htons (sizeof (msg));
910 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS);
911 msg.destination = *peer;
912 msg.channels = htonl (GCT_count_channels (t));
913 msg.connections = htonl (GCT_count_any_connections (t));
914 msg.cstate = htons ((uint16_t) GCT_get_cstate (t));
915 msg.estate = htons ((uint16_t) GCT_get_estate (t));
916
917 LOG (GNUNET_ERROR_TYPE_DEBUG, "sending info about tunnel ->%s\n",
918 GNUNET_i2s (peer));
919
920 GNUNET_SERVER_notification_context_unicast (nc, client,
921 &msg.header, GNUNET_NO);
922 return GNUNET_YES;
923}
924
925
926/**
927 * Handler for client's INFO TUNNELS request.
928 *
929 * @param cls Closure (unused).
930 * @param client Identification of the client.
931 * @param message The actual message.
932 */
933static void
934handle_get_tunnels (void *cls, struct GNUNET_SERVER_Client *client,
935 const struct GNUNET_MessageHeader *message)
936{
937 struct CadetClient *c;
938 struct GNUNET_MessageHeader reply;
939
940 /* Sanity check for client registration */
941 if (NULL == (c = GML_client_get (client)))
942 {
943 GNUNET_break (0);
944 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
945 return;
946 }
947
948 LOG (GNUNET_ERROR_TYPE_DEBUG,
949 "Received get tunnels request from client %u (%p)\n",
950 c->id, client);
951
952 GCT_iterate_all (get_all_tunnels_iterator, client);
953 reply.size = htons (sizeof (reply));
954 reply.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS);
955 GNUNET_SERVER_notification_context_unicast (nc, client, &reply, GNUNET_NO);
956
957 LOG (GNUNET_ERROR_TYPE_DEBUG,
958 "Get tunnels request from client %u completed\n", c->id);
959 GNUNET_SERVER_receive_done (client, GNUNET_OK);
960}
961
962
963static void
964iter_connection (void *cls, struct CadetConnection *c)
965{
966 struct GNUNET_CADET_LocalInfoTunnel *msg = cls;
967 struct GNUNET_CADET_ConnectionTunnelIdentifier *h;
968
969 h = (struct GNUNET_CADET_ConnectionTunnelIdentifier *) &msg[1];
970 h[msg->connections] = *(GCC_get_id (c));
971 msg->connections++;
972}
973
974static void
975iter_channel (void *cls, struct CadetChannel *ch)
976{
977 struct GNUNET_CADET_LocalInfoTunnel *msg = cls;
978 struct GNUNET_CADET_ConnectionTunnelIdentifier *h = (struct GNUNET_CADET_ConnectionTunnelIdentifier *) &msg[1];
979 struct GNUNET_CADET_ChannelTunnelNumber *chn = (struct GNUNET_CADET_ChannelTunnelNumber *) &h[msg->connections];
980
981 chn[msg->channels] = GCCH_get_id (ch);
982 msg->channels++;
983}
984
985
986/**
987 * Handler for client's SHOW_TUNNEL request.
988 *
989 * @param cls Closure (unused).
990 * @param client Identification of the client.
991 * @param message The actual message.
992 */
993void
994handle_show_tunnel (void *cls, struct GNUNET_SERVER_Client *client,
995 const struct GNUNET_MessageHeader *message)
996{
997 const struct GNUNET_CADET_LocalInfo *msg;
998 struct GNUNET_CADET_LocalInfoTunnel *resp;
999 struct CadetClient *c;
1000 struct CadetTunnel *t;
1001 unsigned int ch_n;
1002 unsigned int c_n;
1003 size_t size;
1004
1005 /* Sanity check for client registration */
1006 if (NULL == (c = GML_client_get (client)))
1007 {
1008 GNUNET_break (0);
1009 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1010 return;
1011 }
1012
1013 msg = (struct GNUNET_CADET_LocalInfo *) message;
1014 LOG (GNUNET_ERROR_TYPE_DEBUG,
1015 "Received tunnel info request from client %u for tunnel %s\n",
1016 c->id, GNUNET_i2s_full(&msg->peer));
1017
1018 t = GCP_get_tunnel (GCP_get (&msg->peer, GNUNET_NO));
1019 if (NULL == t)
1020 {
1021 /* We don't know the tunnel */
1022 struct GNUNET_CADET_LocalInfoTunnel warn;
1023
1024 LOG (GNUNET_ERROR_TYPE_INFO, "Tunnel %s unknown %u\n",
1025 GNUNET_i2s_full(&msg->peer), sizeof (warn));
1026 warn.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL);
1027 warn.header.size = htons (sizeof (warn));
1028 warn.destination = msg->peer;
1029 warn.channels = htonl (0);
1030 warn.connections = htonl (0);
1031 warn.cstate = htons (0);
1032 warn.estate = htons (0);
1033
1034 GNUNET_SERVER_notification_context_unicast (nc, client,
1035 &warn.header,
1036 GNUNET_NO);
1037 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1038 return;
1039 }
1040
1041 /* Initialize context */
1042 ch_n = GCT_count_channels (t);
1043 c_n = GCT_count_any_connections (t);
1044
1045 size = sizeof (struct GNUNET_CADET_LocalInfoTunnel);
1046 size += c_n * sizeof (struct GNUNET_CADET_ConnectionTunnelIdentifier);
1047 size += ch_n * sizeof (struct GNUNET_CADET_ChannelTunnelNumber);
1048
1049 resp = GNUNET_malloc (size);
1050 resp->header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL);
1051 resp->header.size = htons (size);
1052 resp->destination = msg->peer;
1053 /* Do not interleave with iterators, iter_channel needs conn in HBO */
1054 GCT_iterate_connections (t, &iter_connection, resp);
1055 GCT_iterate_channels (t, &iter_channel, resp);
1056 resp->connections = htonl (resp->connections);
1057 resp->channels = htonl (resp->channels);
1058 /* Do not interleave end */
1059 resp->cstate = htons (GCT_get_cstate (t));
1060 resp->estate = htons (GCT_get_estate (t));
1061 GNUNET_SERVER_notification_context_unicast (nc, c->handle,
1062 &resp->header, GNUNET_NO);
1063 GNUNET_free (resp);
1064
1065 LOG (GNUNET_ERROR_TYPE_DEBUG,
1066 "Show tunnel request from client %u completed. %u conn, %u ch\n",
1067 c->id, c_n, ch_n);
1068 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1069}
1070
1071
1072/**
1073 * Handler for client's INFO_DUMP request.
1074 *
1075 * @param cls Closure (unused).
1076 * @param client Identification of the client.
1077 * @param message The actual message.
1078 */
1079void
1080handle_info_dump (void *cls, struct GNUNET_SERVER_Client *client,
1081 const struct GNUNET_MessageHeader *message)
1082{
1083 struct CadetClient *c;
1084
1085 /* Sanity check for client registration */
1086 if (NULL == (c = GML_client_get (client)))
1087 {
1088 GNUNET_break (0);
1089 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1090 return;
1091 }
1092
1093 LOG (GNUNET_ERROR_TYPE_INFO, "Received dump info request from client %u\n",
1094 c->id);
1095 LOG (GNUNET_ERROR_TYPE_ERROR,
1096 "*************************** DUMP START ***************************\n");
1097
1098 for (c = clients_head; NULL != c; c = c->next)
1099 {
1100 LOG (GNUNET_ERROR_TYPE_ERROR, "Client %u (%p), handle: %p\n",
1101 c->id, c, c->handle);
1102 if (NULL != c->ports)
1103 LOG (GNUNET_ERROR_TYPE_ERROR, "\t%3u ports registered\n",
1104 GNUNET_CONTAINER_multihashmap_size (c->ports));
1105 else
1106 LOG (GNUNET_ERROR_TYPE_ERROR, "\t no ports registered\n");
1107 LOG (GNUNET_ERROR_TYPE_ERROR, "\t%3u own channles\n",
1108 GNUNET_CONTAINER_multihashmap32_size (c->own_channels));
1109 LOG (GNUNET_ERROR_TYPE_ERROR, "\t%3u incoming channles\n",
1110 GNUNET_CONTAINER_multihashmap32_size (c->incoming_channels));
1111 }
1112 LOG (GNUNET_ERROR_TYPE_ERROR, "***************************\n");
1113 GCP_iterate_all (&show_peer_iterator, NULL);
1114
1115 LOG (GNUNET_ERROR_TYPE_ERROR,
1116 "**************************** DUMP END ****************************\n");
1117
1118 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1119}
1120
1121
1122/**
1123 * Functions to handle messages from clients
1124 */
1125static struct GNUNET_SERVER_MessageHandler client_handlers[] = {
1126 {&handle_port_open, NULL, GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_OPEN,
1127 sizeof (struct GNUNET_CADET_PortMessage)},
1128 {&handle_port_close, NULL, GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE,
1129 sizeof (struct GNUNET_CADET_PortMessage)},
1130 {&handle_channel_create, NULL, GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE,
1131 sizeof (struct GNUNET_CADET_LocalChannelCreateMessage)},
1132 {&handle_channel_destroy, NULL, GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY,
1133 sizeof (struct GNUNET_CADET_LocalChannelDestroyMessage)},
1134 {&handle_data, NULL, GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA, 0},
1135 {&handle_ack, NULL, GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK,
1136 sizeof (struct GNUNET_CADET_LocalAck)},
1137 {&handle_get_peers, NULL, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS,
1138 sizeof (struct GNUNET_MessageHeader)},
1139 {&handle_show_peer, NULL, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER,
1140 sizeof (struct GNUNET_CADET_LocalInfo)},
1141 {&handle_get_tunnels, NULL, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS,
1142 sizeof (struct GNUNET_MessageHeader)},
1143 {&handle_show_tunnel, NULL, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL,
1144 sizeof (struct GNUNET_CADET_LocalInfo)},
1145 {&handle_info_dump, NULL, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_DUMP,
1146 sizeof (struct GNUNET_MessageHeader)},
1147 {NULL, NULL, 0, 0}
1148};
1149
1150
1151
1152/******************************************************************************/
1153/******************************** API ***********************************/
1154/******************************************************************************/
1155
1156/**
1157 * Initialize server subsystem.
1158 *
1159 * @param handle Server handle.
1160 */
1161void
1162GML_init (struct GNUNET_SERVER_Handle *handle)
1163{
1164 LOG (GNUNET_ERROR_TYPE_DEBUG, "init\n");
1165 server_handle = handle;
1166 GNUNET_SERVER_suspend (server_handle);
1167 ports = GNUNET_CONTAINER_multihashmap_create (16, GNUNET_NO);
1168}
1169
1170
1171/**
1172 * Install server (service) handlers and start listening to clients.
1173 */
1174void
1175GML_start (void)
1176{
1177 GNUNET_SERVER_add_handlers (server_handle, client_handlers);
1178 GNUNET_SERVER_connect_notify (server_handle, &handle_client_connect, NULL);
1179 GNUNET_SERVER_disconnect_notify (server_handle, &handle_client_disconnect,
1180 NULL);
1181 nc = GNUNET_SERVER_notification_context_create (server_handle, 1);
1182
1183 clients_head = NULL;
1184 clients_tail = NULL;
1185 next_client_id = 0;
1186 GNUNET_SERVER_resume (server_handle);
1187}
1188
1189
1190/**
1191 * Shutdown server.
1192 */
1193void
1194GML_shutdown (void)
1195{
1196 struct CadetClient *c;
1197
1198 LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down local\n");
1199
1200 for (c = clients_head; NULL != clients_head; c = clients_head)
1201 client_destroy (c);
1202
1203 if (nc != NULL)
1204 {
1205 GNUNET_SERVER_notification_context_destroy (nc);
1206 nc = NULL;
1207 }
1208
1209}
1210
1211
1212/**
1213 * Get a channel from a client.
1214 *
1215 * @param c Client to check.
1216 * @param ccn Channel ID, must be local (> 0x800...).
1217 *
1218 * @return non-NULL if channel exists in the clients lists
1219 */
1220struct CadetChannel *
1221GML_channel_get (struct CadetClient *c,
1222 struct GNUNET_CADET_ClientChannelNumber ccn)
1223{
1224 struct GNUNET_CONTAINER_MultiHashMap32 *map;
1225
1226 if (ntohl (ccn.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
1227 map = c->own_channels;
1228 else
1229 map = c->incoming_channels;
1230
1231 if (NULL == map)
1232 {
1233 GNUNET_break (0);
1234 LOG (GNUNET_ERROR_TYPE_DEBUG,
1235 "Client %s does no t have a valid map for CCN %X\n",
1236 GML_2s (c), ccn);
1237 return NULL;
1238 }
1239 return GNUNET_CONTAINER_multihashmap32_get (map,
1240 ccn.channel_of_client);
1241}
1242
1243
1244/**
1245 * Add a channel to a client
1246 *
1247 * @param client Client.
1248 * @param ccn Channel ID.
1249 * @param ch Channel.
1250 */
1251void
1252GML_channel_add (struct CadetClient *client,
1253 struct GNUNET_CADET_ClientChannelNumber ccn,
1254 struct CadetChannel *ch)
1255{
1256 if (ntohl (ccn.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
1257 GNUNET_CONTAINER_multihashmap32_put (client->own_channels,
1258 ccn.channel_of_client,
1259 ch,
1260 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
1261 else
1262 GNUNET_CONTAINER_multihashmap32_put (client->incoming_channels,
1263 ccn.channel_of_client,
1264 ch,
1265 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
1266}
1267
1268
1269/**
1270 * Remove a channel from a client.
1271 *
1272 * @param client Client.
1273 * @param ccn Channel ID.
1274 * @param ch Channel.
1275 */
1276void
1277GML_channel_remove (struct CadetClient *client,
1278 struct GNUNET_CADET_ClientChannelNumber ccn,
1279 struct CadetChannel *ch)
1280{
1281 if (ntohl (ccn.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
1282 GNUNET_CONTAINER_multihashmap32_remove (client->own_channels,
1283 ccn.channel_of_client,
1284 ch);
1285 else
1286 GNUNET_CONTAINER_multihashmap32_remove (client->incoming_channels,
1287 ccn.channel_of_client,
1288 ch);
1289}
1290
1291
1292/**
1293 * Get the tunnel's next free local channel ID.
1294 *
1295 * @param c Client.
1296 *
1297 * @return LID of a channel free to use.
1298 */
1299struct GNUNET_CADET_ClientChannelNumber
1300GML_get_next_ccn (struct CadetClient *c)
1301{
1302 struct GNUNET_CADET_ClientChannelNumber ccn;
1303
1304 while (NULL != GML_channel_get (c,
1305 c->next_ccn))
1306 {
1307 LOG (GNUNET_ERROR_TYPE_DEBUG,
1308 "Channel %u exists...\n",
1309 c->next_ccn);
1310 c->next_ccn.channel_of_client
1311 = htonl (1 + (ntohl (c->next_ccn.channel_of_client)));
1312 if (ntohl (c->next_ccn.channel_of_client) >=
1313 GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
1314 c->next_ccn.channel_of_client = htonl (0);
1315 }
1316 ccn = c->next_ccn;
1317 c->next_ccn.channel_of_client
1318 = htonl (1 + (ntohl (c->next_ccn.channel_of_client)));
1319
1320 return ccn;
1321}
1322
1323
1324/**
1325 * Check if client has registered with the service and has not disconnected
1326 *
1327 * @param client the client to check
1328 *
1329 * @return non-NULL if client exists in the global DLL
1330 */
1331struct CadetClient *
1332GML_client_get (struct GNUNET_SERVER_Client *client)
1333{
1334 if (NULL == client)
1335 return NULL;
1336 return GNUNET_SERVER_client_get_user_context (client,
1337 struct CadetClient);
1338}
1339
1340
1341/**
1342 * Find a client that has opened a port
1343 *
1344 * @param port Port to check.
1345 *
1346 * @return non-NULL if a client has the port.
1347 */
1348struct CadetClient *
1349GML_client_get_by_port (const struct GNUNET_HashCode *port)
1350{
1351 return GNUNET_CONTAINER_multihashmap_get (ports, port);
1352}
1353
1354
1355/**
1356 * Deletes a channel from a client (either owner or destination).
1357 *
1358 * @param c Client whose tunnel to delete.
1359 * @param ch Channel which should be deleted.
1360 * @param id Channel ID.
1361 */
1362void
1363GML_client_delete_channel (struct CadetClient *c,
1364 struct CadetChannel *ch,
1365 struct GNUNET_CADET_ClientChannelNumber id)
1366{
1367 int res;
1368
1369 if (ntohl (id.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
1370 {
1371 res = GNUNET_CONTAINER_multihashmap32_remove (c->own_channels,
1372 id.channel_of_client,
1373 ch);
1374 if (GNUNET_YES != res)
1375 LOG (GNUNET_ERROR_TYPE_DEBUG, "client_delete_tunnel root KO\n");
1376 }
1377 else
1378 {
1379 res = GNUNET_CONTAINER_multihashmap32_remove (c->incoming_channels,
1380 id.channel_of_client,
1381 ch);
1382 if (GNUNET_YES != res)
1383 LOG (GNUNET_ERROR_TYPE_DEBUG, "client_delete_channel dest KO\n");
1384 }
1385}
1386
1387/**
1388 * Build a local ACK message and send it to a local client, if needed.
1389 *
1390 * If the client was already allowed to send data, do nothing.
1391 *
1392 * @param c Client to whom send the ACK.
1393 * @param ccn Channel ID to use
1394 */
1395void
1396GML_send_ack (struct CadetClient *c,
1397 struct GNUNET_CADET_ClientChannelNumber ccn)
1398{
1399 struct GNUNET_CADET_LocalAck msg;
1400
1401 LOG (GNUNET_ERROR_TYPE_DEBUG,
1402 "send local %s ack on %X towards %p\n",
1403 ntohl (ccn.channel_of_client) < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI
1404 ? "FWD" : "BCK",
1405 ntohl (ccn.channel_of_client),
1406 c);
1407
1408 msg.header.size = htons (sizeof (msg));
1409 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK);
1410 msg.ccn = ccn;
1411 GNUNET_SERVER_notification_context_unicast (nc,
1412 c->handle,
1413 &msg.header,
1414 GNUNET_NO);
1415
1416}
1417
1418
1419
1420/**
1421 * Notify the client that a new incoming channel was created.
1422 *
1423 * @param c Client to notify.
1424 * @param ccn Channel ID.
1425 * @param port Channel's destination port.
1426 * @param opt Options (bit array).
1427 * @param peer Origin peer.
1428 */
1429void
1430GML_send_channel_create (struct CadetClient *c,
1431 struct GNUNET_CADET_ClientChannelNumber ccn,
1432 const struct GNUNET_HashCode *port,
1433 uint32_t opt,
1434 const struct GNUNET_PeerIdentity *peer)
1435{
1436 struct GNUNET_CADET_LocalChannelCreateMessage msg;
1437
1438 msg.header.size = htons (sizeof (msg));
1439 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE);
1440 msg.ccn = ccn;
1441 msg.port = *port;
1442 msg.opt = htonl (opt);
1443 msg.peer = *peer;
1444 GNUNET_SERVER_notification_context_unicast (nc, c->handle,
1445 &msg.header, GNUNET_NO);
1446}
1447
1448
1449/**
1450 * Build a local channel NACK message and send it to a local client.
1451 *
1452 * @param c Client to whom send the NACK.
1453 * @param ccn Channel ID to use
1454 */
1455void
1456GML_send_channel_nack (struct CadetClient *c,
1457 struct GNUNET_CADET_ClientChannelNumber ccn)
1458{
1459 struct GNUNET_CADET_LocalAck msg;
1460
1461 LOG (GNUNET_ERROR_TYPE_DEBUG,
1462 "send local nack on %X towards %p\n",
1463 ntohl (ccn.channel_of_client),
1464 c);
1465
1466 msg.header.size = htons (sizeof (msg));
1467 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_NACK_DEPRECATED);
1468 msg.ccn = ccn;
1469 GNUNET_SERVER_notification_context_unicast (nc,
1470 c->handle,
1471 &msg.header,
1472 GNUNET_NO);
1473
1474}
1475
1476/**
1477 * Notify a client that a channel is no longer valid.
1478 *
1479 * @param c Client.
1480 * @param ccn ID of the channel that is destroyed.
1481 */
1482void
1483GML_send_channel_destroy (struct CadetClient *c,
1484 struct GNUNET_CADET_ClientChannelNumber ccn)
1485{
1486 struct GNUNET_CADET_LocalChannelDestroyMessage msg;
1487
1488 if (NULL == c)
1489 {
1490 GNUNET_break (0);
1491 return;
1492 }
1493 if (GNUNET_YES == c->shutting_down)
1494 return;
1495 msg.header.size = htons (sizeof (msg));
1496 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY);
1497 msg.ccn = ccn;
1498 GNUNET_SERVER_notification_context_unicast (nc, c->handle,
1499 &msg.header, GNUNET_NO);
1500}
1501
1502
1503/**
1504 * Modify the cadet message ID from global to local and send to client.
1505 *
1506 * @param c Client to send to.
1507 * @param msg Message to modify and send.
1508 * @param ccn Channel ID to use (c can be both owner and client).
1509 */
1510void
1511GML_send_data (struct CadetClient *c,
1512 const struct GNUNET_CADET_ChannelAppDataMessage *msg,
1513 struct GNUNET_CADET_ClientChannelNumber ccn)
1514{
1515 struct GNUNET_CADET_LocalData *copy;
1516 uint16_t size = ntohs (msg->header.size) - sizeof (struct GNUNET_CADET_ChannelAppDataMessage);
1517 char cbuf[size + sizeof (struct GNUNET_CADET_LocalData)];
1518
1519 if (size < sizeof (struct GNUNET_MessageHeader))
1520 {
1521 GNUNET_break_op (0);
1522 return;
1523 }
1524 if (NULL == c)
1525 {
1526 GNUNET_break (0);
1527 return;
1528 }
1529 copy = (struct GNUNET_CADET_LocalData *) cbuf;
1530 GNUNET_memcpy (&copy[1], &msg[1], size);
1531 copy->header.size = htons (sizeof (struct GNUNET_CADET_LocalData) + size);
1532 copy->header.type = htons (GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA);
1533 copy->ccn = ccn;
1534 GNUNET_SERVER_notification_context_unicast (nc, c->handle,
1535 &copy->header, GNUNET_NO);
1536}
1537
1538
1539/**
1540 * Get the static string to represent a client.
1541 *
1542 * @param c Client.
1543 *
1544 * @return Static string for the client.
1545 */
1546const char *
1547GML_2s (const struct CadetClient *c)
1548{
1549 static char buf[32];
1550
1551 SPRINTF (buf, "%u", c->id);
1552 return buf;
1553}
diff --git a/src/cadet/gnunet-service-cadet_local.h b/src/cadet/gnunet-service-cadet_local.h
deleted file mode 100644
index 113c2f489..000000000
--- a/src/cadet/gnunet-service-cadet_local.h
+++ /dev/null
@@ -1,234 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2013 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 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 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file cadet/gnunet-service-cadet_local.h
23 * @brief cadet service; dealing with local clients
24 * @author Bartlomiej Polot
25 *
26 * All functions in this file should use the prefix GML (Gnunet Cadet Local)
27 */
28
29#ifndef GNUNET_SERVICE_CADET_LOCAL_H
30#define GNUNET_SERVICE_CADET_LOCAL_H
31
32#ifdef __cplusplus
33extern "C"
34{
35#if 0 /* keep Emacsens' auto-indent happy */
36}
37#endif
38#endif
39
40#include "platform.h"
41#include "gnunet_util_lib.h"
42
43/**
44 * Struct containing information about a client of the service
45 */
46struct CadetClient;
47
48#include "gnunet-service-cadet_channel.h"
49
50/******************************************************************************/
51/******************************** API ***********************************/
52/******************************************************************************/
53
54/**
55 * Initialize server subsystem.
56 *
57 * @param handle Server handle.
58 */
59void
60GML_init (struct GNUNET_SERVER_Handle *handle);
61
62/**
63 * Install server (service) handlers and start listening to clients.
64 */
65void
66GML_start (void);
67
68/**
69 * Shutdown server.
70 */
71void
72GML_shutdown (void);
73
74/**
75 * Get a channel from a client.
76 *
77 * @param c Client to check.
78 * @param ccn Channel ID, must be local (> 0x800...).
79 *
80 * @return non-NULL if channel exists in the clients lists
81 */
82struct CadetChannel *
83GML_channel_get (struct CadetClient *c,
84 struct GNUNET_CADET_ClientChannelNumber ccn);
85
86/**
87 * Add a channel to a client
88 *
89 * @param client Client.
90 * @param ccn Channel ID.
91 * @param ch Channel.
92 */
93void
94GML_channel_add (struct CadetClient *client,
95 struct GNUNET_CADET_ClientChannelNumber ccn,
96 struct CadetChannel *ch);
97
98/**
99 * Remove a channel from a client
100 *
101 * @param client Client.
102 * @param ccn Channel ID.
103 * @param ch Channel.
104 */
105void
106GML_channel_remove (struct CadetClient *client,
107 struct GNUNET_CADET_ClientChannelNumber ccn,
108 struct CadetChannel *ch);
109
110/**
111 * Get the tunnel's next free local channel ID.
112 *
113 * @param c Client.
114 *
115 * @return LID of a channel free to use.
116 */
117struct GNUNET_CADET_ClientChannelNumber
118GML_get_next_ccn (struct CadetClient *c);
119
120/**
121 * Check if client has registered with the service and has not disconnected
122 *
123 * @param client the client to check
124 *
125 * @return non-NULL if client exists in the global DLL
126 */
127struct CadetClient *
128GML_client_get (struct GNUNET_SERVER_Client *client);
129
130/**
131 * Find a client that has opened a port
132 *
133 * @param port Port to check.
134 *
135 * @return non-NULL if a client has the port.
136 */
137struct CadetClient *
138GML_client_get_by_port (const struct GNUNET_HashCode *port);
139
140/**
141 * Deletes a tunnel from a client (either owner or destination).
142 *
143 * @param c Client whose tunnel to delete.
144 * @param ch Channel which should be deleted.
145 * @param id Channel ID.
146 */
147void
148GML_client_delete_channel (struct CadetClient *c,
149 struct CadetChannel *ch,
150 struct GNUNET_CADET_ClientChannelNumber id);
151
152/**
153 * Build a local ACK message and send it to a local client, if needed.
154 *
155 * If the client was already allowed to send data, do nothing.
156 *
157 * @param c Client to whom send the ACK.
158 * @param id Channel ID to use
159 */
160void
161GML_send_ack (struct CadetClient *c,
162 struct GNUNET_CADET_ClientChannelNumber id);
163
164/**
165 * Notify the appropriate client that a new incoming channel was created.
166 *
167 * @param c Client to notify.
168 * @param id Channel ID.
169 * @param port Channel's destination port.
170 * @param opt Options (bit array).
171 * @param peer Origin peer.
172 */
173void
174GML_send_channel_create (struct CadetClient *c,
175 struct GNUNET_CADET_ClientChannelNumber id,
176 const struct GNUNET_HashCode *port,
177 uint32_t opt,
178 const struct GNUNET_PeerIdentity *peer);
179
180/**
181 * Build a local channel NACK message and send it to a local client.
182 *
183 * @param c Client to whom send the NACK.
184 * @param id Channel ID to use
185 */
186void
187GML_send_channel_nack (struct CadetClient *c,
188 struct GNUNET_CADET_ClientChannelNumber id);
189
190
191/**
192 * Notify a client that a channel is no longer valid.
193 *
194 * @param c Client.
195 * @param id ID of the channel that is destroyed.
196 */
197void
198GML_send_channel_destroy (struct CadetClient *c,
199 struct GNUNET_CADET_ClientChannelNumber id);
200
201
202/**
203 * Modify the cadet message ID from global to local and send to client.
204 *
205 * @param c Client to send to.
206 * @param msg Message to modify and send.
207 * @param id Channel ID to use (c can be both owner and client).
208 */
209void
210GML_send_data (struct CadetClient *c,
211 const struct GNUNET_CADET_ChannelAppDataMessage *msg,
212 struct GNUNET_CADET_ClientChannelNumber id);
213
214/**
215 * Get the static string to represent a client.
216 *
217 * @param c Client.
218 *
219 * @return Static string for the client.
220 */
221const char *
222GML_2s (const struct CadetClient *c);
223
224
225#if 0 /* keep Emacsens' auto-indent happy */
226{
227#endif
228#ifdef __cplusplus
229}
230#endif
231
232/* ifndef GNUNET_CADET_SERVICE_LOCAL_H */
233#endif
234/* end of gnunet-cadet-service_LOCAL.h */
diff --git a/src/cadet/gnunet-service-cadet-new_paths.c b/src/cadet/gnunet-service-cadet_paths.c
index 685656ec3..13752643c 100644
--- a/src/cadet/gnunet-service-cadet-new_paths.c
+++ b/src/cadet/gnunet-service-cadet_paths.c
@@ -18,18 +18,16 @@
18 Boston, MA 02110-1301, USA. 18 Boston, MA 02110-1301, USA.
19*/ 19*/
20/** 20/**
21 * @file cadet/gnunet-service-cadet-new_paths.c 21 * @file cadet/gnunet-service-cadet_paths.c
22 * @brief Information we track per path. 22 * @brief Information we track per path.
23 * @author Bartlomiej Polot 23 * @author Bartlomiej Polot
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 *
26 * TODO:
27 * - path desirability score calculations are not done
28 */ 25 */
29#include "platform.h" 26#include "platform.h"
30#include "gnunet-service-cadet-new_connection.h" 27#include "gnunet-service-cadet_connection.h"
31#include "gnunet-service-cadet-new_peer.h" 28#include "gnunet-service-cadet_tunnels.h"
32#include "gnunet-service-cadet-new_paths.h" 29#include "gnunet-service-cadet_peer.h"
30#include "gnunet-service-cadet_paths.h"
33 31
34 32
35#define LOG(level, ...) GNUNET_log_from(level,"cadet-pat",__VA_ARGS__) 33#define LOG(level, ...) GNUNET_log_from(level,"cadet-pat",__VA_ARGS__)
@@ -75,8 +73,16 @@ struct CadetPeerPath
75static void 73static void
76recalculate_path_desirability (struct CadetPeerPath *path) 74recalculate_path_desirability (struct CadetPeerPath *path)
77{ 75{
78 /* FIXME: update path desirability! */ 76 double result = 0.0;
79 GNUNET_break (0); // not implemented 77
78 for (unsigned int i=0;i<path->entries_length;i++)
79 {
80 struct CadetPeer *cp = path->entries[i]->peer;
81
82 result += GCP_get_desirability_of_path (cp,
83 i);
84 }
85 path->desirability = (GNUNET_CONTAINER_HeapCostType) result;
80} 86}
81 87
82 88
@@ -147,6 +153,7 @@ GCPP_add_connection (struct CadetPeerPath *path,
147 GNUNET_assert (off < path->entries_length); 153 GNUNET_assert (off < path->entries_length);
148 entry = path->entries[off]; 154 entry = path->entries[off];
149 GNUNET_assert (NULL == entry->cc); 155 GNUNET_assert (NULL == entry->cc);
156 GNUNET_assert (NULL != cc);
150 entry->cc = cc; 157 entry->cc = cc;
151} 158}
152 159
@@ -191,7 +198,20 @@ path_destroy (struct CadetPeerPath *path)
191 "Destroying path %s\n", 198 "Destroying path %s\n",
192 GCPP_2s (path)); 199 GCPP_2s (path));
193 for (unsigned int i=0;i<path->entries_length;i++) 200 for (unsigned int i=0;i<path->entries_length;i++)
194 GNUNET_free (path->entries[i]); 201 {
202 struct CadetPeerPathEntry *entry = path->entries[i];
203
204 if (NULL != entry->cc)
205 {
206 struct CadetTConnection *ct;
207
208 ct = GCC_get_ct (entry->cc);
209 if (NULL != ct)
210 GCT_connection_lost (ct);
211 GCC_destroy_without_tunnel (entry->cc);
212 }
213 GNUNET_free (entry);
214 }
195 GNUNET_free (path->entries); 215 GNUNET_free (path->entries);
196 GNUNET_free (path); 216 GNUNET_free (path);
197} 217}
@@ -208,15 +228,18 @@ void
208GCPP_release (struct CadetPeerPath *path) 228GCPP_release (struct CadetPeerPath *path)
209{ 229{
210 struct CadetPeerPathEntry *entry; 230 struct CadetPeerPathEntry *entry;
231 int force;
211 232
212 LOG (GNUNET_ERROR_TYPE_DEBUG, 233 LOG (GNUNET_ERROR_TYPE_DEBUG,
213 "Owner releases path %s\n", 234 "Owner releases path %s\n",
214 GCPP_2s (path)); 235 GCPP_2s (path));
215 path->hn = NULL; 236 path->hn = NULL;
216 entry = path->entries[path->entries_length - 1]; 237 entry = path->entries[path->entries_length - 1];
238 GNUNET_assert (path == entry->path);
217 while (1) 239 while (1)
218 { 240 {
219 /* cut 'off' end of path */ 241 /* cut 'off' end of path */
242 GNUNET_assert (NULL == entry->cc);
220 GCP_path_entry_remove (entry->peer, 243 GCP_path_entry_remove (entry->peer,
221 entry, 244 entry,
222 path->entries_length - 1); 245 path->entries_length - 1);
@@ -228,12 +251,15 @@ GCPP_release (struct CadetPeerPath *path)
228 251
229 /* see if new peer at the end likes this path any better */ 252 /* see if new peer at the end likes this path any better */
230 entry = path->entries[path->entries_length - 1]; 253 entry = path->entries[path->entries_length - 1];
254 GNUNET_assert (path == entry->path);
255 force = (NULL == entry->cc) ? GNUNET_NO : GNUNET_YES;
231 path->hn = GCP_attach_path (entry->peer, 256 path->hn = GCP_attach_path (entry->peer,
232 path, 257 path,
233 path->entries_length - 1, 258 path->entries_length - 1,
234 GNUNET_NO); 259 force);
235 if (NULL != path->hn) 260 if (NULL != path->hn)
236 return; /* yep, got attached, we are done. */ 261 return; /* yep, got attached, we are done. */
262 GNUNET_assert (GNUNET_NO == force);
237 } 263 }
238 264
239 /* nobody wants us, discard the path */ 265 /* nobody wants us, discard the path */
@@ -367,7 +393,6 @@ extend_path (struct CadetPeerPath *path,
367 int force) 393 int force)
368{ 394{
369 unsigned int old_len = path->entries_length; 395 unsigned int old_len = path->entries_length;
370 struct GNUNET_CONTAINER_HeapNode *hn;
371 int i; 396 int i;
372 397
373 /* Expand path */ 398 /* Expand path */
@@ -393,38 +418,43 @@ extend_path (struct CadetPeerPath *path,
393 418
394 /* If we extend an existing path, detach it from the 419 /* If we extend an existing path, detach it from the
395 old owner and re-attach to the new one */ 420 old owner and re-attach to the new one */
396 hn = NULL; 421 GCP_detach_path (path->entries[old_len-1]->peer,
422 path,
423 path->hn);
424 path->hn = NULL;
397 for (i=num_peers-1;i>=0;i--) 425 for (i=num_peers-1;i>=0;i--)
398 { 426 {
399 struct CadetPeerPathEntry *entry = path->entries[old_len + i]; 427 struct CadetPeerPathEntry *entry = path->entries[old_len + i];
400 428
401 path->entries_length = old_len + i + 1; 429 path->entries_length = old_len + i + 1;
402 recalculate_path_desirability (path); 430 recalculate_path_desirability (path);
403 hn = GCP_attach_path (peers[i], 431 path->hn = GCP_attach_path (peers[i],
404 path, 432 path,
405 old_len + (unsigned int) i, 433 old_len + (unsigned int) i,
406 GNUNET_YES); 434 force);
407 if (NULL != hn) 435 if (NULL != path->hn)
408 break; 436 break;
437 GNUNET_assert (NULL == entry->cc);
409 GCP_path_entry_remove (entry->peer, 438 GCP_path_entry_remove (entry->peer,
410 entry, 439 entry,
411 old_len + i); 440 old_len + i);
412 GNUNET_free (entry); 441 GNUNET_free (entry);
413 path->entries[old_len + i] = NULL; 442 path->entries[old_len + i] = NULL;
414 } 443 }
415 if (NULL == hn) 444 if (NULL == path->hn)
416 { 445 {
417 /* none of the peers is interested in this path; 446 /* none of the peers is interested in this path;
418 shrink path back */ 447 shrink path back and re-attach. */
419 GNUNET_array_grow (path->entries, 448 GNUNET_array_grow (path->entries,
420 path->entries_length, 449 path->entries_length,
421 old_len); 450 old_len);
451 path->hn = GCP_attach_path (path->entries[old_len - 1]->peer,
452 path,
453 old_len - 1,
454 GNUNET_YES);
455 GNUNET_assert (NULL != path->hn);
422 return; 456 return;
423 } 457 }
424 GCP_detach_path (path->entries[old_len-1]->peer,
425 path,
426 path->hn);
427 path->hn = hn;
428 LOG (GNUNET_ERROR_TYPE_DEBUG, 458 LOG (GNUNET_ERROR_TYPE_DEBUG,
429 "Extended path %s\n", 459 "Extended path %s\n",
430 GCPP_2s (path)); 460 GCPP_2s (path));
@@ -454,25 +484,42 @@ GCPP_try_path_from_dht (const struct GNUNET_PeerIdentity *get_path,
454 struct CadetPeerPath *path; 484 struct CadetPeerPath *path;
455 struct GNUNET_CONTAINER_HeapNode *hn; 485 struct GNUNET_CONTAINER_HeapNode *hn;
456 int i; 486 int i;
487 unsigned int skip;
488 unsigned int total_len;
457 489
458 /* precompute 'cpath' so we can avoid doing the lookups lots of times */ 490 /* precompute 'cpath' so we can avoid doing the lookups lots of times */
459 for (unsigned int off=0;off<get_path_length + put_path_length;off++) 491 skip = 0;
492 memset (cpath,
493 0,
494 sizeof (cpath)); /* Just to trigger harder errors later. */
495 total_len = get_path_length + put_path_length;
496 for (unsigned int off=0;off<total_len;off++)
460 { 497 {
461 const struct GNUNET_PeerIdentity *pid; 498 const struct GNUNET_PeerIdentity *pid;
462 499
463 pid = (off < get_path_length) 500 pid = (off < get_path_length)
464 ? &get_path[get_path_length - off] 501 ? &get_path[get_path_length - off]
465 : &put_path[get_path_length + put_path_length - off]; 502 : &put_path[get_path_length + put_path_length - off];
466 cpath[off] = GCP_get (pid, 503 cpath[off - skip] = GCP_get (pid,
467 GNUNET_YES); 504 GNUNET_YES);
505 /* Check that no peer is twice on the path */
506 for (unsigned int i=0;i<off - skip;i++)
507 {
508 if (cpath[i] == cpath[off - skip])
509 {
510 skip = off - i;
511 break;
512 }
513 }
468 } 514 }
515 total_len -= skip;
469 516
470 /* First figure out if this path is a subset of an existing path, an 517 /* First figure out if this path is a subset of an existing path, an
471 extension of an existing path, or a new path. */ 518 extension of an existing path, or a new path. */
472 cm_ctx.cpath_length = get_path_length + put_path_length; 519 cm_ctx.cpath_length = total_len;
473 cm_ctx.cpath = cpath; 520 cm_ctx.cpath = cpath;
474 cm_ctx.match = NULL; 521 cm_ctx.match = NULL;
475 for (i=get_path_length + put_path_length-1;i>=0;i--) 522 for (i=total_len-1;i>=0;i--)
476 { 523 {
477 GCP_iterate_paths_at (cpath[i], 524 GCP_iterate_paths_at (cpath[i],
478 (unsigned int) i, 525 (unsigned int) i,
@@ -480,7 +527,7 @@ GCPP_try_path_from_dht (const struct GNUNET_PeerIdentity *get_path,
480 &cm_ctx); 527 &cm_ctx);
481 if (NULL != cm_ctx.match) 528 if (NULL != cm_ctx.match)
482 { 529 {
483 if (i == get_path_length + put_path_length - 1) 530 if (i == total_len - 1)
484 { 531 {
485 /* Existing path includes this one, nothing to do! */ 532 /* Existing path includes this one, nothing to do! */
486 LOG (GNUNET_ERROR_TYPE_DEBUG, 533 LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -494,8 +541,8 @@ GCPP_try_path_from_dht (const struct GNUNET_PeerIdentity *get_path,
494 "Trying to extend existing path %s by additional links discovered from DHT\n", 541 "Trying to extend existing path %s by additional links discovered from DHT\n",
495 GCPP_2s (cm_ctx.match)); 542 GCPP_2s (cm_ctx.match));
496 extend_path (cm_ctx.match, 543 extend_path (cm_ctx.match,
497 &cpath[i], 544 &cpath[i + 1],
498 get_path_length + put_path_length - i, 545 total_len - i - 1,
499 GNUNET_NO); 546 GNUNET_NO);
500 return; 547 return;
501 } 548 }
@@ -504,7 +551,7 @@ GCPP_try_path_from_dht (const struct GNUNET_PeerIdentity *get_path,
504 551
505 /* No match at all, create completely new path */ 552 /* No match at all, create completely new path */
506 path = GNUNET_new (struct CadetPeerPath); 553 path = GNUNET_new (struct CadetPeerPath);
507 path->entries_length = get_path_length + put_path_length; 554 path->entries_length = total_len;
508 path->entries = GNUNET_new_array (path->entries_length, 555 path->entries = GNUNET_new_array (path->entries_length,
509 struct CadetPeerPathEntry *); 556 struct CadetPeerPathEntry *);
510 for (i=path->entries_length-1;i>=0;i--) 557 for (i=path->entries_length-1;i>=0;i--)
@@ -526,7 +573,7 @@ GCPP_try_path_from_dht (const struct GNUNET_PeerIdentity *get_path,
526 573
527 /* Finally, try to attach it */ 574 /* Finally, try to attach it */
528 hn = NULL; 575 hn = NULL;
529 for (i=get_path_length + put_path_length-1;i>=0;i--) 576 for (i=total_len-1;i>=0;i--)
530 { 577 {
531 struct CadetPeerPathEntry *entry = path->entries[i]; 578 struct CadetPeerPathEntry *entry = path->entries[i];
532 579
@@ -613,8 +660,8 @@ GCPP_get_path_from_route (unsigned int path_length,
613 "Extending existing path %s to create inverse for incoming connection\n", 660 "Extending existing path %s to create inverse for incoming connection\n",
614 GCPP_2s (cm_ctx.match)); 661 GCPP_2s (cm_ctx.match));
615 extend_path (cm_ctx.match, 662 extend_path (cm_ctx.match,
616 &cpath[i], 663 &cpath[i + 1],
617 path_length - i, 664 path_length - i - 1,
618 GNUNET_YES); 665 GNUNET_YES);
619 /* Check that extension was successful */ 666 /* Check that extension was successful */
620 GNUNET_assert (cm_ctx.match->entries_length == path_length); 667 GNUNET_assert (cm_ctx.match->entries_length == path_length);
diff --git a/src/cadet/gnunet-service-cadet-new_paths.h b/src/cadet/gnunet-service-cadet_paths.h
index 7310d75e6..6b7bef640 100644
--- a/src/cadet/gnunet-service-cadet-new_paths.h
+++ b/src/cadet/gnunet-service-cadet_paths.h
@@ -29,7 +29,7 @@
29#define GNUNET_SERVICE_CADET_PATHS_H 29#define GNUNET_SERVICE_CADET_PATHS_H
30 30
31#include "gnunet_util_lib.h" 31#include "gnunet_util_lib.h"
32#include "gnunet-service-cadet-new.h" 32#include "gnunet-service-cadet.h"
33 33
34/** 34/**
35 * Create a peer path based on the result of a DHT lookup. If we 35 * Create a peer path based on the result of a DHT lookup. If we
diff --git a/src/cadet/gnunet-service-cadet_peer.c b/src/cadet/gnunet-service-cadet_peer.c
index fa3f2be80..71c7c67d0 100644
--- a/src/cadet/gnunet-service-cadet_peer.c
+++ b/src/cadet/gnunet-service-cadet_peer.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2013, 2015 GNUnet e.V. 3 Copyright (C) 2001-2017 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -17,2193 +17,1461 @@
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA. 18 Boston, MA 02110-1301, USA.
19*/ 19*/
20
20/** 21/**
21 * @file cadet/gnunet-service-cadet_peer.c 22 * @file cadet/gnunet-service-cadet_peer.c
22 * @brief GNUnet CADET service connection handling 23 * @brief Information we track per peer.
23 * @author Bartlomiej Polot 24 * @author Bartlomiej Polot
25 * @author Christian Grothoff
26 *
27 * TODO:
28 * - optimize stopping/restarting DHT search to situations
29 * where we actually need it (i.e. not if we have a direct connection,
30 * or if we already have plenty of good short ones, or maybe even
31 * to take a break if we have some connections and have searched a lot (?))
24 */ 32 */
25#include "platform.h" 33#include "platform.h"
26#include "gnunet_util_lib.h" 34#include "gnunet_util_lib.h"
35#include "gnunet_hello_lib.h"
27#include "gnunet_signatures.h" 36#include "gnunet_signatures.h"
28#include "gnunet_transport_service.h" 37#include "gnunet_transport_service.h"
29#include "gnunet_ats_service.h" 38#include "gnunet_ats_service.h"
30#include "gnunet_core_service.h" 39#include "gnunet_core_service.h"
31#include "gnunet_statistics_service.h" 40#include "gnunet_statistics_service.h"
32#include "cadet_protocol.h" 41#include "cadet_protocol.h"
33#include "gnunet-service-cadet_peer.h"
34#include "gnunet-service-cadet_dht.h"
35#include "gnunet-service-cadet_connection.h" 42#include "gnunet-service-cadet_connection.h"
36#include "gnunet-service-cadet_tunnel.h" 43#include "gnunet-service-cadet_dht.h"
37#include "cadet_path.h" 44#include "gnunet-service-cadet_peer.h"
45#include "gnunet-service-cadet_paths.h"
46#include "gnunet-service-cadet_tunnels.h"
38 47
39#define LOG(level, ...) GNUNET_log_from (level,"cadet-p2p",__VA_ARGS__)
40#define LOG2(level, ...) GNUNET_log_from_nocheck(level,"cadet-p2p",__VA_ARGS__)
41 48
49#define LOG(level, ...) GNUNET_log_from(level,"cadet-per",__VA_ARGS__)
42 50
43/******************************************************************************/
44/******************************** STRUCTS **********************************/
45/******************************************************************************/
46 51
47/** 52/**
48 * Information about a queued message on the peer level. 53 * How long do we wait until tearing down an idle peer?
49 */ 54 */
50struct CadetPeerQueue { 55#define IDLE_PEER_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 5)
51
52 struct CadetPeerQueue *next;
53 struct CadetPeerQueue *prev;
54
55 /**
56 * Envelope to cancel message before MQ sends it.
57 */
58 struct GNUNET_MQ_Envelope *env;
59
60 /**
61 * Peer (neighbor) this message is being sent to.
62 */
63 struct CadetPeer *peer;
64
65 /**
66 * Continuation to call to notify higher layers about message sent.
67 */
68 GCP_sent cont;
69
70 /**
71 * Closure for @a cont.
72 */
73 void *cont_cls;
74
75 /**
76 * Task to asynchronously run the drop continuation.
77 */
78 struct GNUNET_SCHEDULER_Task *drop_task;
79
80 /**
81 * Time when message was queued for sending.
82 */
83 struct GNUNET_TIME_Absolute queue_timestamp;
84
85 /**
86 * #GNUNET_YES if message was management traffic (POLL, ACK, ...).
87 */
88 int management_traffic;
89
90 /**
91 * Message type.
92 */
93 uint16_t type;
94
95 /**
96 * Message size.
97 */
98 uint16_t size;
99
100 /**
101 * Type of the message's payload, if it was encrypted data.
102 */
103 uint16_t payload_type;
104
105 /**
106 * ID of the payload (PID, ACK #, ...).
107 */
108 struct CadetEncryptedMessageIdentifier payload_id;
109
110 /**
111 * Connection this message was sent on.
112 */
113 struct CadetConnection *c;
114
115 /**
116 * Direction in @a c this message was send on (#GNUNET_YES = FWD).
117 */
118 int c_fwd;
119};
120
121 56
122/** 57/**
123 * Struct containing all information regarding a given peer 58 * How long do we keep paths around if we no longer care about the peer?
124 */ 59 */
125struct CadetPeer 60#define IDLE_PATH_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2)
126{
127 /**
128 * ID of the peer
129 */
130 GNUNET_PEER_Id id;
131
132 struct CadetPeerQueue *q_head;
133 struct CadetPeerQueue *q_tail;
134
135 /**
136 * Last time we heard from this peer
137 */
138 struct GNUNET_TIME_Absolute last_contact;
139
140 /**
141 * Paths to reach the peer, ordered by ascending hop count
142 */
143 struct CadetPeerPath *path_head;
144
145 /**
146 * Paths to reach the peer, ordered by ascending hop count
147 */
148 struct CadetPeerPath *path_tail;
149
150 /**
151 * Handle to stop the DHT search for paths to this peer
152 */
153 struct GCD_search_handle *search_h;
154
155 /**
156 * Handle to stop the DHT search for paths to this peer
157 */
158 struct GNUNET_SCHEDULER_Task *search_delayed;
159
160 /**
161 * Tunnel to this peer, if any.
162 */
163 struct CadetTunnel *tunnel;
164
165 /**
166 * Connections that go through this peer; indexed by tid.
167 */
168 struct GNUNET_CONTAINER_MultiShortmap *connections;
169
170 /**
171 * Handle for core transmissions.
172 */
173 struct GNUNET_MQ_Handle *core_mq;
174
175 /**
176 * How many messages are in the queue to this peer.
177 */
178 unsigned int queue_n;
179
180 /**
181 * Hello message.
182 */
183 struct GNUNET_HELLO_Message* hello;
184
185 /**
186 * Handle to us offering the HELLO to the transport.
187 */
188 struct GNUNET_TRANSPORT_OfferHelloHandle *hello_offer;
189
190 /**
191 * Handle to our ATS request asking ATS to suggest an address
192 * to TRANSPORT for this peer (to establish a direct link).
193 */
194 struct GNUNET_ATS_ConnectivitySuggestHandle *connectivity_suggestion;
195 61
196};
197
198
199/******************************************************************************/
200/******************************* GLOBALS ***********************************/
201/******************************************************************************/
202
203/**
204 * Global handle to the statistics service.
205 */
206extern struct GNUNET_STATISTICS_Handle *stats;
207 62
208/**
209 * Local peer own ID (full value).
210 */
211extern struct GNUNET_PeerIdentity my_full_id;
212 63
213/**
214 * Local peer own ID (short)
215 */
216extern GNUNET_PEER_Id myid;
217 64
218/** 65/**
219 * Peers known, indexed by PeerIdentity, values of type `struct CadetPeer`. 66 * Data structure used to track whom we have to notify about changes
67 * to our message queue.
220 */ 68 */
221static struct GNUNET_CONTAINER_MultiPeerMap *peers; 69struct GCP_MessageQueueManager
222 70{
223/**
224 * How many peers do we want to remember?
225 */
226static unsigned long long max_peers;
227 71
228/** 72 /**
229 * Percentage of messages that will be dropped (for test purposes only). 73 * Kept in a DLL.
230 */ 74 */
231static unsigned long long drop_percent; 75 struct GCP_MessageQueueManager *next;
232 76
233/** 77 /**
234 * Handle to communicate with CORE. 78 * Kept in a DLL.
235 */ 79 */
236static struct GNUNET_CORE_Handle *core_handle; 80 struct GCP_MessageQueueManager *prev;
237 81
238/** 82 /**
239 * Our configuration; 83 * Function to call with updated message queue object.
240 */ 84 */
241static const struct GNUNET_CONFIGURATION_Handle *cfg; 85 GCP_MessageQueueNotificationCallback cb;
242 86
243/** 87 /**
244 * Handle to communicate with ATS. 88 * Closure for @e cb.
245 */ 89 */
246static struct GNUNET_ATS_ConnectivityHandle *ats_ch; 90 void *cb_cls;
247 91
248/** 92 /**
249 * Shutdown falg. 93 * The peer this is for.
250 */ 94 */
251static int in_shutdown; 95 struct CadetPeer *cp;
252 96
97 /**
98 * Envelope this manager would like to transmit once it is its turn.
99 */
100 struct GNUNET_MQ_Envelope *env;
253 101
254/******************************************************************************/ 102};
255/***************************** CORE HELPERS *********************************/
256/******************************************************************************/
257 103
258 104
259/** 105/**
260 * Iterator to notify all connections of a broken link. Mark connections 106 * Struct containing all information regarding a given peer
261 * to destroy after all traffic has been sent.
262 *
263 * @param cls Closure (disconnected peer).
264 * @param key Current key code (peer id).
265 * @param value Value in the hash map (connection).
266 *
267 * @return #GNUNET_YES to continue to iterate.
268 */ 107 */
269static int 108struct CadetPeer
270notify_broken (void *cls,
271 const struct GNUNET_ShortHashCode *key,
272 void *value)
273{ 109{
274 struct CadetPeer *peer = cls; 110 /**
275 struct CadetConnection *c = value; 111 * ID of the peer
112 */
113 struct GNUNET_PeerIdentity pid;
114
115 /**
116 * Last time we heard from this peer (currently not used!)
117 */
118 struct GNUNET_TIME_Absolute last_contactXXX;
119
120 /**
121 * Array of DLLs of paths traversing the peer, organized by the
122 * offset of the peer on the larger path.
123 */
124 struct CadetPeerPathEntry **path_heads;
125
126 /**
127 * Array of DLL of paths traversing the peer, organized by the
128 * offset of the peer on the larger path.
129 */
130 struct CadetPeerPathEntry **path_tails;
131
132 /**
133 * Notifications to call when @e core_mq changes.
134 */
135 struct GCP_MessageQueueManager *mqm_head;
136
137 /**
138 * Notifications to call when @e core_mq changes.
139 */
140 struct GCP_MessageQueueManager *mqm_tail;
141
142 /**
143 * Pointer to first "ready" entry in @e mqm_head.
144 */
145 struct GCP_MessageQueueManager *mqm_ready_ptr;
146
147 /**
148 * MIN-heap of paths owned by this peer (they also end at this
149 * peer). Ordered by desirability.
150 */
151 struct GNUNET_CONTAINER_Heap *path_heap;
152
153 /**
154 * Handle to stop the DHT search for paths to this peer
155 */
156 struct GCD_search_handle *search_h;
157
158 /**
159 * Task to clean up @e path_heap asynchronously.
160 */
161 struct GNUNET_SCHEDULER_Task *heap_cleanup_task;
162
163 /**
164 * Task to destroy this entry.
165 */
166 struct GNUNET_SCHEDULER_Task *destroy_task;
167
168 /**
169 * Tunnel to this peer, if any.
170 */
171 struct CadetTunnel *t;
172
173 /**
174 * Connections that go through this peer; indexed by tid.
175 */
176 struct GNUNET_CONTAINER_MultiShortmap *connections;
177
178 /**
179 * Handle for core transmissions.
180 */
181 struct GNUNET_MQ_Handle *core_mq;
182
183 /**
184 * Hello message of the peer.
185 */
186 struct GNUNET_HELLO_Message *hello;
187
188 /**
189 * Handle to us offering the HELLO to the transport.
190 */
191 struct GNUNET_TRANSPORT_OfferHelloHandle *hello_offer;
192
193 /**
194 * Handle to our ATS request asking ATS to suggest an address
195 * to TRANSPORT for this peer (to establish a direct link).
196 */
197 struct GNUNET_ATS_ConnectivitySuggestHandle *connectivity_suggestion;
198
199 /**
200 * How many messages are in the queue to this peer.
201 */
202 unsigned int queue_n;
203
204 /**
205 * How many paths do we have to this peer (in all @e path_heads DLLs combined).
206 */
207 unsigned int num_paths;
208
209 /**
210 * Sum over all of the offsets of all of the paths in the @a path_heads DLLs.
211 * Used to speed-up @GCP_get_desirability_of_path() calculation.
212 */
213 unsigned int off_sum;
214
215 /**
216 * Number of message queue managers of this peer that have a message in waiting.
217 *
218 * Used to quickly see if we need to bother scanning the @e msm_head DLL.
219 * TODO: could be replaced by another DLL that would then allow us to avoid
220 * the O(n)-scan of the DLL for ready entries!
221 */
222 unsigned int mqm_ready_counter;
223
224 /**
225 * Current length of the @e path_heads and @path_tails arrays.
226 * The arrays should be grown as needed.
227 */
228 unsigned int path_dll_length;
276 229
277 LOG (GNUNET_ERROR_TYPE_DEBUG, 230};
278 "Notifying %s due to %s disconnect\n",
279 GCC_2s (c), GCP_2s (peer));
280 GCC_neighbor_disconnected (c, peer);
281 return GNUNET_YES;
282}
283 231
284 232
285/** 233/**
286 * Remove the direct path to the peer. 234 * Get the static string for a peer ID.
287 *
288 * @param peer Peer to remove the direct path from.
289 */
290static struct CadetPeerPath *
291pop_direct_path (struct CadetPeer *peer)
292{
293 struct CadetPeerPath *iter;
294
295 for (iter = peer->path_head; NULL != iter; iter = iter->next)
296 {
297 if (2 >= iter->length)
298 {
299 GNUNET_CONTAINER_DLL_remove (peer->path_head,
300 peer->path_tail,
301 iter);
302 return iter;
303 }
304 }
305 return NULL;
306}
307
308/**
309 * Call the continuation after a message has been sent or dropped.
310 *
311 * This funcion removes the message from the queue.
312 * 235 *
313 * @param q Queue handle. 236 * @param cp Peer.
314 * @param sent #GNUNET_YES if was sent to CORE, #GNUNET_NO if dropped. 237 * @return Static string for it's ID.
315 */ 238 */
316static void 239const char *
317call_peer_cont (struct CadetPeerQueue *q, int sent); 240GCP_2s (const struct CadetPeer *cp)
241{
242 static char buf[32];
243
244 GNUNET_snprintf (buf,
245 sizeof (buf),
246 "P(%s)",
247 GNUNET_i2s (&cp->pid));
248 return buf;
249}
250
251
252/**
253 * Calculate how desirable a path is for @a cp if @a cp
254 * is at offset @a off.
255 *
256 * The 'desirability_table.c' program can be used to compute a list of
257 * sample outputs for different scenarios. Basically, we score paths
258 * lower if there are many alternatives, and higher if they are
259 * shorter than average, and very high if they are much shorter than
260 * average and without many alternatives.
261 *
262 * @param cp a peer reachable via a path
263 * @param off offset of @a cp in the path
264 * @return score how useful a path is to reach @a cp,
265 * positive scores mean path is more desirable
266 */
267double
268GCP_get_desirability_of_path (struct CadetPeer *cp,
269 unsigned int off)
270{
271 unsigned int num_alts = cp->num_paths;
272 unsigned int off_sum;
273 double avg_sum;
274 double path_delta;
275 double weight_alts;
276
277 GNUNET_assert (num_alts >= 1); /* 'path' should be in there! */
278 GNUNET_assert (0 != cp->path_dll_length);
279
280 /* We maintain 'off_sum' in 'peer' and thereby
281 avoid the SLOW recalculation each time. Kept here
282 just to document what is going on. */
283#if SLOW
284 off_sum = 0;
285 for (unsigned int j=0;j<cp->path_dll_length;j++)
286 for (struct CadetPeerPathEntry *pe = cp->path_heads[j];
287 NULL != pe;
288 pe = pe->next)
289 off_sum += j;
290 GNUNET_assert (off_sum == cp->off_sum);
291#else
292 off_sum = cp->off_sum;
293#endif
294 avg_sum = off_sum * 1.0 / cp->path_dll_length;
295 path_delta = off - avg_sum;
296 /* path_delta positiv: path off of peer above average (bad path for peer),
297 path_delta negativ: path off of peer below average (good path for peer) */
298 if (path_delta <= - 1.0)
299 weight_alts = - num_alts / path_delta; /* discount alternative paths */
300 else if (path_delta >= 1.0)
301 weight_alts = num_alts * path_delta; /* overcount alternative paths */
302 else
303 weight_alts = num_alts; /* count alternative paths normally */
318 304
319 305
320/******************************************************************************/ 306 /* off+1: long paths are generally harder to find and thus count
321/***************************** CORE CALLBACKS *********************************/ 307 a bit more as they get longer. However, above-average paths
322/******************************************************************************/ 308 still need to count less, hence the squaring of that factor. */
309 return (off + 1.0) / (weight_alts * weight_alts);
310}
323 311
324 312
325/** 313/**
326 * Method called whenever a given peer connects. 314 * This peer is no longer be needed, clean it up now.
327 * 315 *
328 * @param cls Core closure (unused). 316 * @param cls peer to clean up
329 * @param peer Peer identity this notification is about
330 * @param mq Message Queue to this peer.
331 *
332 * @return Internal closure for handlers (CadetPeer struct).
333 */ 317 */
334static void * 318static void
335core_connect_handler (void *cls, 319destroy_peer (void *cls)
336 const struct GNUNET_PeerIdentity *peer, 320{
337 struct GNUNET_MQ_Handle *mq) 321 struct CadetPeer *cp = cls;
338{ 322
339 struct CadetPeer *neighbor; 323 LOG (GNUNET_ERROR_TYPE_DEBUG,
340 struct CadetPeerPath *path; 324 "Destroying state about peer %s\n",
341 char own_id[16]; 325 GCP_2s (cp));
342 326 cp->destroy_task = NULL;
343 GCC_check_connections (); 327 GNUNET_assert (NULL == cp->t);
344 GNUNET_snprintf (own_id, 328 GNUNET_assert (NULL == cp->core_mq);
345 sizeof (own_id), 329 GNUNET_assert (0 == cp->num_paths);
346 "%s", 330 for (unsigned int i=0;i<cp->path_dll_length;i++)
347 GNUNET_i2s (&my_full_id)); 331 GNUNET_assert (NULL == cp->path_heads[i]);
348 332 GNUNET_assert (0 == GNUNET_CONTAINER_multishortmap_size (cp->connections));
349 /* Save a path to the neighbor */ 333 GNUNET_assert (GNUNET_YES ==
350 neighbor = GCP_get (peer, GNUNET_YES); 334 GNUNET_CONTAINER_multipeermap_remove (peers,
351 if (myid == neighbor->id) 335 &cp->pid,
352 { 336 cp));
353 LOG (GNUNET_ERROR_TYPE_INFO, 337 GNUNET_free_non_null (cp->path_heads);
354 "CONNECTED %s (self)\n", 338 GNUNET_free_non_null (cp->path_tails);
355 own_id); 339 cp->path_dll_length = 0;
356 path = path_new (1); 340 if (NULL != cp->search_h)
357 } 341 {
358 else 342 GCD_search_stop (cp->search_h);
359 { 343 cp->search_h = NULL;
360 LOG (GNUNET_ERROR_TYPE_INFO, 344 }
361 "CONNECTED %s <= %s\n", 345 /* FIXME: clean up search_delayedXXX! */
362 own_id,
363 GNUNET_i2s (peer));
364 path = path_new (2);
365 path->peers[1] = neighbor->id;
366 GNUNET_PEER_change_rc (neighbor->id, 1);
367 GNUNET_assert (NULL == neighbor->core_mq);
368 neighbor->core_mq = mq;
369 }
370 path->peers[0] = myid;
371 GNUNET_PEER_change_rc (myid, 1);
372 GCP_add_path (neighbor, path, GNUNET_YES);
373
374 /* Create the connections hashmap */
375 GNUNET_assert (NULL == neighbor->connections);
376 neighbor->connections = GNUNET_CONTAINER_multishortmap_create (16,
377 GNUNET_YES);
378 GNUNET_STATISTICS_update (stats,
379 "# peers",
380 1,
381 GNUNET_NO);
382
383 if ( (NULL != GCP_get_tunnel (neighbor)) &&
384 (0 > GNUNET_CRYPTO_cmp_peer_identity (&my_full_id, peer)) )
385 {
386 GCP_connect (neighbor);
387 }
388 GCC_check_connections ();
389 346
390 return neighbor; 347 if (NULL != cp->hello_offer)
348 {
349 GNUNET_TRANSPORT_offer_hello_cancel (cp->hello_offer);
350 cp->hello_offer = NULL;
351 }
352 if (NULL != cp->connectivity_suggestion)
353 {
354 GNUNET_ATS_connectivity_suggest_cancel (cp->connectivity_suggestion);
355 cp->connectivity_suggestion = NULL;
356 }
357 GNUNET_CONTAINER_multishortmap_destroy (cp->connections);
358 if (NULL != cp->path_heap)
359 {
360 GNUNET_CONTAINER_heap_destroy (cp->path_heap);
361 cp->path_heap = NULL;
362 }
363 if (NULL != cp->heap_cleanup_task)
364 {
365 GNUNET_SCHEDULER_cancel (cp->heap_cleanup_task);
366 cp->heap_cleanup_task = NULL;
367 }
368 GNUNET_free_non_null (cp->hello);
369 /* Peer should not be freed if paths exist; if there are no paths,
370 there ought to be no connections, and without connections, no
371 notifications. Thus we can assert that mqm_head is empty at this
372 point. */
373 GNUNET_assert (NULL == cp->mqm_head);
374 GNUNET_assert (NULL == cp->mqm_ready_ptr);
375 GNUNET_free (cp);
391} 376}
392 377
393 378
394/** 379/**
395 * Method called whenever a peer disconnects. 380 * This peer is now on more "active" duty, activate processes related to it.
396 * 381 *
397 * @param cls Core closure (unused). 382 * @param cp the more-active peer
398 * @param peer Peer identity this notification is about.
399 * @param internal_cls Internal closure (CadetPeer struct).
400 */ 383 */
401static void 384static void
402core_disconnect_handler (void *cls, 385consider_peer_activate (struct CadetPeer *cp)
403 const struct GNUNET_PeerIdentity *peer,
404 void *internal_cls)
405{ 386{
406 struct CadetPeer *p = internal_cls; 387 uint32_t strength;
407 struct CadetPeerPath *direct_path; 388
408 char own_id[16]; 389 LOG (GNUNET_ERROR_TYPE_DEBUG,
409 390 "Updating peer %s activation state (%u connections)%s%s\n",
410 GCC_check_connections (); 391 GCP_2s (cp),
411 strncpy (own_id, GNUNET_i2s (&my_full_id), 16); 392 GNUNET_CONTAINER_multishortmap_size (cp->connections),
412 own_id[15] = '\0'; 393 (NULL == cp->t) ? "" : " with tunnel",
413 if (myid == p->id) 394 (NULL == cp->core_mq) ? "" : " with CORE link");
414 { 395 if (NULL != cp->destroy_task)
415 LOG (GNUNET_ERROR_TYPE_INFO, 396 {
416 "DISCONNECTED %s (self)\n", 397 /* It's active, do not destory! */
417 own_id); 398 GNUNET_SCHEDULER_cancel (cp->destroy_task);
418 } 399 cp->destroy_task = NULL;
419 else 400 }
401 if ( (0 == GNUNET_CONTAINER_multishortmap_size (cp->connections)) &&
402 (NULL == cp->t) )
403 {
404 /* We're just on a path or directly connected; don't bother too much */
405 if (NULL != cp->connectivity_suggestion)
420 { 406 {
421 LOG (GNUNET_ERROR_TYPE_INFO, 407 GNUNET_ATS_connectivity_suggest_cancel (cp->connectivity_suggestion);
422 "DISCONNECTED %s <= %s\n", 408 cp->connectivity_suggestion = NULL;
423 own_id, GNUNET_i2s (peer));
424 p->core_mq = NULL;
425 } 409 }
426 direct_path = pop_direct_path (p); 410 if (NULL != cp->search_h)
427 if (NULL != p->connections)
428 { 411 {
429 GNUNET_CONTAINER_multishortmap_iterate (p->connections, 412 GCD_search_stop (cp->search_h);
430 &notify_broken, 413 cp->search_h = NULL;
431 p);
432 GNUNET_CONTAINER_multishortmap_destroy (p->connections);
433 p->connections = NULL;
434 } 414 }
435 GNUNET_STATISTICS_update (stats, 415 return;
436 "# peers", 416 }
437 -1, 417 if (NULL == cp->core_mq)
438 GNUNET_NO); 418 {
439 path_destroy (direct_path); 419 /* Lacks direct connection, try to create one by querying the DHT */
440 GCC_check_connections (); 420 if ( (NULL == cp->search_h) &&
441} 421 (DESIRED_CONNECTIONS_PER_TUNNEL > cp->num_paths) )
442 422 cp->search_h
443 423 = GCD_search (&cp->pid);
444/******************************************************************************/ 424 }
445/******************************************************************************/ 425 else
446/******************************************************************************/ 426 {
447/******************************************************************************/ 427 /* Have direct connection, stop DHT search if active */
448/******************************************************************************/ 428 if (NULL != cp->search_h)
449
450/**
451 * Check if the create_connection message has the appropriate size.
452 *
453 * @param cls Closure (unused).
454 * @param msg Message to check.
455 *
456 * @return #GNUNET_YES if size is correct, #GNUNET_NO otherwise.
457 */
458static int
459check_create (void *cls, const struct GNUNET_CADET_ConnectionCreateMessage *msg)
460{
461 uint16_t size;
462
463 size = ntohs (msg->header.size);
464 if (size < sizeof (*msg))
465 { 429 {
466 GNUNET_break_op (0); 430 GCD_search_stop (cp->search_h);
467 return GNUNET_NO; 431 cp->search_h = NULL;
468 } 432 }
469 return GNUNET_YES; 433 }
470}
471
472/**
473 * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE
474 *
475 * @param cls Closure (CadetPeer for neighbor that sent the message).
476 * @param msg Message itself.
477 */
478static void
479handle_create (void *cls, const struct GNUNET_CADET_ConnectionCreateMessage *msg)
480{
481 struct CadetPeer *peer = cls;
482 GCC_handle_create (peer, msg);
483}
484
485
486/**
487 * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK
488 *
489 * @param cls Closure (CadetPeer for neighbor that sent the message).
490 * @param msg Message itself.
491 */
492static void
493handle_confirm (void *cls, const struct GNUNET_CADET_ConnectionCreateAckMessage *msg)
494{
495 struct CadetPeer *peer = cls;
496 GCC_handle_confirm (peer, msg);
497}
498
499 434
500/** 435 /* If we have a tunnel, our urge for connections is much bigger */
501 * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN 436 strength = (NULL != cp->t) ? 32 : 1;
502 * 437 if (NULL != cp->connectivity_suggestion)
503 * @param cls Closure (CadetPeer for neighbor that sent the message). 438 GNUNET_ATS_connectivity_suggest_cancel (cp->connectivity_suggestion);
504 * @param msg Message itself. 439 cp->connectivity_suggestion
505 */ 440 = GNUNET_ATS_connectivity_suggest (ats_ch,
506static void 441 &cp->pid,
507handle_broken (void *cls, const struct GNUNET_CADET_ConnectionBrokenMessage *msg) 442 strength);
508{
509 struct CadetPeer *peer = cls;
510 GCC_handle_broken (peer, msg);
511} 443}
512 444
513 445
514/** 446/**
515 * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY 447 * This peer may no longer be needed, consider cleaning it up.
516 * 448 *
517 * @param cls Closure (CadetPeer for neighbor that sent the message). 449 * @param cp peer to clean up
518 * @param msg Message itself.
519 */ 450 */
520static void 451static void
521handle_destroy (void *cls, const struct GNUNET_CADET_ConnectionDestroyMessage *msg) 452consider_peer_destroy (struct CadetPeer *cp);
522{
523 struct CadetPeer *peer = cls;
524 GCC_handle_destroy (peer, msg);
525}
526 453
527 454
528/** 455/**
529 * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_HOP_BY_HOP_ENCRYPTED_ACK 456 * We really no longere care about a peer, stop hogging memory with paths to it.
457 * Afterwards, see if there is more to be cleaned up about this peer.
530 * 458 *
531 * @param cls Closure (CadetPeer for neighbor that sent the message). 459 * @param cls a `struct CadetPeer`.
532 * @param msg Message itself.
533 */ 460 */
534static void 461static void
535handle_ack (void *cls, const struct GNUNET_CADET_ConnectionEncryptedAckMessage *msg) 462drop_paths (void *cls)
536{ 463{
537 struct CadetPeer *peer = cls; 464 struct CadetPeer *cp = cls;
538 GCC_handle_ack (peer, msg); 465 struct CadetPeerPath *path;
539}
540 466
541 467 cp->destroy_task = NULL;
542/** 468 while (NULL != (path = GNUNET_CONTAINER_heap_remove_root (cp->path_heap)))
543 * Handle for #GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED_POLL 469 GCPP_release (path);
544 * 470 consider_peer_destroy (cp);
545 * @param cls Closure (CadetPeer for neighbor that sent the message).
546 * @param msg Message itself.
547 */
548static void
549handle_poll (void *cls, const struct GNUNET_CADET_ConnectionHopByHopPollMessage *msg)
550{
551 struct CadetPeer *peer = cls;
552 GCC_handle_poll (peer, msg);
553} 471}
554 472
555 473
556/** 474/**
557 * Handle for #GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX 475 * This peer may no longer be needed, consider cleaning it up.
558 * 476 *
559 * @param cls Closure (CadetPeer for neighbor that sent the message). 477 * @param cp peer to clean up
560 * @param msg Message itself.
561 */ 478 */
562static void 479static void
563handle_kx (void *cls, const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg) 480consider_peer_destroy (struct CadetPeer *cp)
564{
565 struct CadetPeer *peer = cls;
566 GCC_handle_kx (peer, msg);
567}
568
569
570/**
571 * Check if the encrypted message has the appropriate size.
572 *
573 * @param cls Closure (unused).
574 * @param msg Message to check.
575 *
576 * @return #GNUNET_YES if size is correct, #GNUNET_NO otherwise.
577 */
578static int
579check_encrypted (void *cls, const struct GNUNET_CADET_TunnelEncryptedMessage *msg)
580{ 481{
581 uint16_t size; 482 struct GNUNET_TIME_Relative exp;
582 uint16_t minimum_size;
583
584 size = ntohs (msg->header.size);
585 minimum_size = sizeof (struct GNUNET_CADET_TunnelEncryptedMessage)
586 + sizeof (struct GNUNET_MessageHeader);
587
588 if (size < minimum_size)
589 {
590 GNUNET_break_op (0);
591 return GNUNET_NO;
592 }
593 return GNUNET_YES;
594}
595 483
596/** 484 if (NULL != cp->destroy_task)
597 * Handle for #GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED. 485 {
598 * 486 GNUNET_SCHEDULER_cancel (cp->destroy_task);
599 * @param cls Closure (CadetPeer for neighbor that sent the message). 487 cp->destroy_task = NULL;
600 * @param msg Message itself. 488 }
601 */ 489 if (NULL != cp->t)
602static void 490 return; /* still relevant! */
603handle_encrypted (void *cls, const struct GNUNET_CADET_TunnelEncryptedMessage *msg) 491 if (NULL != cp->core_mq)
604{ 492 return; /* still relevant! */
605 struct CadetPeer *peer = cls; 493 if (0 != GNUNET_CONTAINER_multishortmap_size (cp->connections))
606 GCC_handle_encrypted (peer, msg); 494 return; /* still relevant! */
607} 495 if ( (NULL != cp->path_heap) &&
608 496 (0 < GNUNET_CONTAINER_heap_get_size (cp->path_heap)) )
609 497 {
610/** 498 cp->destroy_task = GNUNET_SCHEDULER_add_delayed (IDLE_PATH_TIMEOUT,
611 * To be called on core init/fail. 499 &drop_paths,
612 * 500 cp);
613 * @param cls Closure (config) 501 return;
614 * @param identity The public identity of this peer. 502 }
615 */ 503 if (0 != cp->num_paths)
616static void 504 return; /* still relevant! */
617core_init_notify (void *cls, 505 if (NULL != cp->hello)
618 const struct GNUNET_PeerIdentity *identity); 506 {
619 507 /* relevant only until HELLO expires */
620 508 exp = GNUNET_TIME_absolute_get_remaining (GNUNET_HELLO_get_last_expiration (cp->hello));
621static void 509 cp->destroy_task = GNUNET_SCHEDULER_add_delayed (exp,
622connect_to_core (const struct GNUNET_CONFIGURATION_Handle *c) 510 &destroy_peer,
623{ 511 cp);
624 struct GNUNET_MQ_MessageHandler core_handlers[] = { 512 return;
625 GNUNET_MQ_hd_var_size (create, 513 }
626 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE, 514 cp->destroy_task = GNUNET_SCHEDULER_add_delayed (IDLE_PEER_TIMEOUT,
627 struct GNUNET_CADET_ConnectionCreateMessage, 515 &destroy_peer,
628 NULL), 516 cp);
629 GNUNET_MQ_hd_fixed_size (confirm,
630 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK,
631 struct GNUNET_CADET_ConnectionCreateAckMessage,
632 NULL),
633 GNUNET_MQ_hd_fixed_size (broken,
634 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN,
635 struct GNUNET_CADET_ConnectionBrokenMessage,
636 NULL),
637 GNUNET_MQ_hd_fixed_size (destroy,
638 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY,
639 struct GNUNET_CADET_ConnectionDestroyMessage,
640 NULL),
641 GNUNET_MQ_hd_fixed_size (ack,
642 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_HOP_BY_HOP_ENCRYPTED_ACK,
643 struct GNUNET_CADET_ConnectionEncryptedAckMessage,
644 NULL),
645 GNUNET_MQ_hd_fixed_size (poll,
646 GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED_POLL,
647 struct GNUNET_CADET_ConnectionHopByHopPollMessage,
648 NULL),
649 GNUNET_MQ_hd_fixed_size (kx,
650 GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX,
651 struct GNUNET_CADET_TunnelKeyExchangeMessage,
652 NULL),
653 GNUNET_MQ_hd_var_size (encrypted,
654 GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED,
655 struct GNUNET_CADET_TunnelEncryptedMessage,
656 NULL),
657 GNUNET_MQ_handler_end ()
658 };
659 core_handle = GNUNET_CORE_connect (c, NULL,
660 &core_init_notify,
661 &core_connect_handler,
662 &core_disconnect_handler,
663 core_handlers);
664}
665
666/******************************************************************************/
667/******************************************************************************/
668/******************************************************************************/
669/******************************************************************************/
670/******************************************************************************/
671
672/**
673 * To be called on core init/fail.
674 *
675 * @param cls Closure (config)
676 * @param identity The public identity of this peer.
677 */
678static void
679core_init_notify (void *cls,
680 const struct GNUNET_PeerIdentity *core_identity)
681{
682 const struct GNUNET_CONFIGURATION_Handle *c = cls;
683
684 LOG (GNUNET_ERROR_TYPE_DEBUG, "Core init\n");
685 if (0 != memcmp (core_identity, &my_full_id, sizeof (my_full_id)))
686 {
687 LOG (GNUNET_ERROR_TYPE_ERROR, _("Wrong CORE service\n"));
688 LOG (GNUNET_ERROR_TYPE_ERROR, " core id %s\n", GNUNET_i2s (core_identity));
689 LOG (GNUNET_ERROR_TYPE_ERROR, " my id %s\n", GNUNET_i2s (&my_full_id));
690 GNUNET_CORE_disconnect (core_handle);
691 connect_to_core (c);
692 return;
693 }
694 GML_start ();
695} 517}
696 518
697 519
698/******************************************************************************/
699/******************************** STATIC ***********************************/
700/******************************************************************************/
701
702
703/** 520/**
704 * Get priority for a queued message. 521 * Set the message queue to @a mq for peer @a cp and notify watchers.
705 *
706 * @param q Queued message
707 *
708 * @return CORE priority to use.
709 * 522 *
710 * FIXME make static 523 * @param cp peer to modify
711 * FIXME use when sending 524 * @param mq message queue to set (can be NULL)
712 */ 525 */
713enum GNUNET_CORE_Priority 526void
714get_priority (struct CadetPeerQueue *q) 527GCP_set_mq (struct CadetPeer *cp,
715{ 528 struct GNUNET_MQ_Handle *mq)
716 enum GNUNET_CORE_Priority low; 529{
717 enum GNUNET_CORE_Priority high; 530 LOG (GNUNET_ERROR_TYPE_DEBUG,
718 531 "Message queue for peer %s is now %p\n",
719 if (NULL == q) 532 GCP_2s (cp),
720 { 533 mq);
721 GNUNET_break (0); 534 cp->core_mq = mq;
722 return GNUNET_CORE_PRIO_BACKGROUND; 535 for (struct GCP_MessageQueueManager *mqm = cp->mqm_head, *next;
723 } 536 NULL != mqm;
724 537 mqm = next)
725 /* Relayed traffic has lower priority, our own traffic has higher */ 538 {
726 if (NULL == q->c || GNUNET_NO == GCC_is_origin (q->c, q->c_fwd)) 539 /* Save next pointer in case mqm gets freed by the callback */
540 next = mqm->next;
541 if (NULL == mq)
727 { 542 {
728 low = GNUNET_CORE_PRIO_BEST_EFFORT; 543 if (NULL != mqm->env)
729 high = GNUNET_CORE_PRIO_URGENT; 544 {
545 GNUNET_MQ_discard (mqm->env);
546 mqm->env = NULL;
547 mqm->cb (mqm->cb_cls,
548 GNUNET_SYSERR);
549 }
550 else
551 {
552 mqm->cb (mqm->cb_cls,
553 GNUNET_NO);
554 }
730 } 555 }
731 else 556 else
732 { 557 {
733 low = GNUNET_CORE_PRIO_URGENT; 558 GNUNET_assert (NULL == mqm->env);
734 high = GNUNET_CORE_PRIO_CRITICAL_CONTROL; 559 mqm->cb (mqm->cb_cls,
560 GNUNET_YES);
735 } 561 }
562 }
563 if ( (NULL != mq) ||
564 (NULL != cp->t) )
565 consider_peer_activate (cp);
566 else
567 consider_peer_destroy (cp);
736 568
737 /* Bulky payload has lower priority, control traffic has higher. */ 569 if ( (NULL != mq) &&
738 if (GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED == q->type) 570 (NULL != cp->t) )
739 return low; 571 {
740 return high; 572 /* have a new, direct path to the target, notify tunnel */
741} 573 struct CadetPeerPath *path;
742
743
744/**
745 * Cancel all messages queued to CORE MQ towards this peer.
746 *
747 * @param peer Peer towards which to cancel all messages.
748 */
749static void
750cancel_queued_messages (struct CadetPeer *peer)
751{
752 while (NULL != peer->q_head)
753 {
754 struct CadetPeerQueue *q;
755
756 q = peer->q_head;
757 call_peer_cont (q, GNUNET_NO);
758 GNUNET_free (q);
759 }
760}
761
762
763/**
764 * Destroy the peer_info and free any allocated resources linked to it
765 *
766 * @param peer The peer_info to destroy.
767 * @return #GNUNET_OK on success
768 */
769static int
770peer_destroy (struct CadetPeer *peer)
771{
772 struct GNUNET_PeerIdentity id;
773 struct CadetPeerPath *p;
774 struct CadetPeerPath *nextp;
775
776 GNUNET_PEER_resolve (peer->id, &id);
777 GNUNET_PEER_change_rc (peer->id, -1);
778
779 LOG (GNUNET_ERROR_TYPE_INFO,
780 "destroying peer %s\n",
781 GNUNET_i2s (&id));
782
783 if (GNUNET_YES !=
784 GNUNET_CONTAINER_multipeermap_remove (peers, &id, peer))
785 {
786 GNUNET_break (0);
787 LOG (GNUNET_ERROR_TYPE_WARNING, " peer not in peermap!!\n");
788 }
789 GCP_stop_search (peer);
790 p = peer->path_head;
791 while (NULL != p)
792 {
793 nextp = p->next;
794 GNUNET_CONTAINER_DLL_remove (peer->path_head,
795 peer->path_tail,
796 p);
797 path_destroy (p);
798 p = nextp;
799 }
800 if (NULL != peer->tunnel)
801 GCT_destroy_empty (peer->tunnel);
802 if (NULL != peer->connections)
803 {
804 GNUNET_assert (0 == GNUNET_CONTAINER_multishortmap_size (peer->connections));
805 GNUNET_CONTAINER_multishortmap_destroy (peer->connections);
806 peer->connections = NULL;
807 }
808 if (NULL != peer->hello_offer)
809 {
810 GNUNET_TRANSPORT_offer_hello_cancel (peer->hello_offer);
811 peer->hello_offer = NULL;
812 }
813 if (NULL != peer->connectivity_suggestion)
814 {
815 GNUNET_ATS_connectivity_suggest_cancel (peer->connectivity_suggestion);
816 peer->connectivity_suggestion = NULL;
817 }
818 cancel_queued_messages (peer);
819 574
820 GNUNET_free_non_null (peer->hello); 575 path = GCPP_get_path_from_route (1,
821 GNUNET_free (peer); 576 &cp->pid);
822 return GNUNET_OK; 577 GCT_consider_path (cp->t,
578 path,
579 0);
580 }
823} 581}
824 582
825 583
826/** 584/**
827 * Iterator over peer hash map entries to destroy the peer during in_shutdown. 585 * Debug function should NEVER return true in production code, useful to
586 * simulate losses for testcases.
828 * 587 *
829 * @param cls closure 588 * @return #GNUNET_YES or #GNUNET_NO with the decision to drop.
830 * @param key current key code
831 * @param value value in the hash map
832 * @return #GNUNET_YES if we should continue to iterate,
833 * #GNUNET_NO if not.
834 */ 589 */
835static int 590static int
836shutdown_peer (void *cls, 591should_I_drop (void)
837 const struct GNUNET_PeerIdentity *key,
838 void *value)
839{ 592{
840 struct CadetPeer *p = value; 593 if (0 == drop_percent)
841 struct CadetTunnel *t = p->tunnel; 594 return GNUNET_NO;
842 595 if (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
843 LOG (GNUNET_ERROR_TYPE_DEBUG, " shutting down %s\n", GCP_2s (p)); 596 101) < drop_percent)
844 if (NULL != t)
845 GCT_destroy (t);
846 p->tunnel = NULL;
847 peer_destroy (p);
848 return GNUNET_YES; 597 return GNUNET_YES;
598 return GNUNET_NO;
849} 599}
850 600
851 601
852/** 602/**
853 * Check if peer is searching for a path (either active or delayed search). 603 * Function called when CORE took one of the messages from
854 * 604 * a message queue manager and transmitted it.
855 * @param peer Peer to check
856 * @return #GNUNET_YES if there is a search active.
857 * #GNUNET_NO otherwise.
858 */
859static int
860is_searching (const struct CadetPeer *peer)
861{
862 return ( (NULL == peer->search_h) &&
863 (NULL == peer->search_delayed) ) ?
864 GNUNET_NO : GNUNET_YES;
865}
866
867
868/**
869 * @brief Start a search for a peer.
870 * 605 *
871 * @param cls Closure (Peer to search for). 606 * @param cls the `struct CadetPeeer` where we made progress
872 */ 607 */
873static void 608static void
874delayed_search (void *cls) 609mqm_send_done (void *cls);
875{
876 struct CadetPeer *peer = cls;
877
878 peer->search_delayed = NULL;
879 GCC_check_connections ();
880 GCP_start_search (peer);
881 GCC_check_connections ();
882}
883 610
884 611
885/** 612/**
886 * Returns if peer is used (has a tunnel or is neighbor). 613 * Transmit current envelope from this @a mqm.
887 * 614 *
888 * @param peer Peer to check. 615 * @param mqm mqm to transmit message for now
889 * @return #GNUNET_YES if peer is in use.
890 */ 616 */
891static int 617static void
892peer_is_used (struct CadetPeer *peer) 618mqm_execute (struct GCP_MessageQueueManager *mqm)
893{
894 struct CadetPeerPath *p;
895
896 if (NULL != peer->tunnel)
897 return GNUNET_YES;
898
899 for (p = peer->path_head; NULL != p; p = p->next)
900 {
901 if (p->length < 3)
902 return GNUNET_YES;
903 }
904 return GNUNET_NO;
905}
906
907
908/**
909 * Iterator over all the peers to get the oldest timestamp.
910 *
911 * @param cls Closure (unsued).
912 * @param key ID of the peer.
913 * @param value Peer_Info of the peer.
914 */
915static int
916peer_get_oldest (void *cls,
917 const struct GNUNET_PeerIdentity *key,
918 void *value)
919{ 619{
920 struct CadetPeer *p = value; 620 struct CadetPeer *cp = mqm->cp;
921 struct GNUNET_TIME_Absolute *abs = cls;
922
923 /* Don't count active peers */
924 if (GNUNET_YES == peer_is_used (p))
925 return GNUNET_YES;
926 621
927 if (abs->abs_value_us < p->last_contact.abs_value_us) 622 /* Move ready pointer to the next entry that might be ready. */
928 abs->abs_value_us = p->last_contact.abs_value_us; 623 if ( (mqm == cp->mqm_ready_ptr) &&
929 624 (NULL != mqm->next) )
930 return GNUNET_YES; 625 cp->mqm_ready_ptr = mqm->next;
626 /* Move entry to the end of the DLL, to be fair. */
627 if (mqm != cp->mqm_tail)
628 {
629 GNUNET_CONTAINER_DLL_remove (cp->mqm_head,
630 cp->mqm_tail,
631 mqm);
632 GNUNET_CONTAINER_DLL_insert_tail (cp->mqm_head,
633 cp->mqm_tail,
634 mqm);
635 }
636 cp->mqm_ready_counter--;
637 if (GNUNET_YES == should_I_drop ())
638 {
639 LOG (GNUNET_ERROR_TYPE_DEBUG,
640 "DROPPING message to peer %s from MQM %p\n",
641 GCP_2s (cp),
642 mqm);
643 GNUNET_MQ_discard (mqm->env);
644 mqm->env = NULL;
645 mqm_send_done (cp);
646 }
647 else
648 {
649 LOG (GNUNET_ERROR_TYPE_DEBUG,
650 "Sending to peer %s from MQM %p\n",
651 GCP_2s (cp),
652 mqm);
653 GNUNET_MQ_send (cp->core_mq,
654 mqm->env);
655 mqm->env = NULL;
656 }
657 mqm->cb (mqm->cb_cls,
658 GNUNET_YES);
931} 659}
932 660
933 661
934/** 662/**
935 * Iterator over all the peers to remove the oldest entry. 663 * Find the next ready message in the queue (starting
664 * the search from the `cp->mqm_ready_ptr`) and if possible
665 * execute the transmission.
936 * 666 *
937 * @param cls Closure (unsued). 667 * @param cp peer to try to send the next ready message to
938 * @param key ID of the peer.
939 * @param value Peer_Info of the peer.
940 */
941static int
942peer_timeout (void *cls,
943 const struct GNUNET_PeerIdentity *key,
944 void *value)
945{
946 struct CadetPeer *p = value;
947 struct GNUNET_TIME_Absolute *abs = cls;
948
949 LOG (GNUNET_ERROR_TYPE_WARNING,
950 "peer %s timeout\n", GNUNET_i2s (key));
951
952 if (p->last_contact.abs_value_us == abs->abs_value_us &&
953 GNUNET_NO == peer_is_used (p))
954 {
955 peer_destroy (p);
956 return GNUNET_NO;
957 }
958 return GNUNET_YES;
959}
960
961
962/**
963 * Delete oldest unused peer.
964 */ 668 */
965static void 669static void
966peer_delete_oldest (void) 670send_next_ready (struct CadetPeer *cp)
967{ 671{
968 struct GNUNET_TIME_Absolute abs; 672 struct GCP_MessageQueueManager *mqm;
969
970 abs = GNUNET_TIME_UNIT_FOREVER_ABS;
971
972 GNUNET_CONTAINER_multipeermap_iterate (peers,
973 &peer_get_oldest,
974 &abs);
975 GNUNET_CONTAINER_multipeermap_iterate (peers,
976 &peer_timeout,
977 &abs);
978}
979
980 673
981/** 674 if (0 == cp->mqm_ready_counter)
982 * Choose the best (yet unused) path towards a peer, 675 return;
983 * considering the tunnel properties. 676 while ( (NULL != (mqm = cp->mqm_ready_ptr)) &&
984 * 677 (NULL == mqm->env) )
985 * @param peer The destination peer. 678 cp->mqm_ready_ptr = mqm->next;
986 * @return Best current known path towards the peer, if any. 679 if (NULL == mqm)
987 */ 680 return; /* nothing to do */
988static struct CadetPeerPath * 681 mqm_execute (mqm);
989peer_get_best_path (const struct CadetPeer *peer)
990{
991 struct CadetPeerPath *best_p;
992 struct CadetPeerPath *p;
993 unsigned int best_cost;
994 unsigned int cost;
995
996 best_cost = UINT_MAX;
997 best_p = NULL;
998 for (p = peer->path_head; NULL != p; p = p->next)
999 {
1000 if (GNUNET_NO == path_is_valid (p))
1001 continue; /* Don't use invalid paths. */
1002 if (GNUNET_YES == GCT_is_path_used (peer->tunnel, p))
1003 continue; /* If path is already in use, skip it. */
1004
1005 if ((cost = GCT_get_path_cost (peer->tunnel, p)) < best_cost)
1006 {
1007 best_cost = cost;
1008 best_p = p;
1009 }
1010 }
1011 return best_p;
1012} 682}
1013 683
1014 684
1015/** 685/**
1016 * Function to process paths received for a new peer addition. The recorded 686 * Function called when CORE took one of the messages from
1017 * paths form the initial tunnel, which can be optimized later. 687 * a message queue manager and transmitted it.
1018 * Called on each result obtained for the DHT search.
1019 * 688 *
1020 * @param cls Closure (peer towards a path has been found). 689 * @param cls the `struct CadetPeeer` where we made progress
1021 * @param path Path created from the DHT query. Will be freed afterwards.
1022 */ 690 */
1023static void 691static void
1024search_handler (void *cls, const struct CadetPeerPath *path) 692mqm_send_done (void *cls)
1025{ 693{
1026 struct CadetPeer *peer = cls; 694 struct CadetPeer *cp = cls;
1027 unsigned int connection_count;
1028
1029 GCC_check_connections ();
1030 GCP_add_path_to_all (path, GNUNET_NO);
1031
1032 /* Count connections */
1033 connection_count = GCT_count_connections (peer->tunnel);
1034 695
1035 /* If we already have our minimum (or more) connections, it's enough */ 696 LOG (GNUNET_ERROR_TYPE_DEBUG,
1036 if (CONNECTIONS_PER_TUNNEL <= connection_count) 697 "Sending to peer %s completed\n",
1037 { 698 GCP_2s (cp));
1038 GCC_check_connections (); 699 send_next_ready (cp);
1039 return;
1040 }
1041
1042 if (CADET_TUNNEL_SEARCHING == GCT_get_cstate (peer->tunnel))
1043 {
1044 LOG (GNUNET_ERROR_TYPE_DEBUG, " ... connect!\n");
1045 GCP_connect (peer);
1046 }
1047 GCC_check_connections ();
1048}
1049
1050
1051/**
1052 * Test if a message type is connection management traffic
1053 * or regular payload traffic.
1054 *
1055 * @param type Message type.
1056 *
1057 * @return #GNUNET_YES if connection management, #GNUNET_NO otherwise.
1058 */
1059static int
1060is_connection_management (uint16_t type)
1061{
1062 return type == GNUNET_MESSAGE_TYPE_CADET_CONNECTION_HOP_BY_HOP_ENCRYPTED_ACK ||
1063 type == GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED_POLL;
1064} 700}
1065 701
1066 702
1067/** 703/**
1068 * Debug function should NEVER return true in production code, useful to 704 * Send the message in @a env to @a cp.
1069 * simulate losses for testcases.
1070 * 705 *
1071 * @return #GNUNET_YES or #GNUNET_NO with the decision to drop. 706 * @param mqm the message queue manager to use for transmission
707 * @param env envelope with the message to send; must NOT
708 * yet have a #GNUNET_MQ_notify_sent() callback attached to it
1072 */ 709 */
1073static int 710void
1074should_I_drop (void) 711GCP_send (struct GCP_MessageQueueManager *mqm,
712 struct GNUNET_MQ_Envelope *env)
1075{ 713{
1076 if (0 == drop_percent) 714 struct CadetPeer *cp = mqm->cp;
1077 return GNUNET_NO;
1078 715
1079 if (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 101) < drop_percent) 716 GNUNET_assert (NULL != env);
1080 return GNUNET_YES; 717 LOG (GNUNET_ERROR_TYPE_DEBUG,
1081 718 "Queueing message to peer %s in MQM %p\n",
1082 return GNUNET_NO; 719 GCP_2s (cp),
720 mqm);
721 GNUNET_assert (NULL != cp->core_mq);
722 GNUNET_assert (NULL == mqm->env);
723 GNUNET_MQ_notify_sent (env,
724 &mqm_send_done,
725 cp);
726 mqm->env = env;
727 cp->mqm_ready_counter++;
728 if (mqm != cp->mqm_ready_ptr)
729 cp->mqm_ready_ptr = cp->mqm_head;
730 if (1 == cp->mqm_ready_counter)
731 cp->mqm_ready_ptr = mqm;
732 if (0 != GNUNET_MQ_get_length (cp->core_mq))
733 return;
734 send_next_ready (cp);
1083} 735}
1084 736
1085 737
1086/******************************************************************************/
1087/******************************** API ***********************************/
1088/******************************************************************************/
1089
1090/** 738/**
1091 * Call the continuation after a message has been sent or dropped. 739 * Function called to destroy a peer now.
1092 * 740 *
1093 * This funcion removes the message from the queue. 741 * @param cls NULL
1094 * 742 * @param pid identity of the peer (unused)
1095 * @param q Queue handle. 743 * @param value the `struct CadetPeer` to clean up
1096 * @param sent #GNUNET_YES if was sent to CORE, #GNUNET_NO if dropped. 744 * @return #GNUNET_OK (continue to iterate)
1097 */ 745 */
1098static void 746static int
1099call_peer_cont (struct CadetPeerQueue *q, int sent) 747destroy_iterator_cb (void *cls,
1100{ 748 const struct GNUNET_PeerIdentity *pid,
1101 LOG (GNUNET_ERROR_TYPE_DEBUG, " core mq just sent %s\n", GC_m2s (q->type)); 749 void *value)
1102 if (NULL != q->cont)
1103 {
1104 struct GNUNET_TIME_Relative wait_time;
1105
1106 wait_time = GNUNET_TIME_absolute_get_duration (q->queue_timestamp);
1107 LOG (GNUNET_ERROR_TYPE_DEBUG,
1108 " calling callback on %s after %s\n",
1109 GCC_2s (q->c),
1110 GNUNET_STRINGS_relative_time_to_string (wait_time, GNUNET_NO));
1111 q->cont (q->cont_cls,
1112 q->c, q->c_fwd, sent,
1113 q->type,
1114 q->payload_type,
1115 q->payload_id,
1116 q->size, wait_time);
1117 q->cont = NULL;
1118 }
1119 GNUNET_CONTAINER_DLL_remove (q->peer->q_head, q->peer->q_tail, q);
1120}
1121
1122
1123/**
1124 * Function called by MQ when a message is sent to CORE.
1125 *
1126 * @param cls Closure (queue handle).
1127 */
1128static void
1129mq_sent (void *cls)
1130{ 750{
1131 struct CadetPeerQueue *q = cls; 751 struct CadetPeer *cp = value;
1132 752
1133 if (GNUNET_NO == q->management_traffic) 753 if (NULL != cp->destroy_task)
1134 { 754 {
1135 q->peer->queue_n--; 755 GNUNET_SCHEDULER_cancel (cp->destroy_task);
1136 } 756 cp->destroy_task = NULL;
1137 call_peer_cont (q, GNUNET_YES); 757 }
1138 GNUNET_free (q); 758 destroy_peer (cp);
759 return GNUNET_OK;
1139} 760}
1140 761
1141 762
1142/** 763/**
1143 * Finish the drop operation. 764 * Clean up all entries about all peers.
1144 * 765 * Must only be called after all tunnels, CORE-connections and
1145 * @param cls queue entry to finish drop for 766 * connections are down.
1146 */ 767 */
1147static void 768void
1148drop_cb (void *cls) 769GCP_destroy_all_peers ()
1149{ 770{
1150 struct CadetPeerQueue *q = cls; 771 LOG (GNUNET_ERROR_TYPE_DEBUG,
1151 772 "Destroying all peers now\n");
1152 GNUNET_MQ_discard (q->env); 773 GNUNET_CONTAINER_multipeermap_iterate (peers,
1153 call_peer_cont (q, GNUNET_YES); 774 &destroy_iterator_cb,
1154 GNUNET_free (q); 775 NULL);
1155} 776}
1156 777
1157 778
1158/** 779/**
1159 * @brief Send a message to another peer (using CORE). 780 * Drop all paths owned by this peer, and do not
781 * allow new ones to be added: We are shutting down.
1160 * 782 *
1161 * @param peer Peer towards which to queue the message. 783 * @param cp peer to drop paths to
1162 * @param message Message to send.
1163 * @param payload_type Type of the message's payload, for debug messages.
1164 * 0 if the message is a retransmission (unknown payload).
1165 * UINT16_MAX if the message does not have payload.
1166 * @param payload_id ID of the payload (MID, ACK #, etc)
1167 * @param c Connection this message belongs to (can be NULL).
1168 * @param fwd Is this a message going root->dest? (FWD ACK are NOT FWD!)
1169 * @param cont Continuation to be called once CORE has sent the message.
1170 * @param cont_cls Closure for @c cont.
1171 *
1172 * @return A handle to the message in the queue or NULL (if dropped).
1173 */ 784 */
1174struct CadetPeerQueue * 785void
1175GCP_send (struct CadetPeer *peer, 786GCP_drop_owned_paths (struct CadetPeer *cp)
1176 const struct GNUNET_MessageHeader *message,
1177 uint16_t payload_type,
1178 struct CadetEncryptedMessageIdentifier payload_id,
1179 struct CadetConnection *c,
1180 int fwd,
1181 GCP_sent cont,
1182 void *cont_cls)
1183{ 787{
1184 struct CadetPeerQueue *q; 788 struct CadetPeerPath *path;
1185 uint16_t type;
1186 uint16_t size;
1187
1188 GCC_check_connections ();
1189 type = ntohs (message->type);
1190 size = ntohs (message->size);
1191 LOG (GNUNET_ERROR_TYPE_DEBUG,
1192 "que %s (%s %4u) on conn %s (%p) %s towards %s (size %u)\n",
1193 GC_m2s (type), GC_m2s (payload_type),
1194 ntohl (payload_id.pid),
1195 GCC_2s (c), c, GC_f2s (fwd), GCP_2s (peer), size);
1196
1197 if (NULL == peer->connections)
1198 {
1199 /* We are not connected to this peer, ignore request. */
1200 GNUNET_break (0);
1201 LOG (GNUNET_ERROR_TYPE_INFO, "%s not a neighbor\n", GCP_2s (peer));
1202 GNUNET_STATISTICS_update (stats, "# messages dropped due to wrong hop", 1,
1203 GNUNET_NO);
1204 return NULL;
1205 }
1206 789
1207 q = GNUNET_new (struct CadetPeerQueue); 790 LOG (GNUNET_ERROR_TYPE_DEBUG,
1208 q->env = GNUNET_MQ_msg_copy (message); 791 "Destroying all paths to %s\n",
1209 q->peer = peer; 792 GCP_2s (cp));
1210 q->cont = cont; 793 while (NULL != (path =
1211 q->cont_cls = cont_cls; 794 GNUNET_CONTAINER_heap_remove_root (cp->path_heap)))
1212 q->queue_timestamp = GNUNET_TIME_absolute_get (); 795 GCPP_release (path);
1213 q->management_traffic = is_connection_management (type); 796 GNUNET_CONTAINER_heap_destroy (cp->path_heap);
1214 q->type = type; 797 cp->path_heap = NULL;
1215 q->size = size;
1216 q->payload_type = payload_type;
1217 q->payload_id = payload_id;
1218 q->c = c;
1219 q->c_fwd = fwd;
1220 GNUNET_MQ_notify_sent (q->env, &mq_sent, q);
1221 GNUNET_CONTAINER_DLL_insert (peer->q_head, peer->q_tail, q);
1222
1223 if (GNUNET_YES == q->management_traffic)
1224 {
1225 GNUNET_MQ_send (peer->core_mq, q->env); // FIXME implement "_urgent", use
1226 }
1227 else
1228 {
1229 if (GNUNET_YES == should_I_drop ())
1230 {
1231 LOG (GNUNET_ERROR_TYPE_WARNING,
1232 "DD %s (%s %u) on conn %s %s (random drop for testing)\n",
1233 GC_m2s (q->type),
1234 GC_m2s (q->payload_type),
1235 ntohl (q->payload_id.pid),
1236 GCC_2s (c),
1237 GC_f2s (q->c_fwd));
1238 q->drop_task = GNUNET_SCHEDULER_add_now (&drop_cb,
1239 q);
1240 return q;
1241 }
1242 GNUNET_MQ_send (peer->core_mq, q->env);
1243 peer->queue_n++;
1244 }
1245
1246 GCC_check_connections ();
1247 return q;
1248} 798}
1249 799
1250 800
1251/** 801/**
1252 * Cancel sending a message. Message must have been sent with 802 * Add an entry to the DLL of all of the paths that this peer is on.
1253 * #GCP_send before. May not be called after the notify sent
1254 * callback has been called.
1255 *
1256 * It DOES call the continuation given to #GCP_send.
1257 * 803 *
1258 * @param q Queue handle to cancel 804 * @param cp peer to modify
805 * @param entry an entry on a path
806 * @param off offset of this peer on the path
1259 */ 807 */
1260void 808void
1261GCP_send_cancel (struct CadetPeerQueue *q) 809GCP_path_entry_add (struct CadetPeer *cp,
1262{ 810 struct CadetPeerPathEntry *entry,
1263 if (NULL != q->drop_task) 811 unsigned int off)
812{
813 GNUNET_assert (cp == GCPP_get_peer_at_offset (entry->path,
814 off));
815 LOG (GNUNET_ERROR_TYPE_DEBUG,
816 "Discovered that peer %s is on path %s at offset %u\n",
817 GCP_2s (cp),
818 GCPP_2s (entry->path),
819 off);
820 if (off >= cp->path_dll_length)
1264 { 821 {
1265 GNUNET_SCHEDULER_cancel (q->drop_task); 822 unsigned int len = cp->path_dll_length;
1266 q->drop_task = NULL; 823
1267 GNUNET_MQ_discard (q->env); 824 GNUNET_array_grow (cp->path_heads,
825 len,
826 off + 4);
827 GNUNET_array_grow (cp->path_tails,
828 cp->path_dll_length,
829 off + 4);
1268 } 830 }
1269 else 831 GNUNET_CONTAINER_DLL_insert (cp->path_heads[off],
832 cp->path_tails[off],
833 entry);
834 cp->off_sum += off;
835 cp->num_paths++;
836
837 /* If we have a tunnel to this peer, tell the tunnel that there is a
838 new path available. */
839 if (NULL != cp->t)
840 GCT_consider_path (cp->t,
841 entry->path,
842 off);
843
844 if ( (NULL != cp->search_h) &&
845 (DESIRED_CONNECTIONS_PER_TUNNEL <= cp->num_paths) )
1270 { 846 {
1271 GNUNET_MQ_send_cancel (q->env); 847 /* Now I have enough paths, stop search */
848 GCD_search_stop (cp->search_h);
849 cp->search_h = NULL;
850 }
851 if (NULL != cp->destroy_task)
852 {
853 /* paths changed, this resets the destroy timeout counter
854 and aborts a destroy task that may no longer be valid
855 to have (as we now have more paths via this peer). */
856 consider_peer_destroy (cp);
1272 } 857 }
1273 call_peer_cont (q, GNUNET_NO);
1274 GNUNET_free (q);
1275} 858}
1276 859
1277 860
1278/** 861/**
1279 * Initialize the peer subsystem. 862 * Remove an entry from the DLL of all of the paths that this peer is on.
1280 * 863 *
1281 * @param c Configuration. 864 * @param cp peer to modify
1282 */ 865 * @param entry an entry on a path
1283void 866 * @param off offset of this peer on the path
1284GCP_init (const struct GNUNET_CONFIGURATION_Handle *c)
1285{
1286 cfg = c;
1287 LOG (GNUNET_ERROR_TYPE_DEBUG,
1288 "GCP_init\n");
1289 in_shutdown = GNUNET_NO;
1290 peers = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_NO);
1291 if (GNUNET_OK !=
1292 GNUNET_CONFIGURATION_get_value_number (c, "CADET", "MAX_PEERS",
1293 &max_peers))
1294 {
1295 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
1296 "CADET", "MAX_PEERS", "USING DEFAULT");
1297 max_peers = 1000;
1298 }
1299
1300 if (GNUNET_OK !=
1301 GNUNET_CONFIGURATION_get_value_number (c, "CADET", "DROP_PERCENT",
1302 &drop_percent))
1303 {
1304 drop_percent = 0;
1305 }
1306 else
1307 {
1308 LOG (GNUNET_ERROR_TYPE_WARNING, "**************************************\n");
1309 LOG (GNUNET_ERROR_TYPE_WARNING, "Cadet is running with DROP enabled.\n");
1310 LOG (GNUNET_ERROR_TYPE_WARNING, "This is NOT a good idea!\n");
1311 LOG (GNUNET_ERROR_TYPE_WARNING, "Remove DROP_PERCENT from config file.\n");
1312 LOG (GNUNET_ERROR_TYPE_WARNING, "**************************************\n");
1313 }
1314 ats_ch = GNUNET_ATS_connectivity_init (c);
1315 connect_to_core (c);
1316 if (NULL == core_handle)
1317 {
1318 GNUNET_break (0);
1319 GNUNET_SCHEDULER_shutdown ();
1320 }
1321}
1322
1323
1324/**
1325 * Shut down the peer subsystem.
1326 */ 867 */
1327void 868void
1328GCP_shutdown (void) 869GCP_path_entry_remove (struct CadetPeer *cp,
1329{ 870 struct CadetPeerPathEntry *entry,
1330 LOG (GNUNET_ERROR_TYPE_DEBUG, 871 unsigned int off)
1331 "Shutting down peer subsystem\n"); 872{
1332 in_shutdown = GNUNET_YES; 873 LOG (GNUNET_ERROR_TYPE_DEBUG,
1333 if (NULL != core_handle) 874 "Removing knowledge about peer %s beging on path %s at offset %u\n",
1334 { 875 GCP_2s (cp),
1335 GNUNET_CORE_disconnect (core_handle); 876 GCPP_2s (entry->path),
1336 core_handle = NULL; 877 off);
1337 } 878 GNUNET_CONTAINER_DLL_remove (cp->path_heads[off],
1338 GNUNET_PEER_change_rc (myid, -1); 879 cp->path_tails[off],
1339 /* With MQ API, CORE calls the disconnect handler for every peer 880 entry);
1340 * after calling GNUNET_CORE_disconnect, shutdown must occur *after* that. 881 GNUNET_assert (0 < cp->num_paths);
1341 */ 882 cp->off_sum -= off;
1342 GNUNET_CONTAINER_multipeermap_iterate (peers, 883 cp->num_paths--;
1343 &shutdown_peer, 884 if ( (NULL == cp->core_mq) &&
1344 NULL); 885 (NULL != cp->t) &&
1345 if (NULL != ats_ch) 886 (NULL == cp->search_h) &&
1346 { 887 (DESIRED_CONNECTIONS_PER_TUNNEL > cp->num_paths) )
1347 GNUNET_ATS_connectivity_done (ats_ch); 888 cp->search_h
1348 ats_ch = NULL; 889 = GCD_search (&cp->pid);
1349 } 890 if (NULL == cp->destroy_task)
1350 GNUNET_CONTAINER_multipeermap_destroy (peers); 891 {
1351 peers = NULL; 892 /* paths changed, we might now be ready for destruction, check again */
1352} 893 consider_peer_destroy (cp);
1353 894 }
1354
1355/**
1356 * Retrieve the CadetPeer stucture associated with the peer. Optionally create
1357 * one and insert it in the appropriate structures if the peer is not known yet.
1358 *
1359 * @param peer_id Full identity of the peer.
1360 * @param create #GNUNET_YES if a new peer should be created if unknown.
1361 * #GNUNET_NO otherwise.
1362 *
1363 * @return Existing or newly created peer structure.
1364 * NULL if unknown and not requested @a create
1365 */
1366struct CadetPeer *
1367GCP_get (const struct GNUNET_PeerIdentity *peer_id, int create)
1368{
1369 struct CadetPeer *peer;
1370
1371 peer = GNUNET_CONTAINER_multipeermap_get (peers, peer_id);
1372 if (NULL == peer)
1373 {
1374 peer = GNUNET_new (struct CadetPeer);
1375 if (GNUNET_CONTAINER_multipeermap_size (peers) > max_peers)
1376 {
1377 peer_delete_oldest ();
1378 }
1379 GNUNET_assert (GNUNET_OK ==
1380 GNUNET_CONTAINER_multipeermap_put (peers,
1381 peer_id,
1382 peer,
1383 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1384 peer->id = GNUNET_PEER_intern (peer_id);
1385 }
1386 peer->last_contact = GNUNET_TIME_absolute_get ();
1387
1388 return peer;
1389}
1390
1391
1392/**
1393 * Retrieve the CadetPeer stucture associated with the
1394 * peer. Optionally create one and insert it in the appropriate
1395 * structures if the peer is not known yet.
1396 *
1397 * @param peer Short identity of the peer.
1398 * @param create #GNUNET_YES if a new peer should be created if unknown.
1399 * #GNUNET_NO otherwise.
1400 *
1401 * @return Existing or newly created peer structure.
1402 * NULL if unknown and not requested @a create
1403 */
1404struct CadetPeer *
1405GCP_get_short (const GNUNET_PEER_Id peer, int create)
1406{
1407 return GCP_get (GNUNET_PEER_resolve2 (peer), create);
1408} 895}
1409 896
1410 897
1411/** 898/**
1412 * Function called once #GNUNET_TRANSPORT_offer_hello() is done. 899 * Prune down the number of paths to this peer, we seem to
1413 * Marks the operation as finished. 900 * have way too many.
1414 * 901 *
1415 * @param cls Closure (our `struct CadetPeer`). 902 * @param cls the `struct CadetPeer` to maintain the path heap for
1416 */ 903 */
1417static void 904static void
1418hello_offer_done (void *cls) 905path_heap_cleanup (void *cls)
1419{ 906{
1420 struct CadetPeer *peer = cls; 907 struct CadetPeer *cp = cls;
908 struct CadetPeerPath *root;
1421 909
1422 peer->hello_offer = NULL; 910 cp->heap_cleanup_task = NULL;
911 while (GNUNET_CONTAINER_heap_get_size (cp->path_heap) >=
912 2 * DESIRED_CONNECTIONS_PER_TUNNEL)
913 {
914 /* Now we have way too many, drop least desirable UNLESS it is in use!
915 (Note that this intentionally keeps highly desireable, but currently
916 unused paths around in the hope that we might be able to switch, even
917 if the number of paths exceeds the threshold.) */
918 root = GNUNET_CONTAINER_heap_peek (cp->path_heap);
919 GNUNET_assert (NULL != root);
920 if (NULL !=
921 GCPP_get_connection (root,
922 cp,
923 GCPP_get_length (root) - 1))
924 break; /* can't fix */
925 /* Got plenty of paths to this destination, and this is a low-quality
926 one that we don't care about. Allow it to die. */
927 GNUNET_assert (root ==
928 GNUNET_CONTAINER_heap_remove_root (cp->path_heap));
929 GCPP_release (root);
930 }
1423} 931}
1424 932
1425 933
1426/** 934/**
1427 * Try to establish a new connection to this peer (in its tunnel). 935 * Try adding a @a path to this @a peer. If the peer already
1428 * If the peer doesn't have any path to it yet, try to get one. 936 * has plenty of paths, return NULL.
1429 * If the peer already has some path, send a CREATE CONNECTION towards it.
1430 * 937 *
1431 * @param peer Peer to connect to. 938 * @param cp peer to which the @a path leads to
939 * @param path a path looking for an owner; may not be fully initialized yet!
940 * @param off offset of @a cp in @a path
941 * @param force force attaching the path
942 * @return NULL if this peer does not care to become a new owner,
943 * otherwise the node in the peer's path heap for the @a path.
1432 */ 944 */
1433void 945struct GNUNET_CONTAINER_HeapNode *
1434GCP_connect (struct CadetPeer *peer) 946GCP_attach_path (struct CadetPeer *cp,
947 struct CadetPeerPath *path,
948 unsigned int off,
949 int force)
1435{ 950{
1436 struct CadetTunnel *t; 951 GNUNET_CONTAINER_HeapCostType desirability;
1437 struct CadetPeerPath *path; 952 struct CadetPeerPath *root;
1438 struct CadetConnection *c; 953 GNUNET_CONTAINER_HeapCostType root_desirability;
1439 int rerun_search; 954 struct GNUNET_CONTAINER_HeapNode *hn;
1440
1441 GCC_check_connections ();
1442 LOG (GNUNET_ERROR_TYPE_DEBUG,
1443 "peer_connect towards %s\n",
1444 GCP_2s (peer));
1445 /* If we have a current hello, try to connect using it. */
1446 GCP_try_connect (peer);
1447 955
1448 t = peer->tunnel; 956 GNUNET_assert (off == GCPP_get_length (path) - 1);
1449 c = NULL; 957 GNUNET_assert (cp == GCPP_get_peer_at_offset (path,
1450 rerun_search = GNUNET_NO; 958 off));
1451 959 if (NULL == cp->path_heap)
1452 if (NULL != peer->path_head) 960 {
961 /* #GCP_drop_owned_paths() was already called, we cannot take new ones! */
962 GNUNET_assert (GNUNET_NO == force);
963 return NULL;
964 }
965 desirability = GCPP_get_desirability (path);
966 if (GNUNET_NO == force)
967 {
968 /* FIXME: desirability is not yet initialized; tricky! */
969 if (GNUNET_NO ==
970 GNUNET_CONTAINER_heap_peek2 (cp->path_heap,
971 (void **) &root,
972 &root_desirability))
1453 { 973 {
1454 LOG (GNUNET_ERROR_TYPE_DEBUG, " some path exists\n"); 974 root = NULL;
1455 path = peer_get_best_path (peer); 975 root_desirability = 0;
1456 if (NULL != path)
1457 {
1458 char *s;
1459
1460 s = path_2s (path);
1461 LOG (GNUNET_ERROR_TYPE_DEBUG, " path to use: %s\n", s);
1462 GNUNET_free (s);
1463
1464 c = GCT_use_path (t, path);
1465 if (NULL == c)
1466 {
1467 /* This case can happen when the path includes a first hop that is
1468 * not yet known to be connected.
1469 *
1470 * This happens quite often during testing when running cadet
1471 * under valgrind: core connect notifications come very late
1472 * and the DHT result has already come and created a valid
1473 * path. In this case, the peer->connections
1474 * hashmaps will be NULL and tunnel_use_path will not be able
1475 * to create a connection from that path.
1476 *
1477 * Re-running the DHT GET should give core time to callback.
1478 *
1479 * GCT_use_path -> GCC_new -> register_neighbors takes care of
1480 * updating statistics about this issue.
1481 */
1482 rerun_search = GNUNET_YES;
1483 }
1484 else
1485 {
1486 GCC_send_create (c);
1487 return;
1488 }
1489 }
1490 else
1491 {
1492 LOG (GNUNET_ERROR_TYPE_DEBUG, " but is NULL, all paths are in use\n");
1493 }
1494 } 976 }
1495 977
1496 if (GNUNET_YES == rerun_search) 978 if ( (DESIRED_CONNECTIONS_PER_TUNNEL > cp->num_paths) &&
979 (desirability < root_desirability) )
1497 { 980 {
1498 struct GNUNET_TIME_Relative delay; 981 LOG (GNUNET_ERROR_TYPE_DEBUG,
1499 982 "Decided to not attach path %p to peer %s due to undesirability\n",
1500 GCP_stop_search (peer); 983 GCPP_2s (path),
1501 delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 100); 984 GCP_2s (cp));
1502 peer->search_delayed = GNUNET_SCHEDULER_add_delayed (delay, 985 return NULL;
1503 &delayed_search,
1504 peer);
1505 GCC_check_connections ();
1506 return;
1507 } 986 }
987 }
1508 988
1509 if (GNUNET_NO == is_searching (peer)) 989 LOG (GNUNET_ERROR_TYPE_DEBUG,
1510 GCP_start_search (peer); 990 "Attaching path %s to peer %s (%s)\n",
1511 GCC_check_connections (); 991 GCPP_2s (path),
1512} 992 GCP_2s (cp),
1513 993 (GNUNET_NO == force) ? "desirable" : "forced");
1514
1515/**
1516 * Chech whether there is a direct (core level) connection to peer.
1517 *
1518 * @param peer Peer to check.
1519 *
1520 * @return #GNUNET_YES if there is a direct connection.
1521 */
1522int
1523GCP_is_neighbor (const struct CadetPeer *peer)
1524{
1525 struct CadetPeerPath *path;
1526
1527 if (NULL == peer->connections)
1528 return GNUNET_NO;
1529 994
1530 for (path = peer->path_head; NULL != path; path = path->next) 995 /* Yes, we'd like to add this path, add to our heap */
1531 { 996 hn = GNUNET_CONTAINER_heap_insert (cp->path_heap,
1532 if (3 > path->length) 997 path,
1533 return GNUNET_YES; 998 desirability);
1534 }
1535 999
1536 /* Is not a neighbor but connections is not NULL, probably disconnecting */ 1000 /* Consider maybe dropping other paths because of the new one */
1537 return GNUNET_NO; 1001 if ( (GNUNET_CONTAINER_heap_get_size (cp->path_heap) >=
1002 2 * DESIRED_CONNECTIONS_PER_TUNNEL) &&
1003 (NULL != cp->heap_cleanup_task) )
1004 cp->heap_cleanup_task = GNUNET_SCHEDULER_add_now (&path_heap_cleanup,
1005 cp);
1006 return hn;
1538} 1007}
1539 1008
1540 1009
1541/** 1010/**
1542 * Create and initialize a new tunnel towards a peer, in case it has none. 1011 * This peer can no longer own @a path as the path
1543 * In case the peer already has a tunnel, nothing is done. 1012 * has been extended and a peer further down the line
1013 * is now the new owner.
1544 * 1014 *
1545 * Does not generate any traffic, just creates the local data structures. 1015 * @param cp old owner of the @a path
1546 * 1016 * @param path path where the ownership is lost
1547 * @param peer Peer towards which to create the tunnel. 1017 * @param hn note in @a cp's path heap that must be deleted
1548 */ 1018 */
1549void 1019void
1550GCP_add_tunnel (struct CadetPeer *peer) 1020GCP_detach_path (struct CadetPeer *cp,
1021 struct CadetPeerPath *path,
1022 struct GNUNET_CONTAINER_HeapNode *hn)
1551{ 1023{
1552 GCC_check_connections (); 1024 LOG (GNUNET_ERROR_TYPE_DEBUG,
1553 if (NULL != peer->tunnel) 1025 "Detatching path %s from peer %s\n",
1554 return; 1026 GCPP_2s (path),
1555 peer->tunnel = GCT_new (peer); 1027 GCP_2s (cp));
1556 GCC_check_connections (); 1028 GNUNET_assert (path ==
1029 GNUNET_CONTAINER_heap_remove_node (hn));
1557} 1030}
1558 1031
1559 1032
1560/** 1033/**
1561 * Add a connection to a neighboring peer. 1034 * Add a @a connection to this @a cp.
1562 *
1563 * Store that the peer is the first hop of the connection in one
1564 * direction and that on peer disconnect the connection must be
1565 * notified and destroyed, for it will no longer be valid.
1566 * 1035 *
1567 * @param peer Peer to add connection to. 1036 * @param cp peer via which the @a connection goes
1568 * @param c Connection to add. 1037 * @param cc the connection to add
1569 * @param pred #GNUNET_YES if we are predecessor, #GNUNET_NO if we are successor
1570 */ 1038 */
1571void 1039void
1572GCP_add_connection (struct CadetPeer *peer, 1040GCP_add_connection (struct CadetPeer *cp,
1573 struct CadetConnection *c, 1041 struct CadetConnection *cc)
1574 int pred) 1042{
1575{ 1043 LOG (GNUNET_ERROR_TYPE_DEBUG,
1576 LOG (GNUNET_ERROR_TYPE_DEBUG, 1044 "Adding connection %s to peer %s\n",
1577 "adding connection %s\n", 1045 GCC_2s (cc),
1578 GCC_2s (c)); 1046 GCP_2s (cp));
1579 LOG (GNUNET_ERROR_TYPE_DEBUG, 1047 GNUNET_assert (GNUNET_OK ==
1580 "to peer %s\n", 1048 GNUNET_CONTAINER_multishortmap_put (cp->connections,
1581 GCP_2s (peer)); 1049 &GCC_get_id (cc)->connection_of_tunnel,
1582 GNUNET_assert (NULL != peer->connections); 1050 cc,
1583 GNUNET_assert (GNUNET_OK == 1051 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1584 GNUNET_CONTAINER_multishortmap_put (peer->connections, 1052 if (NULL != cp->destroy_task)
1585 &GCC_get_id (c)->connection_of_tunnel, 1053 {
1586 c, 1054 GNUNET_SCHEDULER_cancel (cp->destroy_task);
1587 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 1055 cp->destroy_task = NULL;
1588 LOG (GNUNET_ERROR_TYPE_DEBUG, 1056 }
1589 "Peer %s has now %u connections.\n",
1590 GCP_2s (peer),
1591 GNUNET_CONTAINER_multishortmap_size (peer->connections));
1592}
1593
1594
1595/**
1596 * Add the path to the peer and update the path used to reach it in case this
1597 * is the shortest.
1598 *
1599 * @param peer Destination peer to add the path to.
1600 * @param path New path to add. Last peer must be @c peer.
1601 * Path will be either used of freed if already known.
1602 * @param trusted Do we trust that this path is real?
1603 *
1604 * @return path if path was taken, pointer to existing duplicate if exists
1605 * NULL on error.
1606 */
1607struct CadetPeerPath *
1608GCP_add_path (struct CadetPeer *peer,
1609 struct CadetPeerPath *path,
1610 int trusted)
1611{
1612 struct CadetPeerPath *aux;
1613 unsigned int l;
1614 unsigned int l2;
1615
1616 GCC_check_connections ();
1617 LOG (GNUNET_ERROR_TYPE_DEBUG,
1618 "adding path [%u] to peer %s\n",
1619 path->length, GCP_2s (peer));
1620
1621 if (NULL == peer || NULL == path
1622 || path->peers[path->length - 1] != peer->id)
1623 {
1624 GNUNET_break (0);
1625 path_destroy (path);
1626 return NULL;
1627 }
1628
1629 for (l = 1; l < path->length; l++)
1630 {
1631 if (path->peers[l] == myid)
1632 {
1633 LOG (GNUNET_ERROR_TYPE_DEBUG, " shortening path by %u\n", l);
1634 for (l2 = 0; l2 < path->length - l; l2++)
1635 {
1636 path->peers[l2] = path->peers[l + l2];
1637 }
1638 path->length -= l;
1639 l = 1;
1640 path->peers = GNUNET_realloc (path->peers,
1641 path->length * sizeof (GNUNET_PEER_Id));
1642 }
1643 }
1644
1645 LOG (GNUNET_ERROR_TYPE_DEBUG, " final length: %u\n", path->length);
1646
1647 if (2 >= path->length && GNUNET_NO == trusted)
1648 {
1649 /* Only allow CORE to tell us about direct paths */
1650 path_destroy (path);
1651 return NULL;
1652 }
1653
1654 l = path_get_length (path);
1655 if (0 == l)
1656 {
1657 path_destroy (path);
1658 return NULL;
1659 }
1660
1661 GNUNET_assert (peer->id == path->peers[path->length - 1]);
1662 for (aux = peer->path_head; aux != NULL; aux = aux->next)
1663 {
1664 l2 = path_get_length (aux);
1665 if (l2 > l)
1666 {
1667 LOG (GNUNET_ERROR_TYPE_DEBUG, " added\n");
1668 GNUNET_CONTAINER_DLL_insert_before (peer->path_head,
1669 peer->path_tail, aux, path);
1670 goto finish;
1671 }
1672 else
1673 {
1674 if (l2 == l && memcmp (path->peers, aux->peers, l) == 0)
1675 {
1676 LOG (GNUNET_ERROR_TYPE_DEBUG, " already known\n");
1677 path_destroy (path);
1678 return aux;
1679 }
1680 }
1681 }
1682 GNUNET_CONTAINER_DLL_insert_tail (peer->path_head,
1683 peer->path_tail,
1684 path);
1685 LOG (GNUNET_ERROR_TYPE_DEBUG, " added last\n");
1686
1687finish:
1688 if (NULL != peer->tunnel
1689 && CONNECTIONS_PER_TUNNEL > GCT_count_connections (peer->tunnel)
1690 && 2 < path->length) /* Direct paths are handled by core_connect */
1691 {
1692 GCP_connect (peer);
1693 }
1694 GCC_check_connections ();
1695 return path;
1696} 1057}
1697 1058
1698 1059
1699/** 1060/**
1700 * Add the path to the origin peer and update the path used to reach it in case 1061 * Remove a @a connection that went via this @a cp.
1701 * this is the shortest.
1702 * The path is given in peer_info -> destination, therefore we turn the path
1703 * upside down first.
1704 *
1705 * @param peer Peer to add the path to, being the origin of the path.
1706 * @param path New path to add after being inversed.
1707 * Path will be either used or freed.
1708 * @param trusted Do we trust that this path is real?
1709 * 1062 *
1710 * @return path if path was taken, pointer to existing duplicate if exists 1063 * @param cp peer via which the @a connection went
1711 * NULL on error. 1064 * @param cc the connection to remove
1712 */ 1065 */
1713struct CadetPeerPath * 1066void
1714GCP_add_path_to_origin (struct CadetPeer *peer, 1067GCP_remove_connection (struct CadetPeer *cp,
1715 struct CadetPeerPath *path, 1068 struct CadetConnection *cc)
1716 int trusted)
1717{ 1069{
1718 if (NULL == path) 1070 LOG (GNUNET_ERROR_TYPE_DEBUG,
1719 return NULL; 1071 "Removing connection %s from peer %s\n",
1720 path_invert (path); 1072 GCC_2s (cc),
1721 return GCP_add_path (peer, path, trusted); 1073 GCP_2s (cp));
1074 GNUNET_assert (GNUNET_YES ==
1075 GNUNET_CONTAINER_multishortmap_remove (cp->connections,
1076 &GCC_get_id (cc)->connection_of_tunnel,
1077 cc));
1078 consider_peer_destroy (cp);
1722} 1079}
1723 1080
1724 1081
1725/** 1082/**
1726 * Adds a path to the info of all the peers in the path 1083 * Retrieve the CadetPeer stucture associated with the
1084 * peer. Optionally create one and insert it in the appropriate
1085 * structures if the peer is not known yet.
1727 * 1086 *
1728 * @param p Path to process. 1087 * @param peer_id Full identity of the peer.
1729 * @param confirmed Whether we know if the path works or not. 1088 * @param create #GNUNET_YES if a new peer should be created if unknown.
1089 * #GNUNET_NO to return NULL if peer is unknown.
1090 * @return Existing or newly created peer structure.
1091 * NULL if unknown and not requested @a create
1730 */ 1092 */
1731void 1093struct CadetPeer *
1732GCP_add_path_to_all (const struct CadetPeerPath *p, int confirmed) 1094GCP_get (const struct GNUNET_PeerIdentity *peer_id,
1095 int create)
1733{ 1096{
1734 unsigned int i; 1097 struct CadetPeer *cp;
1735 1098
1736 /* TODO: invert and add to origin */ 1099 cp = GNUNET_CONTAINER_multipeermap_get (peers,
1737 /* TODO: replace all "GCP_add_path" with this, make the other one static */ 1100 peer_id);
1738 GCC_check_connections (); 1101 if (NULL != cp)
1739 for (i = 0; i < p->length && p->peers[i] != myid; i++) /* skip'em */ ; 1102 return cp;
1740 for (i++; i < p->length; i++) 1103 if (GNUNET_NO == create)
1741 { 1104 return NULL;
1742 struct CadetPeer *peer; 1105 cp = GNUNET_new (struct CadetPeer);
1743 struct CadetPeerPath *copy; 1106 cp->pid = *peer_id;
1744 1107 cp->connections = GNUNET_CONTAINER_multishortmap_create (32,
1745 peer = GCP_get_short (p->peers[i], GNUNET_YES); 1108 GNUNET_YES);
1746 copy = path_duplicate (p); 1109 cp->path_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
1747 copy->length = i + 1; 1110 GNUNET_assert (GNUNET_YES ==
1748 GCP_add_path (peer, copy, 3 > p->length ? GNUNET_NO : confirmed); 1111 GNUNET_CONTAINER_multipeermap_put (peers,
1749 } 1112 &cp->pid,
1750 GCC_check_connections (); 1113 cp,
1114 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1115 LOG (GNUNET_ERROR_TYPE_DEBUG,
1116 "Creating peer %s\n",
1117 GCP_2s (cp));
1118 return cp;
1751} 1119}
1752 1120
1753 1121
1754/** 1122/**
1755 * Remove any path to the peer that has the exact same peers as the one given. 1123 * Obtain the peer identity for a `struct CadetPeer`.
1756 * 1124 *
1757 * @param peer Peer to remove the path from. 1125 * @param cp our peer handle
1758 * @param path Path to remove. Is always destroyed . 1126 * @return the peer identity
1759 */ 1127 */
1760void 1128const struct GNUNET_PeerIdentity *
1761GCP_remove_path (struct CadetPeer *peer, 1129GCP_get_id (struct CadetPeer *cp)
1762 struct CadetPeerPath *path)
1763{ 1130{
1764 struct CadetPeerPath *iter; 1131 return &cp->pid;
1765 struct CadetPeerPath *next;
1766
1767 GCC_check_connections ();
1768 GNUNET_assert (myid == path->peers[0]);
1769 GNUNET_assert (peer->id == path->peers[path->length - 1]);
1770
1771 LOG (GNUNET_ERROR_TYPE_INFO,
1772 "Removing path %p (%u) from %s\n",
1773 path, path->length, GCP_2s (peer));
1774
1775 for (iter = peer->path_head; NULL != iter; iter = next)
1776 {
1777 next = iter->next;
1778 if (0 == path_cmp (path, iter))
1779 {
1780 GNUNET_CONTAINER_DLL_remove (peer->path_head,
1781 peer->path_tail,
1782 iter);
1783 if (iter != path)
1784 path_destroy (iter);
1785 }
1786 }
1787 path_destroy (path);
1788 GCC_check_connections ();
1789} 1132}
1790 1133
1791 1134
1792/** 1135/**
1793 * Check that we are aware of a connection from a neighboring peer. 1136 * Iterate over all known peers.
1794 * 1137 *
1795 * @param peer Peer to the connection is with 1138 * @param iter Iterator.
1796 * @param c Connection that should be in the map with this peer. 1139 * @param cls Closure for @c iter.
1797 */ 1140 */
1798void 1141void
1799GCP_check_connection (const struct CadetPeer *peer, 1142GCP_iterate_all (GNUNET_CONTAINER_PeerMapIterator iter,
1800 const struct CadetConnection *c) 1143 void *cls)
1801{ 1144{
1802 GNUNET_assert (NULL != peer); 1145 GNUNET_CONTAINER_multipeermap_iterate (peers,
1803 GNUNET_assert (NULL != peer->connections); 1146 iter,
1804 return; // ???? 1147 cls);
1805 GNUNET_assert (GNUNET_YES ==
1806 GNUNET_CONTAINER_multishortmap_contains_value (peer->connections,
1807 &GCC_get_id (c)->connection_of_tunnel,
1808 c));
1809} 1148}
1810 1149
1811 1150
1812/** 1151/**
1813 * Remove a connection from a neighboring peer. 1152 * Count the number of known paths toward the peer.
1814 * 1153 *
1815 * @param peer Peer to remove connection from. 1154 * @param cp Peer to get path info.
1816 * @param c Connection to remove. 1155 * @return Number of known paths.
1817 */ 1156 */
1818void 1157unsigned int
1819GCP_remove_connection (struct CadetPeer *peer, 1158GCP_count_paths (const struct CadetPeer *cp)
1820 const struct CadetConnection *c)
1821{ 1159{
1822 LOG (GNUNET_ERROR_TYPE_DEBUG, 1160 return cp->num_paths;
1823 "Removing connection %s\n",
1824 GCC_2s (c));
1825 LOG (GNUNET_ERROR_TYPE_DEBUG,
1826 "from peer %s\n",
1827 GCP_2s (peer));
1828 if ( (NULL == peer) ||
1829 (NULL == peer->connections) )
1830 return;
1831 GNUNET_assert (GNUNET_YES ==
1832 GNUNET_CONTAINER_multishortmap_remove (peer->connections,
1833 &GCC_get_id (c)->connection_of_tunnel,
1834 c));
1835 LOG (GNUNET_ERROR_TYPE_DEBUG,
1836 "Peer %s remains with %u connections.\n",
1837 GCP_2s (peer),
1838 GNUNET_CONTAINER_multishortmap_size (peer->connections));
1839} 1161}
1840 1162
1841 1163
1842/** 1164/**
1843 * Start the DHT search for new paths towards the peer: we don't have 1165 * Iterate over the paths to a peer.
1844 * enough good connections.
1845 * 1166 *
1846 * @param peer Destination peer. 1167 * @param cp Peer to get path info.
1168 * @param callback Function to call for every path.
1169 * @param callback_cls Closure for @a callback.
1170 * @return Number of iterated paths.
1847 */ 1171 */
1848void 1172unsigned int
1849GCP_start_search (struct CadetPeer *peer) 1173GCP_iterate_paths (struct CadetPeer *cp,
1174 GCP_PathIterator callback,
1175 void *callback_cls)
1850{ 1176{
1851 const struct GNUNET_PeerIdentity *id; 1177 unsigned int ret = 0;
1852 struct CadetTunnel *t = peer->tunnel;
1853
1854 GCC_check_connections ();
1855 if (NULL != peer->search_h)
1856 {
1857 GNUNET_break (0);
1858 return;
1859 }
1860
1861 if (NULL != peer->search_delayed)
1862 GCP_stop_search (peer);
1863
1864 id = GNUNET_PEER_resolve2 (peer->id);
1865 peer->search_h = GCD_search (id, &search_handler, peer);
1866
1867 if (NULL == t)
1868 {
1869 /* Why would we search for a peer with no tunnel towards it? */
1870 GNUNET_break (0);
1871 return;
1872 }
1873
1874 if (CADET_TUNNEL_NEW == GCT_get_cstate (t)
1875 || 0 == GCT_count_any_connections (t))
1876 {
1877 GCT_change_cstate (t, CADET_TUNNEL_SEARCHING);
1878 }
1879 GCC_check_connections ();
1880}
1881 1178
1179 LOG (GNUNET_ERROR_TYPE_DEBUG,
1180 "Iterating over paths to peer %s%s\n",
1181 GCP_2s (cp),
1182 (NULL == cp->core_mq) ? "" : " including direct link");
1183 if (NULL != cp->core_mq)
1184 {
1185 struct CadetPeerPath *path;
1882 1186
1883/** 1187 path = GCPP_get_path_from_route (1,
1884 * Stop the DHT search for new paths towards the peer: we already have 1188 &cp->pid);
1885 * enough good connections. 1189 ret++;
1886 * 1190 if (GNUNET_NO ==
1887 * @param peer Destination peer. 1191 callback (callback_cls,
1888 */ 1192 path,
1889void 1193 0))
1890GCP_stop_search (struct CadetPeer *peer) 1194 return ret;
1891{ 1195 }
1892 GCC_check_connections (); 1196 for (unsigned int i=0;i<cp->path_dll_length;i++)
1893 if (NULL != peer->search_h) 1197 {
1894 { 1198 for (struct CadetPeerPathEntry *pe = cp->path_heads[i];
1895 GCD_search_stop (peer->search_h); 1199 NULL != pe;
1896 peer->search_h = NULL; 1200 pe = pe->next)
1897 }
1898 if (NULL != peer->search_delayed)
1899 { 1201 {
1900 GNUNET_SCHEDULER_cancel (peer->search_delayed); 1202 ret++;
1901 peer->search_delayed = NULL; 1203 if (GNUNET_NO ==
1204 callback (callback_cls,
1205 pe->path,
1206 i))
1207 return ret;
1902 } 1208 }
1903 GCC_check_connections (); 1209 }
1904} 1210 return ret;
1905
1906
1907/**
1908 * Get the Full ID of a peer.
1909 *
1910 * @param peer Peer to get from.
1911 *
1912 * @return Full ID of peer.
1913 */
1914const struct GNUNET_PeerIdentity *
1915GCP_get_id (const struct CadetPeer *peer)
1916{
1917 return GNUNET_PEER_resolve2 (peer->id);
1918} 1211}
1919 1212
1920 1213
1921/** 1214/**
1922 * Get the Short ID of a peer. 1215 * Iterate over the paths to @a cp where
1923 * 1216 * @a cp is at distance @a dist from us.
1924 * @param peer Peer to get from.
1925 * 1217 *
1926 * @return Short ID of peer. 1218 * @param cp Peer to get path info.
1219 * @param dist desired distance of @a cp to us on the path
1220 * @param callback Function to call for every path.
1221 * @param callback_cls Closure for @a callback.
1222 * @return Number of iterated paths.
1927 */ 1223 */
1928GNUNET_PEER_Id 1224unsigned int
1929GCP_get_short_id (const struct CadetPeer *peer) 1225GCP_iterate_paths_at (struct CadetPeer *cp,
1226 unsigned int dist,
1227 GCP_PathIterator callback,
1228 void *callback_cls)
1930{ 1229{
1931 return peer->id; 1230 unsigned int ret = 0;
1932}
1933
1934 1231
1935/** 1232 if (dist >= cp->path_dll_length)
1936 * Set tunnel. 1233 {
1937 * 1234 LOG (GNUNET_ERROR_TYPE_DEBUG,
1938 * If tunnel is NULL and there was a search active, stop it, as it's useless. 1235 "Asked to look for paths at distance %u, but maximum for me is < %u\n",
1939 * 1236 dist,
1940 * @param peer Peer. 1237 cp->path_dll_length);
1941 * @param t Tunnel. 1238 return 0;
1942 */ 1239 }
1943void 1240 for (struct CadetPeerPathEntry *pe = cp->path_heads[dist];
1944GCP_set_tunnel (struct CadetPeer *peer, struct CadetTunnel *t) 1241 NULL != pe;
1945{ 1242 pe = pe->next)
1946 peer->tunnel = t; 1243 {
1947 if (NULL == t && GNUNET_YES == is_searching (peer)) 1244 if (GNUNET_NO ==
1948 { 1245 callback (callback_cls,
1949 GCP_stop_search (peer); 1246 pe->path,
1950 } 1247 dist))
1248 return ret;
1249 ret++;
1250 }
1251 return ret;
1951} 1252}
1952 1253
1953 1254
1954/** 1255/**
1955 * Get the tunnel towards a peer. 1256 * Get the tunnel towards a peer.
1956 * 1257 *
1957 * @param peer Peer to get from. 1258 * @param cp Peer to get from.
1958 * 1259 * @param create #GNUNET_YES to create a tunnel if we do not have one
1959 * @return Tunnel towards peer. 1260 * @return Tunnel towards peer.
1960 */ 1261 */
1961struct CadetTunnel * 1262struct CadetTunnel *
1962GCP_get_tunnel (const struct CadetPeer *peer) 1263GCP_get_tunnel (struct CadetPeer *cp,
1264 int create)
1963{ 1265{
1964 if (NULL == peer) 1266 if (NULL == cp)
1965 return NULL; 1267 return NULL;
1966 return peer->tunnel; 1268 if ( (NULL != cp->t) ||
1269 (GNUNET_NO == create) )
1270 return cp->t;
1271 cp->t = GCT_create_tunnel (cp);
1272 consider_peer_activate (cp);
1273 return cp->t;
1967} 1274}
1968 1275
1969 1276
1970/** 1277/**
1971 * Set the hello message. 1278 * Hello offer was passed to the transport service. Mark it
1279 * as done.
1972 * 1280 *
1973 * @param peer Peer whose message to set. 1281 * @param cls the `struct CadetPeer` where the offer completed
1974 * @param hello Hello message.
1975 */ 1282 */
1976void 1283static void
1977GCP_set_hello (struct CadetPeer *peer, 1284hello_offer_done (void *cls)
1978 const struct GNUNET_HELLO_Message *hello)
1979{ 1285{
1980 struct GNUNET_HELLO_Message *old; 1286 struct CadetPeer *cp = cls;
1981 size_t size;
1982 1287
1983 GCC_check_connections (); 1288 cp->hello_offer = NULL;
1984 LOG (GNUNET_ERROR_TYPE_DEBUG, "set hello for %s\n", GCP_2s (peer));
1985 if (NULL == hello)
1986 return;
1987
1988 old = GCP_get_hello (peer);
1989 if (NULL == old)
1990 {
1991 size = GNUNET_HELLO_size (hello);
1992 peer->hello = GNUNET_malloc (size);
1993 GNUNET_memcpy (peer->hello, hello, size);
1994 }
1995 else
1996 {
1997 peer->hello = GNUNET_HELLO_merge (old, hello);
1998 GNUNET_free (old);
1999 }
2000 GCC_check_connections ();
2001} 1289}
2002 1290
2003 1291
2004/** 1292/**
2005 * Get the hello message. 1293 * We got a HELLO for a @a peer, remember it, and possibly
2006 * 1294 * trigger adequate actions (like trying to connect).
2007 * @param peer Peer whose message to get.
2008 * 1295 *
2009 * @return Hello message. 1296 * @param cp the peer we got a HELLO for
1297 * @param hello the HELLO to remember
2010 */ 1298 */
2011struct GNUNET_HELLO_Message * 1299void
2012GCP_get_hello (struct CadetPeer *peer) 1300GCP_set_hello (struct CadetPeer *cp,
1301 const struct GNUNET_HELLO_Message *hello)
2013{ 1302{
2014 struct GNUNET_TIME_Absolute expiration; 1303 struct GNUNET_HELLO_Message *mrg;
2015 struct GNUNET_TIME_Relative remaining;
2016
2017 if (NULL == peer->hello)
2018 return NULL;
2019 1304
2020 expiration = GNUNET_HELLO_get_last_expiration (peer->hello); 1305 LOG (GNUNET_ERROR_TYPE_DEBUG,
2021 remaining = GNUNET_TIME_absolute_get_remaining (expiration); 1306 "Got %u byte HELLO for peer %s\n",
2022 if (0 == remaining.rel_value_us) 1307 (unsigned int) GNUNET_HELLO_size (hello),
2023 { 1308 GCP_2s (cp));
2024 LOG (GNUNET_ERROR_TYPE_DEBUG, " get - hello expired on %s\n", 1309 if (NULL != cp->hello_offer)
2025 GNUNET_STRINGS_absolute_time_to_string (expiration)); 1310 {
2026 GNUNET_free (peer->hello); 1311 GNUNET_TRANSPORT_offer_hello_cancel (cp->hello_offer);
2027 peer->hello = NULL; 1312 cp->hello_offer = NULL;
2028 } 1313 }
2029 return peer->hello; 1314 if (NULL != cp->hello)
1315 {
1316 mrg = GNUNET_HELLO_merge (hello,
1317 cp->hello);
1318 GNUNET_free (cp->hello);
1319 cp->hello = mrg;
1320 }
1321 else
1322 {
1323 cp->hello = GNUNET_memdup (hello,
1324 GNUNET_HELLO_size (hello));
1325 }
1326 cp->hello_offer
1327 = GNUNET_TRANSPORT_offer_hello (cfg,
1328 GNUNET_HELLO_get_header (cp->hello) ,
1329 &hello_offer_done,
1330 cp);
1331 /* New HELLO means cp's destruction time may change... */
1332 consider_peer_destroy (cp);
2030} 1333}
2031 1334
2032 1335
2033/** 1336/**
2034 * Try to connect to a peer on TRANSPORT level. 1337 * The tunnel to the given peer no longer exists, remove it from our
1338 * data structures, and possibly clean up the peer itself.
2035 * 1339 *
2036 * @param peer Peer to whom to connect. 1340 * @param cp the peer affected
1341 * @param t the dead tunnel
2037 */ 1342 */
2038void 1343void
2039GCP_try_connect (struct CadetPeer *peer) 1344GCP_drop_tunnel (struct CadetPeer *cp,
1345 struct CadetTunnel *t)
2040{ 1346{
2041 struct GNUNET_HELLO_Message *hello; 1347 LOG (GNUNET_ERROR_TYPE_DEBUG,
2042 struct GNUNET_MessageHeader *mh; 1348 "Dropping tunnel %s to peer %s\n",
2043 1349 GCT_2s (t),
2044 if (GNUNET_YES != 1350 GCP_2s (cp));
2045 GNUNET_CONFIGURATION_get_value_yesno (cfg, 1351 GNUNET_assert (cp->t == t);
2046 "CADET", 1352 cp->t = NULL;
2047 "DISABLE_TRY_CONNECT")) 1353 consider_peer_destroy (cp);
2048 return;
2049 GCC_check_connections ();
2050 if (GNUNET_YES == GCP_is_neighbor (peer))
2051 return;
2052 hello = GCP_get_hello (peer);
2053 if (NULL == hello)
2054 return;
2055
2056 mh = GNUNET_HELLO_get_header (hello);
2057 if (NULL != peer->hello_offer)
2058 {
2059 GNUNET_TRANSPORT_offer_hello_cancel (peer->hello_offer);
2060 peer->hello_offer = NULL;
2061 }
2062 peer->hello_offer = GNUNET_TRANSPORT_offer_hello (cfg,
2063 mh,
2064 &hello_offer_done,
2065 peer);
2066 if (NULL == peer->connectivity_suggestion)
2067 peer->connectivity_suggestion
2068 = GNUNET_ATS_connectivity_suggest (ats_ch,
2069 GCP_get_id (peer),
2070 1); /* strength */
2071 GCC_check_connections ();
2072} 1354}
2073 1355
2074 1356
2075/** 1357/**
2076 * Notify a peer that a link between two other peers is broken. If any path 1358 * Test if @a cp has a core-level connection
2077 * used that link, eliminate it.
2078 * 1359 *
2079 * @param peer Peer affected by the change. 1360 * @param cp peer to test
2080 * @param peer1 Peer whose link is broken. 1361 * @return #GNUNET_YES if @a cp has a core-level connection
2081 * @param peer2 Peer whose link is broken.
2082 */ 1362 */
2083void 1363int
2084GCP_notify_broken_link (struct CadetPeer *peer, 1364GCP_has_core_connection (struct CadetPeer *cp)
2085 const struct GNUNET_PeerIdentity *peer1,
2086 const struct GNUNET_PeerIdentity *peer2)
2087{ 1365{
2088 struct CadetPeerPath *iter; 1366 return (NULL != cp->core_mq) ? GNUNET_YES : GNUNET_NO;
2089 struct CadetPeerPath *next;
2090 unsigned int i;
2091 GNUNET_PEER_Id p1;
2092 GNUNET_PEER_Id p2;
2093
2094 GCC_check_connections ();
2095 p1 = GNUNET_PEER_search (peer1);
2096 p2 = GNUNET_PEER_search (peer2);
2097
2098 LOG (GNUNET_ERROR_TYPE_DEBUG, "Link %u-%u broken\n", p1, p2);
2099 if (0 == p1 || 0 == p2)
2100 {
2101 /* We don't even know them */
2102 return;
2103 }
2104
2105 for (iter = peer->path_head; NULL != iter; iter = next)
2106 {
2107 next = iter->next;
2108 for (i = 0; i < iter->length - 1; i++)
2109 {
2110 if ((iter->peers[i] == p1 && iter->peers[i + 1] == p2)
2111 || (iter->peers[i] == p2 && iter->peers[i + 1] == p1))
2112 {
2113 char *s;
2114
2115 s = path_2s (iter);
2116 LOG (GNUNET_ERROR_TYPE_DEBUG, " - invalidating %s\n", s);
2117 GNUNET_free (s);
2118
2119 path_invalidate (iter);
2120 }
2121 }
2122 }
2123 GCC_check_connections ();
2124} 1367}
2125 1368
2126 1369
2127/** 1370/**
2128 * Count the number of known paths toward the peer. 1371 * Start message queue change notifications.
2129 *
2130 * @param peer Peer to get path info.
2131 * 1372 *
2132 * @return Number of known paths. 1373 * @param cp peer to notify for
1374 * @param cb function to call if mq becomes available or unavailable
1375 * @param cb_cls closure for @a cb
1376 * @return handle to cancel request
2133 */ 1377 */
2134unsigned int 1378struct GCP_MessageQueueManager *
2135GCP_count_paths (const struct CadetPeer *peer) 1379GCP_request_mq (struct CadetPeer *cp,
1380 GCP_MessageQueueNotificationCallback cb,
1381 void *cb_cls)
2136{ 1382{
2137 struct CadetPeerPath *iter; 1383 struct GCP_MessageQueueManager *mqm;
2138 unsigned int i;
2139 1384
2140 for (iter = peer->path_head, i = 0; NULL != iter; iter = iter->next) 1385 mqm = GNUNET_new (struct GCP_MessageQueueManager);
2141 i++; 1386 mqm->cb = cb;
2142 1387 mqm->cb_cls = cb_cls;
2143 return i; 1388 mqm->cp = cp;
1389 GNUNET_CONTAINER_DLL_insert (cp->mqm_head,
1390 cp->mqm_tail,
1391 mqm);
1392 LOG (GNUNET_ERROR_TYPE_DEBUG,
1393 "Creating MQM %p for peer %s\n",
1394 mqm,
1395 GCP_2s (cp));
1396 if (NULL != cp->core_mq)
1397 cb (cb_cls,
1398 GNUNET_YES);
1399 return mqm;
2144} 1400}
2145 1401
2146 1402
2147/** 1403/**
2148 * Iterate over the paths to a peer. 1404 * Stops message queue change notifications.
2149 * 1405 *
2150 * @param peer Peer to get path info. 1406 * @param mqm handle matching request to cancel
2151 * @param callback Function to call for every path. 1407 * @param last_env final message to transmit, or NULL
2152 * @param cls Closure for @a callback.
2153 *
2154 * @return Number of iterated paths.
2155 */ 1408 */
2156unsigned int 1409void
2157GCP_iterate_paths (struct CadetPeer *peer, 1410GCP_request_mq_cancel (struct GCP_MessageQueueManager *mqm,
2158 GCP_path_iterator callback, 1411 struct GNUNET_MQ_Envelope *last_env)
2159 void *cls) 1412{
2160{ 1413 struct CadetPeer *cp = mqm->cp;
2161 struct CadetPeerPath *iter; 1414
2162 unsigned int i; 1415 LOG (GNUNET_ERROR_TYPE_DEBUG,
2163 1416 "Destroying MQM %p for peer %s%s\n",
2164 for (iter = peer->path_head, i = 0; NULL != iter; iter = iter->next) 1417 mqm,
1418 GCP_2s (cp),
1419 (NULL == last_env) ? "" : " with last ditch transmission");
1420 if (NULL != mqm->env)
1421 GNUNET_MQ_discard (mqm->env);
1422 if (NULL != last_env)
1423 {
1424 if (NULL != cp->core_mq)
2165 { 1425 {
2166 i++; 1426 GNUNET_MQ_notify_sent (last_env,
2167 if (GNUNET_YES != callback (cls, peer, iter)) 1427 &mqm_send_done,
2168 break; 1428 cp);
1429 GNUNET_MQ_send (cp->core_mq,
1430 last_env);
2169 } 1431 }
2170 1432 else
2171 return i; 1433 {
1434 GNUNET_MQ_discard (last_env);
1435 }
1436 }
1437 if (cp->mqm_ready_ptr == mqm)
1438 cp->mqm_ready_ptr = mqm->next;
1439 GNUNET_CONTAINER_DLL_remove (cp->mqm_head,
1440 cp->mqm_tail,
1441 mqm);
1442 GNUNET_free (mqm);
2172} 1443}
2173 1444
2174 1445
2175/** 1446/**
2176 * Iterate all known peers. 1447 * Send the message in @a env to @a cp, overriding queueing logic.
1448 * This function should only be used to send error messages outside
1449 * of flow and congestion control, similar to ICMP. Note that
1450 * the envelope may be silently discarded as well.
2177 * 1451 *
2178 * @param iter Iterator. 1452 * @param cp peer to send the message to
2179 * @param cls Closure for @c iter. 1453 * @param env envelope with the message to send
2180 */ 1454 */
2181void 1455void
2182GCP_iterate_all (GNUNET_CONTAINER_PeerMapIterator iter, 1456GCP_send_ooo (struct CadetPeer *cp,
2183 void *cls) 1457 struct GNUNET_MQ_Envelope *env)
2184{ 1458{
2185 GCC_check_connections (); 1459 LOG (GNUNET_ERROR_TYPE_DEBUG,
2186 GNUNET_CONTAINER_multipeermap_iterate (peers, 1460 "Sending message to %s out of management\n",
2187 iter, 1461 GCP_2s (cp));
2188 cls); 1462 if (NULL == cp->core_mq)
2189 GCC_check_connections (); 1463 {
1464 GNUNET_MQ_discard (env);
1465 return;
1466 }
1467 GNUNET_MQ_notify_sent (env,
1468 &mqm_send_done,
1469 cp);
1470 GNUNET_MQ_send (cp->core_mq,
1471 env);
2190} 1472}
2191 1473
2192 1474
2193/**
2194 * Get the static string for a peer ID.
2195 *
2196 * @param peer Peer.
2197 *
2198 * @return Static string for it's ID.
2199 */
2200const char *
2201GCP_2s (const struct CadetPeer *peer)
2202{
2203 if (NULL == peer)
2204 return "(NULL)";
2205 return GNUNET_i2s (GNUNET_PEER_resolve2 (peer->id));
2206}
2207 1475
2208 1476
2209/* end of gnunet-service-cadet_peer.c */ 1477/* end of gnunet-service-cadet-new_peer.c */
diff --git a/src/cadet/gnunet-service-cadet_peer.h b/src/cadet/gnunet-service-cadet_peer.h
index 1e206e10f..baa87ea87 100644
--- a/src/cadet/gnunet-service-cadet_peer.h
+++ b/src/cadet/gnunet-service-cadet_peer.h
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2013 GNUnet e.V. 3 Copyright (C) 2001-2017 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -20,464 +20,374 @@
20 20
21/** 21/**
22 * @file cadet/gnunet-service-cadet_peer.h 22 * @file cadet/gnunet-service-cadet_peer.h
23 * @brief cadet service; dealing with remote peers 23 * @brief Information we track per peer.
24 * @author Bartlomiej Polot 24 * @author Bartlomiej Polot
25 * 25 * @author Christian Grothoff
26 * All functions in this file should use the prefix GMP (Gnunet Cadet Peer)
27 */ 26 */
28
29#ifndef GNUNET_SERVICE_CADET_PEER_H 27#ifndef GNUNET_SERVICE_CADET_PEER_H
30#define GNUNET_SERVICE_CADET_PEER_H 28#define GNUNET_SERVICE_CADET_PEER_H
31 29
32#ifdef __cplusplus 30#include "gnunet-service-cadet.h"
33extern "C" 31#include "gnunet_hello_lib.h"
34{
35#if 0 /* keep Emacsens' auto-indent happy */
36}
37#endif
38#endif
39
40#include "platform.h"
41#include "gnunet_util_lib.h"
42#include "cadet_path.h"
43 32
44/**
45 * Struct containing all information regarding a given peer
46 */
47struct CadetPeer;
48
49/**
50 * Handle to queued messages on a peer level.
51 */
52struct CadetPeerQueue;
53
54#include "gnunet-service-cadet_connection.h"
55
56
57/**
58 * Callback called when a queued message is sent.
59 *
60 * @param cls Closure.
61 * @param c Connection this message was on.
62 * @param fwd Was this a FWD going message?
63 * @param sent Was it really sent? (Could have been canceled)
64 * @param type Type of message sent.
65 * @param payload_type Type of payload, if applicable.
66 * @param pid Message ID, or 0 if not applicable (create, destroy, etc).
67 * @param size Size of the message.
68 * @param wait Time spent waiting for core (only the time for THIS message)
69 */
70typedef void
71(*GCP_sent) (void *cls,
72 struct CadetConnection *c,
73 int fwd,
74 int sent,
75 uint16_t type,
76 uint16_t payload_type,
77 struct CadetEncryptedMessageIdentifier pid,
78 size_t size,
79 struct GNUNET_TIME_Relative wait);
80 33
81/** 34/**
82 * Peer path iterator. 35 * Get the static string for a peer ID.
83 * 36 *
84 * @param cls Closure. 37 * @param peer Peer.
85 * @param peer Peer this path is towards.
86 * @param path Path itself
87 * @return #GNUNET_YES if should keep iterating.
88 * #GNUNET_NO otherwise.
89 */
90typedef int
91(*GCP_path_iterator) (void *cls,
92 struct CadetPeer *peer,
93 struct CadetPeerPath *path);
94
95
96/******************************************************************************/
97/******************************** API ***********************************/
98/******************************************************************************/
99
100/**
101 * Initialize peer subsystem.
102 * 38 *
103 * @param c Configuration. 39 * @return Static string for it's ID.
104 */
105void
106GCP_init (const struct GNUNET_CONFIGURATION_Handle *c);
107
108/**
109 * Shut down the peer subsystem.
110 */ 40 */
111void 41const char *
112GCP_shutdown (void); 42GCP_2s (const struct CadetPeer *peer);
113 43
114 44
115/** 45/**
116 * Retrieve the CadetPeer stucture associated with the peer. Optionally create 46 * Retrieve the CadetPeer stucture associated with the
117 * one and insert it in the appropriate structures if the peer is not known yet. 47 * peer. Optionally create one and insert it in the appropriate
48 * structures if the peer is not known yet.
118 * 49 *
119 * @param peer_id Full identity of the peer. 50 * @param peer_id Full identity of the peer.
120 * @param create #GNUNET_YES if a new peer should be created if unknown. 51 * @param create #GNUNET_YES if a new peer should be created if unknown.
121 * #GNUNET_NO otherwise. 52 * #GNUNET_NO to return NULL if peer is unknown.
122 *
123 * @return Existing or newly created peer structure. 53 * @return Existing or newly created peer structure.
124 * NULL if unknown and not requested @a create 54 * NULL if unknown and not requested @a create
125 */ 55 */
126struct CadetPeer * 56struct CadetPeer *
127GCP_get (const struct GNUNET_PeerIdentity *peer_id, int create); 57GCP_get (const struct GNUNET_PeerIdentity *peer_id,
58 int create);
128 59
129 60
130/** 61/**
131 * Retrieve the CadetPeer stucture associated with the peer. Optionally create 62 * Calculate how desirable a path is for @a cp if
132 * one and insert it in the appropriate structures if the peer is not known yet. 63 * @a cp is at offset @a off in the path.
133 *
134 * @param peer Short identity of the peer.
135 * @param create #GNUNET_YES if a new peer should be created if unknown.
136 * #GNUNET_NO otherwise.
137 * 64 *
138 * @return Existing or newly created peer structure. 65 * @param cp a peer reachable via a path
139 * NULL if unknown and not requested @a create 66 * @param off offset of @a cp in a path
67 * @return score how useful a path is to reach @a cp,
68 * positive scores mean path is more desirable
140 */ 69 */
141struct CadetPeer * 70double
142GCP_get_short (const GNUNET_PEER_Id peer, int create); 71GCP_get_desirability_of_path (struct CadetPeer *cp,
72 unsigned int off);
143 73
144 74
145/** 75/**
146 * Try to establish a new connection to this peer (in its tunnel). 76 * Obtain the peer identity for a `struct CadetPeer`.
147 * If the peer doesn't have any path to it yet, try to get one.
148 * If the peer already has some path, send a CREATE CONNECTION towards it.
149 *
150 * @param peer Peer to connect to.
151 */
152void
153GCP_connect (struct CadetPeer *peer);
154
155/**
156 * @brief Send a message to another peer (using CORE).
157 * 77 *
158 * @param peer Peer towards which to queue the message. 78 * @param cp our peer handle
159 * @param message Message to send. 79 * @return the peer identity
160 * @param payload_type Type of the message's payload, for debug messages.
161 * 0 if the message is a retransmission (unknown payload).
162 * UINT16_MAX if the message does not have payload.
163 * @param payload_id ID of the payload (MID, ACK #, etc)
164 * @param c Connection this message belongs to (can be NULL).
165 * @param fwd Is this a message going root->dest? (FWD ACK are NOT FWD!)
166 * @param cont Continuation to be called once CORE has sent the message.
167 * @param cont_cls Closure for @c cont.
168 */ 80 */
169struct CadetPeerQueue * 81const struct GNUNET_PeerIdentity *
170GCP_send (struct CadetPeer *peer, 82GCP_get_id (struct CadetPeer *cp);
171 const struct GNUNET_MessageHeader *message,
172 uint16_t payload_type,
173 struct CadetEncryptedMessageIdentifier payload_id,
174 struct CadetConnection *c,
175 int fwd,
176 GCP_sent cont,
177 void *cont_cls);
178 83
179/**
180 * Cancel sending a message. Message must have been sent with
181 * #GCP_send before. May not be called after the notify sent
182 * callback has been called.
183 *
184 * It does NOT call the continuation given to #GCP_send.
185 *
186 * @param q Queue handle to cancel
187 */
188void
189GCP_send_cancel (struct CadetPeerQueue *q);
190 84
191/** 85/**
192 * Set tunnel. 86 * Iterate over all known peers.
193 * 87 *
194 * @param peer Peer. 88 * @param iter Iterator.
195 * @param t Tunnel. 89 * @param cls Closure for @c iter.
196 */ 90 */
197void 91void
198GCP_set_tunnel (struct CadetPeer *peer, struct CadetTunnel *t); 92GCP_iterate_all (GNUNET_CONTAINER_PeerMapIterator iter,
93 void *cls);
199 94
200 95
201/** 96/**
202 * Check whether there is a direct (core level) connection to peer. 97 * Count the number of known paths toward the peer.
203 *
204 * @param peer Peer to check.
205 * 98 *
206 * @return #GNUNET_YES if there is a direct connection. 99 * @param cp Peer to get path info.
100 * @return Number of known paths.
207 */ 101 */
208int 102unsigned int
209GCP_is_neighbor (const struct CadetPeer *peer); 103GCP_count_paths (const struct CadetPeer *cp);
210 104
211 105
212/** 106/**
213 * Create and initialize a new tunnel towards a peer, in case it has none. 107 * Drop all paths owned by this peer, and do not
108 * allow new ones to be added: We are shutting down.
214 * 109 *
215 * Does not generate any traffic, just creates the local data structures. 110 * @param cp peer to drop paths to
216 *
217 * @param peer Peer towards which to create the tunnel.
218 */ 111 */
219void 112void
220GCP_add_tunnel (struct CadetPeer *peer); 113GCP_drop_owned_paths (struct CadetPeer *cp);
221 114
222 115
223/** 116/**
224 * Add a connection to a neighboring peer. 117 * Peer path iterator.
225 *
226 * Store that the peer is the first hop of the connection in one
227 * direction and that on peer disconnect the connection must be
228 * notified and destroyed, for it will no longer be valid.
229 * 118 *
230 * @param peer Peer to add connection to. 119 * @param cls Closure.
231 * @param c Connection to add. 120 * @param path Path itself
232 * @param pred #GNUNET_YES if we are predecessor, #GNUNET_NO if we are successor 121 * @param off offset of the target peer in @a path
122 * @return #GNUNET_YES if should keep iterating.
123 * #GNUNET_NO otherwise.
233 */ 124 */
234void 125typedef int
235GCP_add_connection (struct CadetPeer *peer, 126(*GCP_PathIterator) (void *cls,
236 struct CadetConnection *c, 127 struct CadetPeerPath *path,
237 int pred); 128 unsigned int off);
238 129
239 130
240/** 131/**
241 * Add the path to the peer and update the path used to reach it in case this 132 * Iterate over the paths to a peer.
242 * is the shortest.
243 *
244 * @param peer Destination peer to add the path to.
245 * @param path New path to add. Last peer must be the peer in arg 1.
246 * Path will be either used of freed if already known.
247 * @param trusted Do we trust that this path is real?
248 * 133 *
249 * @return path if path was taken, pointer to existing duplicate if exists 134 * @param cp Peer to get path info.
250 * NULL on error. 135 * @param callback Function to call for every path.
136 * @param callback_cls Closure for @a callback.
137 * @return Number of iterated paths.
251 */ 138 */
252struct CadetPeerPath * 139unsigned int
253GCP_add_path (struct CadetPeer *peer, 140GCP_iterate_paths (struct CadetPeer *cp,
254 struct CadetPeerPath *p, 141 GCP_PathIterator callback,
255 int trusted); 142 void *callback_cls);
256 143
257 144
258/** 145/**
259 * Add the path to the origin peer and update the path used to reach it in case 146 * Iterate over the paths to @a peer where
260 * this is the shortest. 147 * @a peer is at distance @a dist from us.
261 * The path is given in peer_info -> destination, therefore we turn the path
262 * upside down first.
263 *
264 * @param peer Peer to add the path to, being the origin of the path.
265 * @param path New path to add after being inversed.
266 * Path will be either used or freed.
267 * @param trusted Do we trust that this path is real?
268 * 148 *
269 * @return path if path was taken, pointer to existing duplicate if exists 149 * @param cp Peer to get path info.
270 * NULL on error. 150 * @param dist desired distance of @a peer to us on the path
151 * @param callback Function to call for every path.
152 * @param callback_cls Closure for @a callback.
153 * @return Number of iterated paths.
271 */ 154 */
272struct CadetPeerPath * 155unsigned int
273GCP_add_path_to_origin (struct CadetPeer *peer, 156GCP_iterate_paths_at (struct CadetPeer *cp,
274 struct CadetPeerPath *path, 157 unsigned int dist,
275 int trusted); 158 GCP_PathIterator callback,
159 void *callback_cls);
160
276 161
277/** 162/**
278 * Adds a path to the info of all the peers in the path 163 * Remove an entry from the DLL of all of the paths that this peer is on.
279 * 164 *
280 * @param p Path to process. 165 * @param cp peer to modify
281 * @param confirmed Whether we know if the path works or not. 166 * @param entry an entry on a path
167 * @param off offset of this peer on the path
282 */ 168 */
283void 169void
284GCP_add_path_to_all (const struct CadetPeerPath *p, int confirmed); 170GCP_path_entry_remove (struct CadetPeer *cp,
171 struct CadetPeerPathEntry *entry,
172 unsigned int off);
285 173
286 174
287/** 175/**
288 * Remove any path to the peer that has the extact same peers as the one given. 176 * Add an entry to the DLL of all of the paths that this peer is on.
289 * 177 *
290 * @param peer Peer to remove the path from. 178 * @param cp peer to modify
291 * @param path Path to remove. Is always destroyed . 179 * @param entry an entry on a path
180 * @param off offset of this peer on the path
292 */ 181 */
293void 182void
294GCP_remove_path (struct CadetPeer *peer, 183GCP_path_entry_add (struct CadetPeer *cp,
295 struct CadetPeerPath *path); 184 struct CadetPeerPathEntry *entry,
185 unsigned int off);
296 186
297 187
298/** 188/**
299 * Check that we are aware of a connection from a neighboring peer. 189 * Get the tunnel towards a peer.
300 * 190 *
301 * @param peer Peer to the connection is with 191 * @param cp Peer to get from.
302 * @param c Connection that should be in the map with this peer. 192 * @param create #GNUNET_YES to create a tunnel if we do not have one
193 * @return Tunnel towards peer.
303 */ 194 */
304void 195struct CadetTunnel *
305GCP_check_connection (const struct CadetPeer *peer, 196GCP_get_tunnel (struct CadetPeer *cp,
306 const struct CadetConnection *c); 197 int create);
307 198
308 199
309/** 200/**
310 * Remove a connection from a neighboring peer. 201 * The tunnel to the given peer no longer exists, remove it from our
202 * data structures, and possibly clean up the peer itself.
311 * 203 *
312 * @param peer Peer to remove connection from. 204 * @param cp the peer affected
313 * @param c Connection to remove. 205 * @param t the dead tunnel
314 */ 206 */
315void 207void
316GCP_remove_connection (struct CadetPeer *peer, 208GCP_drop_tunnel (struct CadetPeer *cp,
317 const struct CadetConnection *c); 209 struct CadetTunnel *t);
318 210
319 211
320/** 212/**
321 * Start the DHT search for new paths towards the peer: we don't have 213 * Try adding a @a path to this @a cp. If the peer already
322 * enough good connections. 214 * has plenty of paths, return NULL.
323 * 215 *
324 * @param peer Destination peer. 216 * @param cp peer to which the @a path leads to
217 * @param path a path looking for an owner; may not be fully initialized yet!
218 * @param off offset of @a cp in @a path
219 * @param force for attaching the path
220 * @return NULL if this peer does not care to become a new owner,
221 * otherwise the node in the peer's path heap for the @a path.
325 */ 222 */
326void 223struct GNUNET_CONTAINER_HeapNode *
327GCP_start_search (struct CadetPeer *peer); 224GCP_attach_path (struct CadetPeer *cp,
225 struct CadetPeerPath *path,
226 unsigned int off,
227 int force);
328 228
329 229
330/** 230/**
331 * Stop the DHT search for new paths towards the peer: we already have 231 * This peer can no longer own @a path as the path
332 * enough good connections. 232 * has been extended and a peer further down the line
233 * is now the new owner.
333 * 234 *
334 * @param peer Destination peer. 235 * @param cp old owner of the @a path
236 * @param path path where the ownership is lost
237 * @param hn note in @a cp's path heap that must be deleted
335 */ 238 */
336void 239void
337GCP_stop_search (struct CadetPeer *peer); 240GCP_detach_path (struct CadetPeer *cp,
241 struct CadetPeerPath *path,
242 struct GNUNET_CONTAINER_HeapNode *hn);
338 243
339 244
340/** 245/**
341 * Get the Full ID of a peer. 246 * Add a @a connection to this @a cp.
342 * 247 *
343 * @param peer Peer to get from. 248 * @param cp peer via which the @a connection goes
344 * 249 * @param cc the connection to add
345 * @return Full ID of peer.
346 */ 250 */
347const struct GNUNET_PeerIdentity * 251void
348GCP_get_id (const struct CadetPeer *peer); 252GCP_add_connection (struct CadetPeer *cp,
253 struct CadetConnection *cc);
349 254
350 255
351/** 256/**
352 * Get the Short ID of a peer. 257 * Remove a @a connection that went via this @a cp.
353 *
354 * @param peer Peer to get from.
355 * 258 *
356 * @return Short ID of peer. 259 * @param cp peer via which the @a connection went
260 * @param cc the connection to remove
357 */ 261 */
358GNUNET_PEER_Id 262void
359GCP_get_short_id (const struct CadetPeer *peer); 263GCP_remove_connection (struct CadetPeer *cp,
264 struct CadetConnection *cc);
360 265
361 266
362/** 267/**
363 * Get the tunnel towards a peer. 268 * We got a HELLO for a @a cp, remember it, and possibly
269 * trigger adequate actions (like trying to connect).
364 * 270 *
365 * @param peer Peer to get from. 271 * @param cp the peer we got a HELLO for
366 * 272 * @param hello the HELLO to remember
367 * @return Tunnel towards peer.
368 */ 273 */
369struct CadetTunnel * 274void
370GCP_get_tunnel (const struct CadetPeer *peer); 275GCP_set_hello (struct CadetPeer *cp,
276 const struct GNUNET_HELLO_Message *hello);
371 277
372 278
373/** 279/**
374 * Set the hello message. 280 * Clean up all entries about all peers.
375 * 281 * Must only be called after all tunnels, CORE-connections and
376 * @param peer Peer whose message to set. 282 * connections are down.
377 * @param hello Hello message.
378 */ 283 */
379void 284void
380GCP_set_hello (struct CadetPeer *peer, 285GCP_destroy_all_peers (void);
381 const struct GNUNET_HELLO_Message *hello);
382 286
383 287
384/** 288/**
385 * Get the hello message. 289 * Data structure used to track whom we have to notify about changes
386 * 290 * in our ability to transmit to a given peer.
387 * @param peer Peer whose message to get.
388 * 291 *
389 * @return Hello message. 292 * All queue managers will be given equal chance for sending messages
293 * to @a cp. This construct this guarantees fairness for access to @a
294 * cp among the different message queues. Each connection or route
295 * will have its respective message queue managers for each direction.
390 */ 296 */
391struct GNUNET_HELLO_Message * 297struct GCP_MessageQueueManager;
392GCP_get_hello (struct CadetPeer *peer);
393 298
394 299
395/** 300/**
396 * Try to connect to a peer on TRANSPORT level. 301 * Function to call with updated message queue object.
397 * 302 *
398 * @param peer Peer to whom to connect. 303 * @param cls closure
304 * @param available #GNUNET_YES if sending is now possible,
305 * #GNUNET_NO if sending is no longer possible
306 * #GNUNET_SYSERR if sending is no longer possible
307 * and the last envelope was discarded
399 */ 308 */
400void 309typedef void
401GCP_try_connect (struct CadetPeer *peer); 310(*GCP_MessageQueueNotificationCallback)(void *cls,
311 int available);
312
402 313
403/** 314/**
404 * Notify a peer that a link between two other peers is broken. If any path 315 * Start message queue change notifications. Will create a new slot
405 * used that link, eliminate it. 316 * to manage the message queue to the given @a cp.
406 * 317 *
407 * @param peer Peer affected by the change. 318 * @param cp peer to notify for
408 * @param peer1 Peer whose link is broken. 319 * @param cb function to call if mq becomes available or unavailable
409 * @param peer2 Peer whose link is broken. 320 * @param cb_cls closure for @a cb
321 * @return handle to cancel request
410 */ 322 */
411void 323struct GCP_MessageQueueManager *
412GCP_notify_broken_link (struct CadetPeer *peer, 324GCP_request_mq (struct CadetPeer *cp,
413 const struct GNUNET_PeerIdentity *peer1, 325 GCP_MessageQueueNotificationCallback cb,
414 const struct GNUNET_PeerIdentity *peer2); 326 void *cb_cls);
415 327
416 328
417/** 329/**
418 * Count the number of known paths toward the peer. 330 * Test if @a cp has a core-level connection
419 * 331 *
420 * @param peer Peer to get path info. 332 * @param cp peer to test
421 * 333 * @return #GNUNET_YES if @a cp has a core-level connection
422 * @return Number of known paths.
423 */ 334 */
424unsigned int 335int
425GCP_count_paths (const struct CadetPeer *peer); 336GCP_has_core_connection (struct CadetPeer *cp);
337
426 338
427/** 339/**
428 * Iterate over the paths to a peer. 340 * Send the message in @a env via a @a mqm. Must only be called at
341 * most once after the respective
342 * #GCP_MessageQueueNotificationCallback was called with `available`
343 * set to #GNUNET_YES, and not after the callback was called with
344 * `available` set to #GNUNET_NO or #GNUNET_SYSERR.
429 * 345 *
430 * @param peer Peer to get path info. 346 * @param mqm message queue manager for the transmission
431 * @param callback Function to call for every path. 347 * @param env envelope with the message to send; must NOT
432 * @param cls Closure for @a callback. 348 * yet have a #GNUNET_MQ_notify_sent() callback attached to it
433 *
434 * @return Number of iterated paths.
435 */ 349 */
436unsigned int 350void
437GCP_iterate_paths (struct CadetPeer *peer, 351GCP_send (struct GCP_MessageQueueManager *mqm,
438 GCP_path_iterator callback, 352 struct GNUNET_MQ_Envelope *env);
439 void *cls);
440 353
441 354
442/** 355/**
443 * Iterate all known peers. 356 * Send the message in @a env to @a cp, overriding queueing logic.
357 * This function should only be used to send error messages outside
358 * of flow and congestion control, similar to ICMP. Note that
359 * the envelope may be silently discarded as well.
444 * 360 *
445 * @param iter Iterator. 361 * @param cp peer to send the message to
446 * @param cls Closure for @c iter. 362 * @param env envelope with the message to send
447 */ 363 */
448void 364void
449GCP_iterate_all (GNUNET_CONTAINER_PeerMapIterator iter, 365GCP_send_ooo (struct CadetPeer *cp,
450 void *cls); 366 struct GNUNET_MQ_Envelope *env);
451 367
452 368
453/** 369/**
454 * Get the static string for a peer ID. 370 * Stops message queue change notifications and sends a last message.
455 * 371 * In practice, this is implemented by sending that @a last_env
456 * @param peer Peer. 372 * message immediately (if any), ignoring queue order.
457 * 373 *
458 * @return Static string for it's ID. 374 * @param mqm handle matching request to cancel
375 * @param last_env final message to transmit, or NULL
459 */ 376 */
460const char * 377void
461GCP_2s (const struct CadetPeer *peer); 378GCP_request_mq_cancel (struct GCP_MessageQueueManager *mqm,
379 struct GNUNET_MQ_Envelope *last_env);
462 380
463 381
464/** 382/**
465 * Log all kinds of info about a peer. 383 * Set the message queue to @a mq for peer @a cp and notify watchers.
466 * 384 *
467 * @param peer Peer. 385 * @param cp peer to modify
386 * @param mq message queue to set (can be NULL)
468 */ 387 */
469void 388void
470GCP_debug (const struct CadetPeer *p, 389GCP_set_mq (struct CadetPeer *cp,
471 enum GNUNET_ErrorType level); 390 struct GNUNET_MQ_Handle *mq);
472
473 391
474#if 0 /* keep Emacsens' auto-indent happy */
475{
476#endif
477#ifdef __cplusplus
478}
479#endif
480 392
481/* ifndef GNUNET_CADET_SERVICE_PEER_H */
482#endif 393#endif
483/* end of gnunet-cadet-service_peer.h */
diff --git a/src/cadet/gnunet-service-cadet_tunnel.c b/src/cadet/gnunet-service-cadet_tunnel.c
deleted file mode 100644
index 3b21f4107..000000000
--- a/src/cadet/gnunet-service-cadet_tunnel.c
+++ /dev/null
@@ -1,3501 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2013, 2017 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 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 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20/**
21 * @file cadet/gnunet-service-cadet_tunnel.c
22 * @brief logical links between CADET clients
23 * @author Bartlomiej Polot
24 */
25#include "platform.h"
26#include "gnunet_util_lib.h"
27#include "gnunet_signatures.h"
28#include "gnunet_statistics_service.h"
29#include "cadet_protocol.h"
30#include "cadet_path.h"
31#include "gnunet-service-cadet_tunnel.h"
32#include "gnunet-service-cadet_connection.h"
33#include "gnunet-service-cadet_channel.h"
34#include "gnunet-service-cadet_peer.h"
35
36#define LOG(level, ...) GNUNET_log_from(level,"cadet-tun",__VA_ARGS__)
37#define LOG2(level, ...) GNUNET_log_from_nocheck(level,"cadet-tun",__VA_ARGS__)
38
39#define REKEY_WAIT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 5)
40
41#if !defined(GNUNET_CULL_LOGGING)
42 #define DUMP_KEYS_TO_STDERR GNUNET_YES
43#else
44 #define DUMP_KEYS_TO_STDERR GNUNET_NO
45#endif
46
47#define MIN_TUNNEL_BUFFER 8
48#define MAX_TUNNEL_BUFFER 64
49#define MAX_SKIPPED_KEYS 64
50#define MAX_KEY_GAP 256
51#define AX_HEADER_SIZE (sizeof (uint32_t) * 2\
52 + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey))
53
54/******************************************************************************/
55/******************************** STRUCTS **********************************/
56/******************************************************************************/
57
58struct CadetTChannel
59{
60 struct CadetTChannel *next;
61 struct CadetTChannel *prev;
62 struct CadetChannel *ch;
63};
64
65
66/**
67 * Entry in list of connections used by tunnel, with metadata.
68 */
69struct CadetTConnection
70{
71 /**
72 * Next in DLL.
73 */
74 struct CadetTConnection *next;
75
76 /**
77 * Prev in DLL.
78 */
79 struct CadetTConnection *prev;
80
81 /**
82 * Connection handle.
83 */
84 struct CadetConnection *c;
85
86 /**
87 * Creation time, to keep oldest connection alive.
88 */
89 struct GNUNET_TIME_Absolute created;
90
91 /**
92 * Connection throughput, to keep fastest connection alive.
93 */
94 uint32_t throughput;
95};
96
97
98/**
99 * Struct to old keys for skipped messages while advancing the Axolotl ratchet.
100 */
101struct CadetTunnelSkippedKey
102{
103 /**
104 * DLL next.
105 */
106 struct CadetTunnelSkippedKey *next;
107
108 /**
109 * DLL prev.
110 */
111 struct CadetTunnelSkippedKey *prev;
112
113 /**
114 * When was this key stored (for timeout).
115 */
116 struct GNUNET_TIME_Absolute timestamp;
117
118 /**
119 * Header key.
120 */
121 struct GNUNET_CRYPTO_SymmetricSessionKey HK;
122
123 /**
124 * Message key.
125 */
126 struct GNUNET_CRYPTO_SymmetricSessionKey MK;
127
128 /**
129 * Key number for a given HK.
130 */
131 unsigned int Kn;
132};
133
134
135/**
136 * Axolotl data, according to https://github.com/trevp/axolotl/wiki .
137 */
138struct CadetTunnelAxolotl
139{
140 /**
141 * A (double linked) list of stored message keys and associated header keys
142 * for "skipped" messages, i.e. messages that have not been
143 * received despite the reception of more recent messages, (head).
144 */
145 struct CadetTunnelSkippedKey *skipped_head;
146
147 /**
148 * Skipped messages' keys DLL, tail.
149 */
150 struct CadetTunnelSkippedKey *skipped_tail;
151
152 /**
153 * Elements in @a skipped_head <-> @a skipped_tail.
154 */
155 unsigned int skipped;
156
157 /**
158 * 32-byte root key which gets updated by DH ratchet.
159 */
160 struct GNUNET_CRYPTO_SymmetricSessionKey RK;
161
162 /**
163 * 32-byte header key (send).
164 */
165 struct GNUNET_CRYPTO_SymmetricSessionKey HKs;
166
167 /**
168 * 32-byte header key (recv)
169 */
170 struct GNUNET_CRYPTO_SymmetricSessionKey HKr;
171
172 /**
173 * 32-byte next header key (send).
174 */
175 struct GNUNET_CRYPTO_SymmetricSessionKey NHKs;
176
177 /**
178 * 32-byte next header key (recv).
179 */
180 struct GNUNET_CRYPTO_SymmetricSessionKey NHKr;
181
182 /**
183 * 32-byte chain keys (used for forward-secrecy updating, send).
184 */
185 struct GNUNET_CRYPTO_SymmetricSessionKey CKs;
186
187 /**
188 * 32-byte chain keys (used for forward-secrecy updating, recv).
189 */
190 struct GNUNET_CRYPTO_SymmetricSessionKey CKr;
191
192 /**
193 * ECDH for key exchange (A0 / B0).
194 */
195 struct GNUNET_CRYPTO_EcdhePrivateKey *kx_0;
196
197 /**
198 * ECDH Ratchet key (send).
199 */
200 struct GNUNET_CRYPTO_EcdhePrivateKey *DHRs;
201
202 /**
203 * ECDH Ratchet key (recv).
204 */
205 struct GNUNET_CRYPTO_EcdhePublicKey DHRr;
206
207 /**
208 * Message number (reset to 0 with each new ratchet, next message to send).
209 */
210 uint32_t Ns;
211
212 /**
213 * Message number (reset to 0 with each new ratchet, next message to recv).
214 */
215 uint32_t Nr;
216
217 /**
218 * Previous message numbers (# of msgs sent under prev ratchet)
219 */
220 uint32_t PNs;
221
222 /**
223 * True (#GNUNET_YES) if we have to send a new ratchet key in next msg.
224 */
225 int ratchet_flag;
226
227 /**
228 * Number of messages recieved since our last ratchet advance.
229 * - If this counter = 0, we cannot send a new ratchet key in next msg.
230 * - If this counter > 0, we can (but don't yet have to) send a new key.
231 */
232 unsigned int ratchet_allowed;
233
234 /**
235 * Number of messages recieved since our last ratchet advance.
236 * - If this counter = 0, we cannot send a new ratchet key in next msg.
237 * - If this counter > 0, we can (but don't yet have to) send a new key.
238 */
239 unsigned int ratchet_counter;
240
241 /**
242 * When does this ratchet expire and a new one is triggered.
243 */
244 struct GNUNET_TIME_Absolute ratchet_expiration;
245};
246
247
248/**
249 * Struct containing all information regarding a tunnel to a peer.
250 */
251struct CadetTunnel
252{
253 /**
254 * Endpoint of the tunnel.
255 */
256 struct CadetPeer *peer;
257
258 /**
259 * Axolotl info.
260 */
261 struct CadetTunnelAxolotl *ax;
262
263 /**
264 * State of the tunnel connectivity.
265 */
266 enum CadetTunnelCState cstate;
267
268 /**
269 * State of the tunnel encryption.
270 */
271 enum CadetTunnelEState estate;
272
273 /**
274 * Peer's ephemeral key, to recreate @c e_key and @c d_key when own ephemeral
275 * key changes.
276 */
277 struct GNUNET_CRYPTO_EcdhePublicKey peers_ephemeral_key;
278
279 /**
280 * Encryption ("our") key. It is only "confirmed" if kx_ctx is NULL.
281 */
282 struct GNUNET_CRYPTO_SymmetricSessionKey e_key;
283
284 /**
285 * Decryption ("their") key. It is only "confirmed" if kx_ctx is NULL.
286 */
287 struct GNUNET_CRYPTO_SymmetricSessionKey d_key;
288
289 /**
290 * Task to start the rekey process.
291 */
292 struct GNUNET_SCHEDULER_Task *rekey_task;
293
294 /**
295 * Paths that are actively used to reach the destination peer.
296 */
297 struct CadetTConnection *connection_head;
298 struct CadetTConnection *connection_tail;
299
300 /**
301 * Next connection number.
302 */
303 uint32_t next_cid;
304
305 /**
306 * Channels inside this tunnel.
307 */
308 struct CadetTChannel *channel_head;
309 struct CadetTChannel *channel_tail;
310
311 /**
312 * Channel ID for the next created channel.
313 */
314 struct GNUNET_CADET_ChannelTunnelNumber next_ctn;
315
316 /**
317 * Destroy flag: if true, destroy on last message.
318 */
319 struct GNUNET_SCHEDULER_Task * destroy_task;
320
321 /**
322 * Queued messages, to transmit once tunnel gets connected.
323 */
324 struct CadetTunnelDelayed *tq_head;
325 struct CadetTunnelDelayed *tq_tail;
326
327 /**
328 * Task to trim connections if too many are present.
329 */
330 struct GNUNET_SCHEDULER_Task * trim_connections_task;
331
332 /**
333 * Ephemeral message in the queue (to avoid queueing more than one).
334 */
335 struct CadetConnectionQueue *ephm_h;
336
337 /**
338 * Pong message in the queue.
339 */
340 struct CadetConnectionQueue *pong_h;
341};
342
343
344/**
345 * Struct used to save messages in a non-ready tunnel to send once connected.
346 */
347struct CadetTunnelDelayed
348{
349 /**
350 * DLL
351 */
352 struct CadetTunnelDelayed *next;
353 struct CadetTunnelDelayed *prev;
354
355 /**
356 * Tunnel.
357 */
358 struct CadetTunnel *t;
359
360 /**
361 * Tunnel queue given to the channel to cancel request. Update on send_queued.
362 */
363 struct CadetTunnelQueue *tq;
364
365 /**
366 * Message to send.
367 */
368 /* struct GNUNET_MessageHeader *msg; */
369};
370
371
372/**
373 * Handle for messages queued but not yet sent.
374 */
375struct CadetTunnelQueue
376{
377 /**
378 * Connection queue handle, to cancel if necessary.
379 */
380 struct CadetConnectionQueue *cq;
381
382 /**
383 * Handle in case message hasn't been given to a connection yet.
384 */
385 struct CadetTunnelDelayed *tqd;
386
387 /**
388 * Continuation to call once sent.
389 */
390 GCT_sent cont;
391
392 /**
393 * Closure for @c cont.
394 */
395 void *cont_cls;
396};
397
398
399/******************************************************************************/
400/******************************* GLOBALS ***********************************/
401/******************************************************************************/
402
403/**
404 * Global handle to the statistics service.
405 */
406extern struct GNUNET_STATISTICS_Handle *stats;
407
408/**
409 * Local peer own ID (memory efficient handle).
410 */
411extern GNUNET_PEER_Id myid;
412
413/**
414 * Local peer own ID (full value).
415 */
416extern struct GNUNET_PeerIdentity my_full_id;
417
418
419/**
420 * Don't try to recover tunnels if shutting down.
421 */
422extern int shutting_down;
423
424
425/**
426 * Set of all tunnels, in order to trigger a new exchange on rekey.
427 * Indexed by peer's ID.
428 */
429static struct GNUNET_CONTAINER_MultiPeerMap *tunnels;
430
431/**
432 * Own Peer ID private key.
433 */
434const static struct GNUNET_CRYPTO_EddsaPrivateKey *id_key;
435
436
437/******************************** AXOLOTL ************************************/
438
439/**
440 * How many messages are needed to trigger a ratchet advance.
441 */
442static unsigned long long ratchet_messages;
443
444/**
445 * How long until we trigger a ratched advance.
446 */
447static struct GNUNET_TIME_Relative ratchet_time;
448
449
450/******************************************************************************/
451/******************************** STATIC ***********************************/
452/******************************************************************************/
453
454/**
455 * Get string description for tunnel connectivity state.
456 *
457 * @param cs Tunnel state.
458 *
459 * @return String representation.
460 */
461static const char *
462cstate2s (enum CadetTunnelCState cs)
463{
464 static char buf[32];
465
466 switch (cs)
467 {
468 case CADET_TUNNEL_NEW:
469 return "CADET_TUNNEL_NEW";
470 case CADET_TUNNEL_SEARCHING:
471 return "CADET_TUNNEL_SEARCHING";
472 case CADET_TUNNEL_WAITING:
473 return "CADET_TUNNEL_WAITING";
474 case CADET_TUNNEL_READY:
475 return "CADET_TUNNEL_READY";
476 case CADET_TUNNEL_SHUTDOWN:
477 return "CADET_TUNNEL_SHUTDOWN";
478 default:
479 SPRINTF (buf, "%u (UNKNOWN STATE)", cs);
480 return buf;
481 }
482 return "";
483}
484
485
486/**
487 * Get string description for tunnel encryption state.
488 *
489 * @param es Tunnel state.
490 *
491 * @return String representation.
492 */
493static const char *
494estate2s (enum CadetTunnelEState es)
495{
496 static char buf[32];
497
498 switch (es)
499 {
500 case CADET_TUNNEL_KEY_UNINITIALIZED:
501 return "CADET_TUNNEL_KEY_UNINITIALIZED";
502 case CADET_TUNNEL_KEY_SENT:
503 return "CADET_TUNNEL_KEY_SENT";
504 case CADET_TUNNEL_KEY_PING:
505 return "CADET_TUNNEL_KEY_PING";
506 case CADET_TUNNEL_KEY_OK:
507 return "CADET_TUNNEL_KEY_OK";
508 case CADET_TUNNEL_KEY_REKEY:
509 return "CADET_TUNNEL_KEY_REKEY";
510 default:
511 SPRINTF (buf, "%u (UNKNOWN STATE)", es);
512 return buf;
513 }
514 return "";
515}
516
517
518/**
519 * @brief Check if tunnel is ready to send traffic.
520 *
521 * Tunnel must be connected and with encryption correctly set up.
522 *
523 * @param t Tunnel to check.
524 *
525 * @return #GNUNET_YES if ready, #GNUNET_NO otherwise
526 */
527static int
528is_ready (struct CadetTunnel *t)
529{
530 int ready;
531 int conn_ok;
532 int enc_ok;
533
534 conn_ok = CADET_TUNNEL_READY == t->cstate;
535 enc_ok = CADET_TUNNEL_KEY_OK == t->estate
536 || CADET_TUNNEL_KEY_REKEY == t->estate
537 || CADET_TUNNEL_KEY_PING == t->estate;
538 ready = conn_ok && enc_ok;
539 ready = ready || GCT_is_loopback (t);
540 return ready;
541}
542
543
544/**
545 * Get the channel's buffer. ONLY FOR NON-LOOPBACK CHANNELS!!
546 *
547 * @param tch Tunnel's channel handle.
548 *
549 * @return Amount of messages the channel can still buffer towards the client.
550 */
551static unsigned int
552get_channel_buffer (const struct CadetTChannel *tch)
553{
554 int fwd;
555
556 /* If channel is incoming, is terminal in the FWD direction and fwd is YES */
557 fwd = GCCH_is_terminal (tch->ch, GNUNET_YES);
558
559 return GCCH_get_buffer (tch->ch, fwd);
560}
561
562
563/**
564 * Get the channel's allowance status.
565 *
566 * @param tch Tunnel's channel handle.
567 *
568 * @return #GNUNET_YES if we allowed the client to send data to us.
569 */
570static int
571get_channel_allowed (const struct CadetTChannel *tch)
572{
573 int fwd;
574
575 /* If channel is outgoing, is origin in the FWD direction and fwd is YES */
576 fwd = GCCH_is_origin (tch->ch, GNUNET_YES);
577
578 return GCCH_get_allowed (tch->ch, fwd);
579}
580
581
582/**
583 * Get the connection's buffer.
584 *
585 * @param tc Tunnel's connection handle.
586 *
587 * @return Amount of messages the connection can still buffer.
588 */
589static unsigned int
590get_connection_buffer (const struct CadetTConnection *tc)
591{
592 int fwd;
593
594 /* If connection is outgoing, is origin in the FWD direction and fwd is YES */
595 fwd = GCC_is_origin (tc->c, GNUNET_YES);
596
597 return GCC_get_buffer (tc->c, fwd);
598}
599
600
601/**
602 * Get the connection's allowance.
603 *
604 * @param tc Tunnel's connection handle.
605 *
606 * @return Amount of messages we have allowed the next peer to send us.
607 */
608static unsigned int
609get_connection_allowed (const struct CadetTConnection *tc)
610{
611 int fwd;
612
613 /* If connection is outgoing, is origin in the FWD direction and fwd is YES */
614 fwd = GCC_is_origin (tc->c, GNUNET_YES);
615
616 return GCC_get_allowed (tc->c, fwd);
617}
618
619
620/**
621 * Create a new Axolotl ephemeral (ratchet) key.
622 *
623 * @param t Tunnel.
624 */
625static void
626new_ephemeral (struct CadetTunnel *t)
627{
628 GNUNET_free_non_null (t->ax->DHRs);
629 t->ax->DHRs = GNUNET_CRYPTO_ecdhe_key_create();
630 #if DUMP_KEYS_TO_STDERR
631 {
632 struct GNUNET_CRYPTO_EcdhePublicKey pub;
633 GNUNET_CRYPTO_ecdhe_key_get_public (t->ax->DHRs, &pub);
634 LOG (GNUNET_ERROR_TYPE_DEBUG, " new DHRs generated: pub %s\n",
635 GNUNET_i2s ((struct GNUNET_PeerIdentity *) &pub));
636 }
637 #endif
638}
639
640
641/**
642 * Calculate HMAC.
643 *
644 * @param plaintext Content to HMAC.
645 * @param size Size of @c plaintext.
646 * @param iv Initialization vector for the message.
647 * @param key Key to use.
648 * @param hmac[out] Destination to store the HMAC.
649 */
650static void
651t_hmac (const void *plaintext, size_t size,
652 uint32_t iv, const struct GNUNET_CRYPTO_SymmetricSessionKey *key,
653 struct GNUNET_ShortHashCode *hmac)
654{
655 static const char ctx[] = "cadet authentication key";
656 struct GNUNET_CRYPTO_AuthKey auth_key;
657 struct GNUNET_HashCode hash;
658
659#if DUMP_KEYS_TO_STDERR
660 LOG (GNUNET_ERROR_TYPE_INFO, " HMAC %u bytes with key %s\n", size,
661 GNUNET_i2s ((struct GNUNET_PeerIdentity *) key));
662#endif
663 GNUNET_CRYPTO_hmac_derive_key (&auth_key, key,
664 &iv, sizeof (iv),
665 key, sizeof (*key),
666 ctx, sizeof (ctx),
667 NULL);
668 /* Two step: CADET_Hash is only 256 bits, HashCode is 512. */
669 GNUNET_CRYPTO_hmac (&auth_key, plaintext, size, &hash);
670 GNUNET_memcpy (hmac, &hash, sizeof (*hmac));
671}
672
673
674/**
675 * Perform a HMAC.
676 *
677 * @param key Key to use.
678 * @param hash[out] Resulting HMAC.
679 * @param source Source key material (data to HMAC).
680 * @param len Length of @a source.
681 */
682static void
683t_ax_hmac_hash (struct GNUNET_CRYPTO_SymmetricSessionKey *key,
684 struct GNUNET_HashCode *hash,
685 void *source, unsigned int len)
686{
687 static const char ctx[] = "axolotl HMAC-HASH";
688 struct GNUNET_CRYPTO_AuthKey auth_key;
689
690 GNUNET_CRYPTO_hmac_derive_key (&auth_key, key,
691 ctx, sizeof (ctx),
692 NULL);
693 GNUNET_CRYPTO_hmac (&auth_key, source, len, hash);
694}
695
696
697/**
698 * Derive a key from a HMAC-HASH.
699 *
700 * @param key Key to use for the HMAC.
701 * @param out Key to generate.
702 * @param source Source key material (data to HMAC).
703 * @param len Length of @a source.
704 */
705static void
706t_hmac_derive_key (struct GNUNET_CRYPTO_SymmetricSessionKey *key,
707 struct GNUNET_CRYPTO_SymmetricSessionKey *out,
708 void *source, unsigned int len)
709{
710 static const char ctx[] = "axolotl derive key";
711 struct GNUNET_HashCode h;
712
713 t_ax_hmac_hash (key, &h, source, len);
714 GNUNET_CRYPTO_kdf (out, sizeof (*out), ctx, sizeof (ctx),
715 &h, sizeof (h), NULL);
716}
717
718
719/**
720 * Encrypt data with the axolotl tunnel key.
721 *
722 * @param t Tunnel whose key to use.
723 * @param dst Destination for the encrypted data.
724 * @param src Source of the plaintext. Can overlap with @c dst.
725 * @param size Size of the plaintext.
726 *
727 * @return Size of the encrypted data.
728 */
729static int
730t_ax_encrypt (struct CadetTunnel *t, void *dst, const void *src, size_t size)
731{
732 struct GNUNET_CRYPTO_SymmetricSessionKey MK;
733 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
734 struct CadetTunnelAxolotl *ax;
735 size_t out_size;
736
737 CADET_TIMING_START;
738
739 ax = t->ax;
740 ax->ratchet_counter++;
741 if (GNUNET_YES == ax->ratchet_allowed
742 && (ratchet_messages <= ax->ratchet_counter
743 || 0 == GNUNET_TIME_absolute_get_remaining (ax->ratchet_expiration).rel_value_us))
744 {
745 ax->ratchet_flag = GNUNET_YES;
746 }
747
748 if (GNUNET_YES == ax->ratchet_flag)
749 {
750 /* Advance ratchet */
751 struct GNUNET_CRYPTO_SymmetricSessionKey keys[3];
752 struct GNUNET_HashCode dh;
753 struct GNUNET_HashCode hmac;
754 static const char ctx[] = "axolotl ratchet";
755
756 new_ephemeral (t);
757 ax->HKs = ax->NHKs;
758
759 /* RK, NHKs, CKs = KDF( HMAC-HASH(RK, DH(DHRs, DHRr)) ) */
760 GNUNET_CRYPTO_ecc_ecdh (ax->DHRs, &ax->DHRr, &dh);
761 t_ax_hmac_hash (&ax->RK, &hmac, &dh, sizeof (dh));
762 GNUNET_CRYPTO_kdf (keys, sizeof (keys), ctx, sizeof (ctx),
763 &hmac, sizeof (hmac), NULL);
764 ax->RK = keys[0];
765 ax->NHKs = keys[1];
766 ax->CKs = keys[2];
767
768 ax->PNs = ax->Ns;
769 ax->Ns = 0;
770 ax->ratchet_flag = GNUNET_NO;
771 ax->ratchet_allowed = GNUNET_NO;
772 ax->ratchet_counter = 0;
773 ax->ratchet_expiration =
774 GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(), ratchet_time);
775 }
776
777 t_hmac_derive_key (&ax->CKs, &MK, "0", 1);
778 GNUNET_CRYPTO_symmetric_derive_iv (&iv, &MK, NULL, 0, NULL);
779
780 #if DUMP_KEYS_TO_STDERR
781 LOG (GNUNET_ERROR_TYPE_DEBUG, " CKs: %s\n",
782 GNUNET_i2s ((struct GNUNET_PeerIdentity *) &ax->CKs));
783 LOG (GNUNET_ERROR_TYPE_INFO, " AX_ENC with key %u: %s\n", ax->Ns,
784 GNUNET_i2s ((struct GNUNET_PeerIdentity *) &MK));
785 #endif
786
787 out_size = GNUNET_CRYPTO_symmetric_encrypt (src, size, &MK, &iv, dst);
788 t_hmac_derive_key (&ax->CKs, &ax->CKs, "1", 1);
789
790 CADET_TIMING_END;
791
792 return out_size;
793}
794
795
796/**
797 * Decrypt data with the axolotl tunnel key.
798 *
799 * @param t Tunnel whose key to use.
800 * @param dst Destination for the decrypted data.
801 * @param src Source of the ciphertext. Can overlap with @c dst.
802 * @param size Size of the ciphertext.
803 *
804 * @return Size of the decrypted data.
805 */
806static int
807t_ax_decrypt (struct CadetTunnel *t, void *dst, const void *src, size_t size)
808{
809 struct GNUNET_CRYPTO_SymmetricSessionKey MK;
810 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
811 struct CadetTunnelAxolotl *ax;
812 size_t out_size;
813
814 CADET_TIMING_START;
815
816 ax = t->ax;
817
818 t_hmac_derive_key (&ax->CKr, &MK, "0", 1);
819 GNUNET_CRYPTO_symmetric_derive_iv (&iv, &MK, NULL, 0, NULL);
820
821 #if DUMP_KEYS_TO_STDERR
822 LOG (GNUNET_ERROR_TYPE_DEBUG, " CKr: %s\n",
823 GNUNET_i2s ((struct GNUNET_PeerIdentity *) &ax->CKr));
824 LOG (GNUNET_ERROR_TYPE_INFO, " AX_DEC with key %u: %s\n", ax->Nr,
825 GNUNET_i2s ((struct GNUNET_PeerIdentity *) &MK));
826 #endif
827
828 GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader));
829 out_size = GNUNET_CRYPTO_symmetric_decrypt (src, size, &MK, &iv, dst);
830 GNUNET_assert (out_size == size);
831
832 t_hmac_derive_key (&ax->CKr, &ax->CKr, "1", 1);
833
834 CADET_TIMING_END;
835
836 return out_size;
837}
838
839
840/**
841 * Encrypt header with the axolotl header key.
842 *
843 * @param t Tunnel whose key to use.
844 * @param msg Message whose header to encrypt.
845 */
846static void
847t_h_encrypt (struct CadetTunnel *t, struct GNUNET_CADET_TunnelEncryptedMessage *msg)
848{
849 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
850 struct CadetTunnelAxolotl *ax;
851 size_t out_size;
852
853 CADET_TIMING_START;
854 ax = t->ax;
855 GNUNET_CRYPTO_symmetric_derive_iv (&iv, &ax->HKs, NULL, 0, NULL);
856
857 #if DUMP_KEYS_TO_STDERR
858 LOG (GNUNET_ERROR_TYPE_INFO, " AX_ENC_H with key %s\n",
859 GNUNET_i2s ((struct GNUNET_PeerIdentity *) &ax->HKs));
860 #endif
861
862 out_size = GNUNET_CRYPTO_symmetric_encrypt (&msg->Ns, AX_HEADER_SIZE,
863 &ax->HKs, &iv, &msg->Ns);
864
865 GNUNET_assert (AX_HEADER_SIZE == out_size);
866 CADET_TIMING_END;
867}
868
869
870/**
871 * Decrypt header with the current axolotl header key.
872 *
873 * @param t Tunnel whose current ax HK to use.
874 * @param src Message whose header to decrypt.
875 * @param dst Where to decrypt header to.
876 */
877static void
878t_h_decrypt (struct CadetTunnel *t, const struct GNUNET_CADET_TunnelEncryptedMessage *src,
879 struct GNUNET_CADET_TunnelEncryptedMessage *dst)
880{
881 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
882 struct CadetTunnelAxolotl *ax;
883 size_t out_size;
884
885 CADET_TIMING_START;
886
887 ax = t->ax;
888 GNUNET_CRYPTO_symmetric_derive_iv (&iv, &ax->HKr, NULL, 0, NULL);
889
890 #if DUMP_KEYS_TO_STDERR
891 LOG (GNUNET_ERROR_TYPE_INFO, " AX_DEC_H with key %s\n",
892 GNUNET_i2s ((struct GNUNET_PeerIdentity *) &ax->HKr));
893 #endif
894
895 out_size = GNUNET_CRYPTO_symmetric_decrypt (&src->Ns, AX_HEADER_SIZE,
896 &ax->HKr, &iv, &dst->Ns);
897
898 GNUNET_assert (AX_HEADER_SIZE == out_size);
899
900 CADET_TIMING_END;
901}
902
903
904/**
905 * Decrypt and verify data with the appropriate tunnel key and verify that the
906 * data has not been altered since it was sent by the remote peer.
907 *
908 * @param t Tunnel whose key to use.
909 * @param dst Destination for the plaintext.
910 * @param src Source of the message. Can overlap with @c dst.
911 * @param size Size of the message.
912 *
913 * @return Size of the decrypted data, -1 if an error was encountered.
914 */
915static int
916try_old_ax_keys (struct CadetTunnel *t, void *dst,
917 const struct GNUNET_CADET_TunnelEncryptedMessage *src, size_t size)
918{
919 struct CadetTunnelSkippedKey *key;
920 struct GNUNET_ShortHashCode *hmac;
921 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
922 struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header;
923 struct GNUNET_CRYPTO_SymmetricSessionKey *valid_HK;
924 size_t esize;
925 size_t res;
926 size_t len;
927 unsigned int N;
928
929 LOG (GNUNET_ERROR_TYPE_DEBUG, "Trying old keys\n");
930 hmac = &plaintext_header.hmac;
931 esize = size - sizeof (struct GNUNET_CADET_TunnelEncryptedMessage);
932
933 /* Find a correct Header Key */
934 for (key = t->ax->skipped_head; NULL != key; key = key->next)
935 {
936 #if DUMP_KEYS_TO_STDERR
937 LOG (GNUNET_ERROR_TYPE_DEBUG, " Trying hmac with key %s\n",
938 GNUNET_i2s ((struct GNUNET_PeerIdentity *) &key->HK));
939 #endif
940 t_hmac (&src->Ns, AX_HEADER_SIZE + esize, 0, &key->HK, hmac);
941 if (0 == memcmp (hmac, &src->hmac, sizeof (*hmac)))
942 {
943 LOG (GNUNET_ERROR_TYPE_DEBUG, " hmac correct\n");
944 valid_HK = &key->HK;
945 break;
946 }
947 }
948 if (NULL == key)
949 return -1;
950
951 /* Should've been checked in -cadet_connection.c handle_cadet_encrypted. */
952 GNUNET_assert (size > sizeof (struct GNUNET_CADET_TunnelEncryptedMessage));
953 len = size - sizeof (struct GNUNET_CADET_TunnelEncryptedMessage);
954 GNUNET_assert (len >= sizeof (struct GNUNET_MessageHeader));
955
956 /* Decrypt header */
957 GNUNET_CRYPTO_symmetric_derive_iv (&iv, &key->HK, NULL, 0, NULL);
958 res = GNUNET_CRYPTO_symmetric_decrypt (&src->Ns, AX_HEADER_SIZE,
959 &key->HK, &iv, &plaintext_header.Ns);
960 GNUNET_assert (AX_HEADER_SIZE == res);
961 LOG (GNUNET_ERROR_TYPE_DEBUG, " Message %u, previous: %u\n",
962 ntohl (plaintext_header.Ns), ntohl (plaintext_header.PNs));
963
964 /* Find the correct Message Key */
965 N = ntohl (plaintext_header.Ns);
966 while (NULL != key && N != key->Kn)
967 key = key->next;
968 if (NULL == key || 0 != memcmp (&key->HK, valid_HK, sizeof (*valid_HK)))
969 return -1;
970
971 #if DUMP_KEYS_TO_STDERR
972 LOG (GNUNET_ERROR_TYPE_INFO, " AX_DEC_H with skipped key %s\n",
973 GNUNET_i2s ((struct GNUNET_PeerIdentity *) &key->HK));
974 LOG (GNUNET_ERROR_TYPE_INFO, " AX_DEC with skipped key %u: %s\n",
975 key->Kn, GNUNET_i2s ((struct GNUNET_PeerIdentity *) &key->MK));
976 #endif
977
978 /* Decrypt payload */
979 GNUNET_CRYPTO_symmetric_derive_iv (&iv, &key->MK, NULL, 0, NULL);
980 res = GNUNET_CRYPTO_symmetric_decrypt (&src[1], len, &key->MK, &iv, dst);
981
982 /* Remove key */
983 GNUNET_CONTAINER_DLL_remove (t->ax->skipped_head, t->ax->skipped_tail, key);
984 t->ax->skipped--;
985 GNUNET_free (key); /* GNUNET_free overwrites memory with 0xbaadf00d */
986
987 return res;
988}
989
990
991/**
992 * Delete a key from the list of skipped keys.
993 *
994 * @param t Tunnel to delete from.
995 * @param HKr Header Key to use.
996 */
997static void
998store_skipped_key (struct CadetTunnel *t,
999 const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr)
1000{
1001 struct CadetTunnelSkippedKey *key;
1002
1003 key = GNUNET_new (struct CadetTunnelSkippedKey);
1004 key->timestamp = GNUNET_TIME_absolute_get ();
1005 key->Kn = t->ax->Nr;
1006 key->HK = t->ax->HKr;
1007 t_hmac_derive_key (&t->ax->CKr, &key->MK, "0", 1);
1008 #if DUMP_KEYS_TO_STDERR
1009 LOG (GNUNET_ERROR_TYPE_DEBUG, " storing MK for Nr %u: %s\n",
1010 key->Kn, GNUNET_i2s ((struct GNUNET_PeerIdentity *) &key->MK));
1011 LOG (GNUNET_ERROR_TYPE_DEBUG, " for CKr: %s\n",
1012 GNUNET_i2s ((struct GNUNET_PeerIdentity *) &t->ax->CKr));
1013 #endif
1014 t_hmac_derive_key (&t->ax->CKr, &t->ax->CKr, "1", 1);
1015 GNUNET_CONTAINER_DLL_insert (t->ax->skipped_head, t->ax->skipped_tail, key);
1016 t->ax->Nr++;
1017 t->ax->skipped++;
1018}
1019
1020
1021/**
1022 * Delete a key from the list of skipped keys.
1023 *
1024 * @param t Tunnel to delete from.
1025 * @param key Key to delete.
1026 */
1027static void
1028delete_skipped_key (struct CadetTunnel *t, struct CadetTunnelSkippedKey *key)
1029{
1030 GNUNET_CONTAINER_DLL_remove (t->ax->skipped_head, t->ax->skipped_tail, key);
1031 GNUNET_free (key);
1032 t->ax->skipped--;
1033}
1034
1035
1036/**
1037 * Stage skipped AX keys and calculate the message key.
1038 *
1039 * Stores each HK and MK for skipped messages.
1040 *
1041 * @param t Tunnel where to stage the keys.
1042 * @param HKr Header key.
1043 * @param Np Received meesage number.
1044 *
1045 * @return GNUNET_OK if keys were stored.
1046 * GNUNET_SYSERR if an error ocurred (Np not expected).
1047 */
1048static int
1049store_ax_keys (struct CadetTunnel *t,
1050 const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr,
1051 uint32_t Np)
1052{
1053 int gap;
1054
1055
1056 gap = Np - t->ax->Nr;
1057 LOG (GNUNET_ERROR_TYPE_INFO, "Storing keys [%u, %u)\n", t->ax->Nr, Np);
1058 if (MAX_KEY_GAP < gap)
1059 {
1060 /* Avoid DoS (forcing peer to do 2*33 chain HMAC operations) */
1061 /* TODO: start new key exchange on return */
1062 GNUNET_break_op (0);
1063 LOG (GNUNET_ERROR_TYPE_WARNING, "Got message %u, expected %u+\n",
1064 Np, t->ax->Nr);
1065 return GNUNET_SYSERR;
1066 }
1067 if (0 > gap)
1068 {
1069 /* Delayed message: don't store keys, flag to try old keys. */
1070 return GNUNET_SYSERR;
1071 }
1072
1073 while (t->ax->Nr < Np)
1074 store_skipped_key (t, HKr);
1075
1076 while (t->ax->skipped > MAX_SKIPPED_KEYS)
1077 delete_skipped_key (t, t->ax->skipped_tail);
1078
1079 return GNUNET_OK;
1080}
1081
1082
1083/**
1084 * Decrypt and verify data with the appropriate tunnel key and verify that the
1085 * data has not been altered since it was sent by the remote peer.
1086 *
1087 * @param t Tunnel whose key to use.
1088 * @param dst Destination for the plaintext.
1089 * @param src Source of the message. Can overlap with @c dst.
1090 * @param size Size of the message.
1091 *
1092 * @return Size of the decrypted data, -1 if an error was encountered.
1093 */
1094static int
1095t_ax_decrypt_and_validate (struct CadetTunnel *t, void *dst,
1096 const struct GNUNET_CADET_TunnelEncryptedMessage *src,
1097 size_t size)
1098{
1099 struct CadetTunnelAxolotl *ax;
1100 struct GNUNET_ShortHashCode msg_hmac;
1101 struct GNUNET_HashCode hmac;
1102 struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header;
1103 uint32_t Np;
1104 uint32_t PNp;
1105 size_t esize; /* Size of encryped payload */
1106 size_t osize; /* Size of output (decrypted payload) */
1107
1108 esize = size - sizeof (struct GNUNET_CADET_TunnelEncryptedMessage);
1109 ax = t->ax;
1110 if (NULL == ax)
1111 return -1;
1112
1113 /* Try current HK */
1114 t_hmac (&src->Ns, AX_HEADER_SIZE + esize, 0, &ax->HKr, &msg_hmac);
1115 if (0 != memcmp (&msg_hmac, &src->hmac, sizeof (msg_hmac)))
1116 {
1117 static const char ctx[] = "axolotl ratchet";
1118 struct GNUNET_CRYPTO_SymmetricSessionKey keys[3]; /* RKp, NHKp, CKp */
1119 struct GNUNET_CRYPTO_SymmetricSessionKey HK;
1120 struct GNUNET_HashCode dh;
1121 struct GNUNET_CRYPTO_EcdhePublicKey *DHRp;
1122
1123 /* Try Next HK */
1124 LOG (GNUNET_ERROR_TYPE_DEBUG, " trying next HK\n");
1125 t_hmac (&src->Ns, AX_HEADER_SIZE + esize, 0, &ax->NHKr, &msg_hmac);
1126 if (0 != memcmp (&msg_hmac, &src->hmac, sizeof (msg_hmac)))
1127 {
1128 /* Try the skipped keys, if that fails, we're out of luck. */
1129 return try_old_ax_keys (t, dst, src, size);
1130 }
1131 LOG (GNUNET_ERROR_TYPE_INFO, "next HK worked\n");
1132
1133 HK = ax->HKr;
1134 ax->HKr = ax->NHKr;
1135 t_h_decrypt (t, src, &plaintext_header);
1136 Np = ntohl (plaintext_header.Ns);
1137 PNp = ntohl (plaintext_header.PNs);
1138 DHRp = &plaintext_header.DHRs;
1139 store_ax_keys (t, &HK, PNp);
1140
1141 /* RKp, NHKp, CKp = KDF (HMAC-HASH (RK, DH (DHRp, DHRs))) */
1142 GNUNET_CRYPTO_ecc_ecdh (ax->DHRs, DHRp, &dh);
1143 t_ax_hmac_hash (&ax->RK, &hmac, &dh, sizeof (dh));
1144 GNUNET_CRYPTO_kdf (keys, sizeof (keys), ctx, sizeof (ctx),
1145 &hmac, sizeof (hmac), NULL);
1146
1147 /* Commit "purported" keys */
1148 ax->RK = keys[0];
1149 ax->NHKr = keys[1];
1150 ax->CKr = keys[2];
1151 ax->DHRr = *DHRp;
1152 ax->Nr = 0;
1153 ax->ratchet_allowed = GNUNET_YES;
1154 }
1155 else
1156 {
1157 LOG (GNUNET_ERROR_TYPE_DEBUG, "current HK\n");
1158 t_h_decrypt (t, src, &plaintext_header);
1159 Np = ntohl (plaintext_header.Ns);
1160 PNp = ntohl (plaintext_header.PNs);
1161 }
1162 LOG (GNUNET_ERROR_TYPE_INFO, " got AX Nr %u\n", Np);
1163 if (Np != ax->Nr)
1164 if (GNUNET_OK != store_ax_keys (t, &ax->HKr, Np))
1165 /* Try the skipped keys, if that fails, we're out of luck. */
1166 return try_old_ax_keys (t, dst, src, size);
1167
1168 osize = t_ax_decrypt (t, dst, &src[1], esize);
1169 ax->Nr = Np + 1;
1170
1171 if (osize != esize)
1172 {
1173 GNUNET_break_op (0);
1174 return -1;
1175 }
1176
1177 return osize;
1178}
1179
1180
1181/**
1182 * Pick a connection on which send the next data message.
1183 *
1184 * @param t Tunnel on which to send the message.
1185 *
1186 * @return The connection on which to send the next message.
1187 */
1188static struct CadetConnection *
1189tunnel_get_connection (struct CadetTunnel *t)
1190{
1191 struct CadetTConnection *iter;
1192 struct CadetConnection *best;
1193 unsigned int qn;
1194 unsigned int lowest_q;
1195
1196 LOG (GNUNET_ERROR_TYPE_DEBUG, "tunnel_get_connection %s\n", GCT_2s (t));
1197 best = NULL;
1198 lowest_q = UINT_MAX;
1199 for (iter = t->connection_head; NULL != iter; iter = iter->next)
1200 {
1201 LOG (GNUNET_ERROR_TYPE_DEBUG, " connection %s: %u\n",
1202 GCC_2s (iter->c), GCC_get_state (iter->c));
1203 if (CADET_CONNECTION_READY == GCC_get_state (iter->c))
1204 {
1205 qn = GCC_get_qn (iter->c, GCC_is_origin (iter->c, GNUNET_YES));
1206 LOG (GNUNET_ERROR_TYPE_DEBUG, " q_n %u, \n", qn);
1207 if (qn < lowest_q)
1208 {
1209 best = iter->c;
1210 lowest_q = qn;
1211 }
1212 }
1213 }
1214 LOG (GNUNET_ERROR_TYPE_DEBUG, " selected: connection %s\n", GCC_2s (best));
1215 return best;
1216}
1217
1218
1219/**
1220 * Callback called when a queued message is sent.
1221 *
1222 * Calculates the average time and connection packet tracking.
1223 *
1224 * @param cls Closure (TunnelQueue handle).
1225 * @param c Connection this message was on.
1226 * @param q Connection queue handle (unused).
1227 * @param type Type of message sent.
1228 * @param fwd Was this a FWD going message?
1229 * @param size Size of the message.
1230 */
1231static void
1232tun_message_sent (void *cls,
1233 struct CadetConnection *c,
1234 struct CadetConnectionQueue *q,
1235 uint16_t type, int fwd, size_t size)
1236{
1237 struct CadetTunnelQueue *qt = cls;
1238 struct CadetTunnel *t;
1239
1240 LOG (GNUNET_ERROR_TYPE_DEBUG, "tun_message_sent\n");
1241
1242 GNUNET_assert (NULL != qt->cont);
1243 t = NULL == c ? NULL : GCC_get_tunnel (c);
1244 qt->cont (qt->cont_cls, t, qt, type, size);
1245 GNUNET_free (qt);
1246}
1247
1248
1249static unsigned int
1250count_queued_data (const struct CadetTunnel *t)
1251{
1252 struct CadetTunnelDelayed *iter;
1253 unsigned int count;
1254
1255 for (count = 0, iter = t->tq_head; iter != NULL; iter = iter->next)
1256 count++;
1257
1258 return count;
1259}
1260
1261/**
1262 * Delete a queued message: either was sent or the channel was destroyed
1263 * before the tunnel's key exchange had a chance to finish.
1264 *
1265 * @param tqd Delayed queue handle.
1266 */
1267static void
1268unqueue_data (struct CadetTunnelDelayed *tqd)
1269{
1270 GNUNET_CONTAINER_DLL_remove (tqd->t->tq_head, tqd->t->tq_tail, tqd);
1271 GNUNET_free (tqd);
1272}
1273
1274
1275/**
1276 * Cache a message to be sent once tunnel is online.
1277 *
1278 * @param t Tunnel to hold the message.
1279 * @param msg Message itself (copy will be made).
1280 */
1281static struct CadetTunnelDelayed *
1282queue_data (struct CadetTunnel *t, const struct GNUNET_MessageHeader *msg)
1283{
1284 struct CadetTunnelDelayed *tqd;
1285 uint16_t size = ntohs (msg->size);
1286
1287 LOG (GNUNET_ERROR_TYPE_DEBUG, "queue data on Tunnel %s\n", GCT_2s (t));
1288
1289 GNUNET_assert (GNUNET_NO == is_ready (t));
1290
1291 tqd = GNUNET_malloc (sizeof (struct CadetTunnelDelayed) + size);
1292
1293 tqd->t = t;
1294 GNUNET_memcpy (&tqd[1], msg, size);
1295 GNUNET_CONTAINER_DLL_insert_tail (t->tq_head, t->tq_tail, tqd);
1296 return tqd;
1297}
1298
1299
1300/**
1301 * Sends an already built message on a tunnel, encrypting it and
1302 * choosing the best connection.
1303 *
1304 * @param message Message to send. Function modifies it.
1305 * @param t Tunnel on which this message is transmitted.
1306 * @param c Connection to use (autoselect if NULL).
1307 * @param force Force the tunnel to take the message (buffer overfill).
1308 * @param cont Continuation to call once message is really sent.
1309 * @param cont_cls Closure for @c cont.
1310 * @param existing_q In case this a transmission of previously queued data,
1311 * this should be TunnelQueue given to the client.
1312 * Otherwise, NULL.
1313 * @return Handle to cancel message.
1314 * NULL if @c cont is NULL or an error happens and message is dropped.
1315 */
1316static struct CadetTunnelQueue *
1317send_prebuilt_message (const struct GNUNET_MessageHeader *message,
1318 struct CadetTunnel *t,
1319 struct CadetConnection *c,
1320 int force,
1321 GCT_sent cont,
1322 void *cont_cls,
1323 struct CadetTunnelQueue *existing_q)
1324{
1325 struct GNUNET_MessageHeader *msg;
1326 struct GNUNET_CADET_TunnelEncryptedMessage *ax_msg;
1327 struct CadetTunnelQueue *tq;
1328 size_t size = ntohs (message->size);
1329 char cbuf[sizeof (struct GNUNET_CADET_TunnelEncryptedMessage) + size] GNUNET_ALIGN;
1330 size_t esize;
1331 uint16_t type;
1332 int fwd;
1333
1334 LOG (GNUNET_ERROR_TYPE_DEBUG, "GMT Send on Tunnel %s\n", GCT_2s (t));
1335
1336 if (GNUNET_NO == is_ready (t))
1337 {
1338 struct CadetTunnelDelayed *tqd;
1339 /* A non null existing_q indicates sending of queued data.
1340 * Should only happen after tunnel becomes ready.
1341 */
1342 GNUNET_assert (NULL == existing_q);
1343 tqd = queue_data (t, message);
1344 if (NULL == cont)
1345 return NULL;
1346 tq = GNUNET_new (struct CadetTunnelQueue);
1347 tq->tqd = tqd;
1348 tqd->tq = tq;
1349 tq->cont = cont;
1350 tq->cont_cls = cont_cls;
1351 return tq;
1352 }
1353
1354 GNUNET_assert (GNUNET_NO == GCT_is_loopback (t));
1355
1356 ax_msg = (struct GNUNET_CADET_TunnelEncryptedMessage *) cbuf;
1357 msg = &ax_msg->header;
1358 msg->size = htons (sizeof (struct GNUNET_CADET_TunnelEncryptedMessage) + size);
1359 msg->type = htons (GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED);
1360 esize = t_ax_encrypt (t, &ax_msg[1], message, size);
1361 ax_msg->Ns = htonl (t->ax->Ns++);
1362 ax_msg->PNs = htonl (t->ax->PNs);
1363 GNUNET_CRYPTO_ecdhe_key_get_public (t->ax->DHRs, &ax_msg->DHRs);
1364 t_h_encrypt (t, ax_msg);
1365 t_hmac (&ax_msg->Ns, AX_HEADER_SIZE + esize, 0, &t->ax->HKs, &ax_msg->hmac);
1366 GNUNET_assert (esize == size);
1367
1368 if (NULL == c)
1369 c = tunnel_get_connection (t);
1370 if (NULL == c)
1371 {
1372 /* Why is tunnel 'ready'? Should have been queued! */
1373 if (NULL != t->destroy_task)
1374 {
1375 GNUNET_break (0);
1376 GCT_debug (t, GNUNET_ERROR_TYPE_WARNING);
1377 }
1378 return NULL; /* Drop... */
1379 }
1380 fwd = GCC_is_origin (c, GNUNET_YES);
1381 ax_msg->cid = *GCC_get_id (c);
1382 ax_msg->cemi = GCC_get_pid (c, fwd);
1383
1384 type = htons (message->type);
1385 LOG (GNUNET_ERROR_TYPE_DEBUG,
1386 "Sending message of type %s with CEMI %u and CID %s\n",
1387 GC_m2s (type),
1388 htonl (ax_msg->cemi.pid),
1389 GNUNET_sh2s (&ax_msg->cid.connection_of_tunnel));
1390
1391 if (NULL == cont)
1392 {
1393 (void) GCC_send_prebuilt_message (msg,
1394 type,
1395 ax_msg->cemi,
1396 c,
1397 fwd,
1398 force, NULL, NULL);
1399 return NULL;
1400 }
1401 if (NULL == existing_q)
1402 {
1403 tq = GNUNET_new (struct CadetTunnelQueue); /* FIXME valgrind: leak*/
1404 }
1405 else
1406 {
1407 tq = existing_q;
1408 tq->tqd = NULL;
1409 }
1410 tq->cont = cont;
1411 tq->cont_cls = cont_cls;
1412 tq->cq = GCC_send_prebuilt_message (msg,
1413 type,
1414 ax_msg->cemi,
1415 c,
1416 fwd,
1417 force,
1418 &tun_message_sent, tq);
1419 GNUNET_assert (NULL != tq->cq);
1420
1421 return tq;
1422}
1423
1424
1425/**
1426 * Send all cached messages that we can, tunnel is online.
1427 *
1428 * @param t Tunnel that holds the messages. Cannot be loopback.
1429 */
1430static void
1431send_queued_data (struct CadetTunnel *t)
1432{
1433 struct CadetTunnelDelayed *tqd;
1434 struct CadetTunnelDelayed *next;
1435 unsigned int room;
1436
1437 LOG (GNUNET_ERROR_TYPE_INFO, "Send queued data, tunnel %s\n", GCT_2s (t));
1438
1439 if (GCT_is_loopback (t))
1440 {
1441 GNUNET_break (0);
1442 return;
1443 }
1444
1445 if (GNUNET_NO == is_ready (t))
1446 {
1447 LOG (GNUNET_ERROR_TYPE_WARNING, " not ready yet: %s/%s\n",
1448 estate2s (t->estate), cstate2s (t->cstate));
1449 return;
1450 }
1451
1452 room = GCT_get_connections_buffer (t);
1453 LOG (GNUNET_ERROR_TYPE_DEBUG, " buffer space: %u\n", room);
1454 LOG (GNUNET_ERROR_TYPE_DEBUG, " tq head: %p\n", t->tq_head);
1455 for (tqd = t->tq_head; NULL != tqd && room > 0; tqd = next)
1456 {
1457 LOG (GNUNET_ERROR_TYPE_DEBUG, " sending queued data\n");
1458 next = tqd->next;
1459 room--;
1460 send_prebuilt_message ((struct GNUNET_MessageHeader *) &tqd[1],
1461 tqd->t, NULL, GNUNET_YES,
1462 NULL != tqd->tq ? tqd->tq->cont : NULL,
1463 NULL != tqd->tq ? tqd->tq->cont_cls : NULL,
1464 tqd->tq);
1465 unqueue_data (tqd);
1466 }
1467 LOG (GNUNET_ERROR_TYPE_DEBUG, "GCT_send_queued_data end\n", GCP_2s (t->peer));
1468}
1469
1470
1471/**
1472 * @brief Resend the KX until we complete the handshake.
1473 *
1474 * @param cls Closure (tunnel).
1475 */
1476static void
1477kx_resend (void *cls)
1478{
1479 struct CadetTunnel *t = cls;
1480
1481 t->rekey_task = NULL;
1482 if (CADET_TUNNEL_KEY_OK == t->estate)
1483 {
1484 /* Should have been canceled on estate change */
1485 GNUNET_break (0);
1486 return;
1487 }
1488
1489 GCT_send_kx (t, CADET_TUNNEL_KEY_SENT >= t->estate);
1490}
1491
1492
1493/**
1494 * Callback called when a queued message is sent.
1495 *
1496 * @param cls Closure.
1497 * @param c Connection this message was on.
1498 * @param type Type of message sent.
1499 * @param fwd Was this a FWD going message?
1500 * @param size Size of the message.
1501 */
1502static void
1503ephm_sent (void *cls,
1504 struct CadetConnection *c,
1505 struct CadetConnectionQueue *q,
1506 uint16_t type, int fwd, size_t size)
1507{
1508 struct CadetTunnel *t = cls;
1509 LOG (GNUNET_ERROR_TYPE_DEBUG, "ephemeral sent %s\n", GC_m2s (type));
1510
1511 t->ephm_h = NULL;
1512
1513 if (CADET_TUNNEL_KEY_OK == t->estate)
1514 return;
1515
1516 if (NULL != t->rekey_task)
1517 {
1518 GNUNET_break (0);
1519 GCT_debug (t, GNUNET_ERROR_TYPE_WARNING);
1520 GNUNET_SCHEDULER_cancel (t->rekey_task);
1521 }
1522 t->rekey_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
1523 &kx_resend, t);
1524
1525}
1526
1527
1528/**
1529 * Called only on shutdown, destroy every tunnel.
1530 *
1531 * @param cls Closure (unused).
1532 * @param key Current public key.
1533 * @param value Value in the hash map (tunnel).
1534 *
1535 * @return #GNUNET_YES, so we should continue to iterate,
1536 */
1537static int
1538destroy_iterator (void *cls,
1539 const struct GNUNET_PeerIdentity *key,
1540 void *value)
1541{
1542 struct CadetTunnel *t = value;
1543
1544 LOG (GNUNET_ERROR_TYPE_DEBUG,
1545 "GCT_shutdown destroying tunnel at %p\n", t);
1546 GCT_destroy (t);
1547 return GNUNET_YES;
1548}
1549
1550
1551/**
1552 * Notify remote peer that we don't know a channel he is talking about,
1553 * probably CHANNEL_DESTROY was missed.
1554 *
1555 * @param t Tunnel on which to notify.
1556 * @param gid ID of the channel.
1557 */
1558static void
1559send_channel_destroy (struct CadetTunnel *t,
1560 struct GNUNET_CADET_ChannelTunnelNumber gid)
1561{
1562 struct GNUNET_CADET_ChannelManageMessage msg;
1563
1564 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY);
1565 msg.header.size = htons (sizeof (msg));
1566 msg.ctn = gid;
1567
1568 LOG (GNUNET_ERROR_TYPE_DEBUG,
1569 "WARNING destroying unknown channel %u on tunnel %s\n",
1570 ntohl (gid.cn),
1571 GCT_2s (t));
1572 send_prebuilt_message (&msg.header, t, NULL, GNUNET_YES, NULL, NULL, NULL);
1573}
1574
1575
1576/**
1577 * Demultiplex data per channel and call appropriate channel handler.
1578 *
1579 * @param t Tunnel on which the data came.
1580 * @param msg Data message.
1581 * @param fwd Is this message fwd? This only is meaningful in loopback channels.
1582 * #GNUNET_YES if message is FWD on the respective channel (loopback)
1583 * #GNUNET_NO if message is BCK on the respective channel (loopback)
1584 * #GNUNET_SYSERR if message on a one-ended channel (remote)
1585 */
1586static void
1587handle_data (struct CadetTunnel *t,
1588 const struct GNUNET_CADET_ChannelAppDataMessage *msg,
1589 int fwd)
1590{
1591 struct CadetChannel *ch;
1592 char buf[128];
1593 size_t size;
1594 uint16_t type;
1595
1596 /* Check size */
1597 size = ntohs (msg->header.size);
1598 if (size <
1599 sizeof (struct GNUNET_CADET_ChannelAppDataMessage) +
1600 sizeof (struct GNUNET_MessageHeader))
1601 {
1602 GNUNET_break (0);
1603 return;
1604 }
1605 type = ntohs (msg[1].header.type);
1606 LOG (GNUNET_ERROR_TYPE_DEBUG, " payload of type %s\n", GC_m2s (type));
1607 SPRINTF (buf, "# received payload of type %hu", type);
1608 GNUNET_STATISTICS_update (stats, buf, 1, GNUNET_NO);
1609
1610
1611 /* Check channel */
1612 ch = GCT_get_channel (t, msg->ctn);
1613 if (NULL == ch)
1614 {
1615 GNUNET_STATISTICS_update (stats,
1616 "# data on unknown channel",
1617 1,
1618 GNUNET_NO);
1619 LOG (GNUNET_ERROR_TYPE_DEBUG,
1620 "channel 0x%X unknown\n",
1621 ntohl (msg->ctn.cn));
1622 send_channel_destroy (t, msg->ctn);
1623 return;
1624 }
1625
1626 GCCH_handle_data (ch, msg, fwd);
1627}
1628
1629
1630/**
1631 * Demultiplex data ACKs per channel and update appropriate channel buffer info.
1632 *
1633 * @param t Tunnel on which the DATA ACK came.
1634 * @param msg DATA ACK message.
1635 * @param fwd Is this message fwd? This only is meaningful in loopback channels.
1636 * #GNUNET_YES if message is FWD on the respective channel (loopback)
1637 * #GNUNET_NO if message is BCK on the respective channel (loopback)
1638 * #GNUNET_SYSERR if message on a one-ended channel (remote)
1639 */
1640static void
1641handle_data_ack (struct CadetTunnel *t,
1642 const struct GNUNET_CADET_ChannelDataAckMessage *msg,
1643 int fwd)
1644{
1645 struct CadetChannel *ch;
1646 size_t size;
1647
1648 /* Check size */
1649 size = ntohs (msg->header.size);
1650 if (size != sizeof (struct GNUNET_CADET_ChannelDataAckMessage))
1651 {
1652 GNUNET_break (0);
1653 return;
1654 }
1655
1656 /* Check channel */
1657 ch = GCT_get_channel (t, msg->ctn);
1658 if (NULL == ch)
1659 {
1660 GNUNET_STATISTICS_update (stats, "# data ack on unknown channel",
1661 1, GNUNET_NO);
1662 LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel %u unknown\n",
1663 ntohl (msg->ctn.cn));
1664 return;
1665 }
1666
1667 GCCH_handle_data_ack (ch, msg, fwd);
1668}
1669
1670
1671/**
1672 * Handle channel create.
1673 *
1674 * @param t Tunnel on which the message came.
1675 * @param msg ChannelCreate message.
1676 */
1677static void
1678handle_ch_create (struct CadetTunnel *t,
1679 const struct GNUNET_CADET_ChannelOpenMessage *msg)
1680{
1681 struct CadetChannel *ch;
1682 size_t size;
1683
1684 /* Check size */
1685 size = ntohs (msg->header.size);
1686 if (size != sizeof (struct GNUNET_CADET_ChannelOpenMessage))
1687 {
1688 GNUNET_break_op (0);
1689 return;
1690 }
1691
1692 /* Check channel */
1693 ch = GCT_get_channel (t, msg->ctn);
1694 if (NULL != ch && ! GCT_is_loopback (t))
1695 {
1696 /* Probably a retransmission, safe to ignore */
1697 LOG (GNUNET_ERROR_TYPE_DEBUG, " already exists...\n");
1698 }
1699 ch = GCCH_handle_create (t, msg);
1700 if (NULL != ch)
1701 GCT_add_channel (t, ch);
1702}
1703
1704
1705
1706/**
1707 * Handle channel NACK: check correctness and call channel handler for NACKs.
1708 *
1709 * @param t Tunnel on which the NACK came.
1710 * @param msg NACK message.
1711 */
1712static void
1713handle_ch_nack (struct CadetTunnel *t,
1714 const struct GNUNET_CADET_ChannelManageMessage *msg)
1715{
1716 struct CadetChannel *ch;
1717 size_t size;
1718
1719 /* Check size */
1720 size = ntohs (msg->header.size);
1721 if (size != sizeof (struct GNUNET_CADET_ChannelManageMessage))
1722 {
1723 GNUNET_break (0);
1724 return;
1725 }
1726
1727 /* Check channel */
1728 ch = GCT_get_channel (t, msg->ctn);
1729 if (NULL == ch)
1730 {
1731 GNUNET_STATISTICS_update (stats, "# channel NACK on unknown channel",
1732 1, GNUNET_NO);
1733 LOG (GNUNET_ERROR_TYPE_DEBUG,
1734 "WARNING channel %u unknown\n",
1735 ntohl (msg->ctn.cn));
1736 return;
1737 }
1738
1739 GCCH_handle_nack (ch);
1740}
1741
1742
1743/**
1744 * Handle a CHANNEL ACK (SYNACK/ACK).
1745 *
1746 * @param t Tunnel on which the CHANNEL ACK came.
1747 * @param msg CHANNEL ACK message.
1748 * @param fwd Is this message fwd? This only is meaningful in loopback channels.
1749 * #GNUNET_YES if message is FWD on the respective channel (loopback)
1750 * #GNUNET_NO if message is BCK on the respective channel (loopback)
1751 * #GNUNET_SYSERR if message on a one-ended channel (remote)
1752 */
1753static void
1754handle_ch_ack (struct CadetTunnel *t,
1755 const struct GNUNET_CADET_ChannelManageMessage *msg,
1756 int fwd)
1757{
1758 struct CadetChannel *ch;
1759 size_t size;
1760
1761 /* Check size */
1762 size = ntohs (msg->header.size);
1763 if (size != sizeof (struct GNUNET_CADET_ChannelManageMessage))
1764 {
1765 GNUNET_break (0);
1766 return;
1767 }
1768
1769 /* Check channel */
1770 ch = GCT_get_channel (t, msg->ctn);
1771 if (NULL == ch)
1772 {
1773 GNUNET_STATISTICS_update (stats,
1774 "# channel ack on unknown channel",
1775 1,
1776 GNUNET_NO);
1777 LOG (GNUNET_ERROR_TYPE_DEBUG,
1778 "WARNING channel %u unknown\n",
1779 ntohl (msg->ctn.cn));
1780 return;
1781 }
1782
1783 GCCH_handle_ack (ch, msg, fwd);
1784}
1785
1786
1787/**
1788 * Handle a channel destruction message.
1789 *
1790 * @param t Tunnel on which the message came.
1791 * @param msg Channel destroy message.
1792 * @param fwd Is this message fwd? This only is meaningful in loopback channels.
1793 * #GNUNET_YES if message is FWD on the respective channel (loopback)
1794 * #GNUNET_NO if message is BCK on the respective channel (loopback)
1795 * #GNUNET_SYSERR if message on a one-ended channel (remote)
1796 */
1797static void
1798handle_ch_destroy (struct CadetTunnel *t,
1799 const struct GNUNET_CADET_ChannelManageMessage *msg,
1800 int fwd)
1801{
1802 struct CadetChannel *ch;
1803 size_t size;
1804
1805 /* Check size */
1806 size = ntohs (msg->header.size);
1807 if (size != sizeof (struct GNUNET_CADET_ChannelManageMessage))
1808 {
1809 GNUNET_break (0);
1810 return;
1811 }
1812
1813 /* Check channel */
1814 ch = GCT_get_channel (t, msg->ctn);
1815 if (NULL == ch)
1816 {
1817 /* Probably a retransmission, safe to ignore */
1818 return;
1819 }
1820
1821 GCCH_handle_destroy (ch, msg, fwd);
1822}
1823
1824
1825/**
1826 * Free Axolotl data.
1827 *
1828 * @param t Tunnel.
1829 */
1830static void
1831destroy_ax (struct CadetTunnel *t)
1832{
1833 if (NULL == t->ax)
1834 return;
1835
1836 GNUNET_free_non_null (t->ax->DHRs);
1837 GNUNET_free_non_null (t->ax->kx_0);
1838 while (NULL != t->ax->skipped_head)
1839 delete_skipped_key (t, t->ax->skipped_head);
1840 GNUNET_assert (0 == t->ax->skipped);
1841
1842 GNUNET_free (t->ax);
1843 t->ax = NULL;
1844
1845 if (NULL != t->rekey_task)
1846 {
1847 GNUNET_SCHEDULER_cancel (t->rekey_task);
1848 t->rekey_task = NULL;
1849 }
1850 if (NULL != t->ephm_h)
1851 {
1852 GCC_cancel (t->ephm_h);
1853 t->ephm_h = NULL;
1854 }
1855}
1856
1857
1858/**
1859 * Demultiplex by message type and call appropriate handler for a message
1860 * towards a channel of a local tunnel.
1861 *
1862 * @param t Tunnel this message came on.
1863 * @param msgh Message header.
1864 * @param fwd Is this message fwd? This only is meaningful in loopback channels.
1865 * #GNUNET_YES if message is FWD on the respective channel (loopback)
1866 * #GNUNET_NO if message is BCK on the respective channel (loopback)
1867 * #GNUNET_SYSERR if message on a one-ended channel (remote)
1868 */
1869static void
1870handle_decrypted (struct CadetTunnel *t,
1871 const struct GNUNET_MessageHeader *msgh,
1872 int fwd)
1873{
1874 uint16_t type;
1875 char buf[256];
1876
1877 type = ntohs (msgh->type);
1878 LOG (GNUNET_ERROR_TYPE_DEBUG, "<-- %s on %s\n", GC_m2s (type), GCT_2s (t));
1879 SPRINTF (buf, "# received encrypted of type %hu (%s)", type, GC_m2s (type));
1880 GNUNET_STATISTICS_update (stats, buf, 1, GNUNET_NO);
1881
1882 switch (type)
1883 {
1884 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE:
1885 /* Do nothing, connection aleady got updated. */
1886 GNUNET_STATISTICS_update (stats, "# keepalives received", 1, GNUNET_NO);
1887 break;
1888
1889 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA:
1890 /* Don't send hop ACK, wait for client to ACK */
1891 handle_data (t, (struct GNUNET_CADET_ChannelAppDataMessage *) msgh, fwd);
1892 break;
1893
1894 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK:
1895 handle_data_ack (t, (struct GNUNET_CADET_ChannelDataAckMessage *) msgh, fwd);
1896 break;
1897
1898 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN:
1899 handle_ch_create (t, (struct GNUNET_CADET_ChannelOpenMessage *) msgh);
1900 break;
1901
1902 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_NACK_DEPRECATED:
1903 handle_ch_nack (t, (struct GNUNET_CADET_ChannelManageMessage *) msgh);
1904 break;
1905
1906 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK:
1907 handle_ch_ack (t, (struct GNUNET_CADET_ChannelManageMessage *) msgh, fwd);
1908 break;
1909
1910 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY:
1911 handle_ch_destroy (t, (struct GNUNET_CADET_ChannelManageMessage *) msgh, fwd);
1912 break;
1913
1914 default:
1915 GNUNET_break_op (0);
1916 LOG (GNUNET_ERROR_TYPE_WARNING,
1917 "end-to-end message not known (%u)\n",
1918 ntohs (msgh->type));
1919 GCT_debug (t, GNUNET_ERROR_TYPE_WARNING);
1920 }
1921}
1922
1923
1924/******************************************************************************/
1925/******************************** API ***********************************/
1926/******************************************************************************/
1927
1928/**
1929 * Decrypt and process an encrypted message.
1930 *
1931 * Calls the appropriate handler for a message in a channel of a local tunnel.
1932 *
1933 * @param t Tunnel this message came on.
1934 * @param msg Message header.
1935 */
1936void
1937GCT_handle_encrypted (struct CadetTunnel *t,
1938 const struct GNUNET_CADET_TunnelEncryptedMessage *msg)
1939{
1940 uint16_t size = ntohs (msg->header.size);
1941 char cbuf [size];
1942 int decrypted_size;
1943 const struct GNUNET_MessageHeader *msgh;
1944 unsigned int off;
1945
1946 GNUNET_STATISTICS_update (stats, "# received encrypted", 1, GNUNET_NO);
1947
1948 decrypted_size = t_ax_decrypt_and_validate (t, cbuf, msg, size);
1949
1950 if (-1 == decrypted_size)
1951 {
1952 GNUNET_STATISTICS_update (stats, "# unable to decrypt", 1, GNUNET_NO);
1953 if (CADET_TUNNEL_KEY_PING <= t->estate)
1954 {
1955 GNUNET_break_op (0);
1956 LOG (GNUNET_ERROR_TYPE_WARNING, "Wrong crypto, tunnel %s\n", GCT_2s (t));
1957 GCT_debug (t, GNUNET_ERROR_TYPE_WARNING);
1958 }
1959 return;
1960 }
1961 GCT_change_estate (t, CADET_TUNNEL_KEY_OK);
1962
1963 /* FIXME: this is bad, as the structs returned from
1964 this loop may be unaligned, see util's MST for
1965 how to do this right. */
1966 off = 0;
1967 while (off + sizeof (struct GNUNET_MessageHeader) <= decrypted_size)
1968 {
1969 uint16_t msize;
1970
1971 msgh = (const struct GNUNET_MessageHeader *) &cbuf[off];
1972 msize = ntohs (msgh->size);
1973 if (msize < sizeof (struct GNUNET_MessageHeader))
1974 {
1975 GNUNET_break_op (0);
1976 return;
1977 }
1978 if (off + msize < decrypted_size)
1979 {
1980 GNUNET_break_op (0);
1981 return;
1982 }
1983 handle_decrypted (t, msgh, GNUNET_SYSERR);
1984 off += msize;
1985 }
1986}
1987
1988
1989/**
1990 * Handle a Key eXchange message.
1991 *
1992 * @param t Tunnel on which the message came.
1993 * @param msg KX message itself.
1994 */
1995void
1996GCT_handle_kx (struct CadetTunnel *t,
1997 const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg)
1998{
1999 struct CadetTunnelAxolotl *ax;
2000 struct GNUNET_HashCode key_material[3];
2001 struct GNUNET_CRYPTO_SymmetricSessionKey keys[5];
2002 const char salt[] = "CADET Axolotl salt";
2003 const struct GNUNET_PeerIdentity *pid;
2004 int am_I_alice;
2005
2006 CADET_TIMING_START;
2007
2008 LOG (GNUNET_ERROR_TYPE_INFO, "<== { KX} on %s\n", GCT_2s (t));
2009
2010 if (NULL == t->ax)
2011 {
2012 /* Something is wrong if ax is NULL. Whose fault it is? */
2013 return;
2014 }
2015 ax = t->ax;
2016
2017 pid = GCT_get_destination (t);
2018 if (0 > GNUNET_CRYPTO_cmp_peer_identity (&my_full_id, pid))
2019 am_I_alice = GNUNET_YES;
2020 else if (0 < GNUNET_CRYPTO_cmp_peer_identity (&my_full_id, pid))
2021 am_I_alice = GNUNET_NO;
2022 else
2023 {
2024 GNUNET_break_op (0);
2025 return;
2026 }
2027
2028 if (0 != (GNUNET_CADET_KX_FLAG_FORCE_REPLY & ntohl (msg->flags)))
2029 {
2030 if (NULL != t->rekey_task)
2031 {
2032 GNUNET_SCHEDULER_cancel (t->rekey_task);
2033 t->rekey_task = NULL;
2034 }
2035 GCT_send_kx (t, GNUNET_NO);
2036 }
2037
2038 if (0 == memcmp (&ax->DHRr, &msg->ratchet_key, sizeof(msg->ratchet_key)))
2039 {
2040 LOG (GNUNET_ERROR_TYPE_INFO, " known ratchet key, exit\n");
2041 return;
2042 }
2043
2044 LOG (GNUNET_ERROR_TYPE_INFO, " is Alice? %s\n", am_I_alice ? "YES" : "NO");
2045
2046 ax->DHRr = msg->ratchet_key;
2047
2048 /* ECDH A B0 */
2049 if (GNUNET_YES == am_I_alice)
2050 {
2051 GNUNET_CRYPTO_eddsa_ecdh (id_key, /* A */
2052 &msg->ephemeral_key, /* B0 */
2053 &key_material[0]);
2054 }
2055 else
2056 {
2057 GNUNET_CRYPTO_ecdh_eddsa (ax->kx_0, /* B0 */
2058 &pid->public_key, /* A */
2059 &key_material[0]);
2060 }
2061
2062 /* ECDH A0 B */
2063 if (GNUNET_YES == am_I_alice)
2064 {
2065 GNUNET_CRYPTO_ecdh_eddsa (ax->kx_0, /* A0 */
2066 &pid->public_key, /* B */
2067 &key_material[1]);
2068 }
2069 else
2070 {
2071 GNUNET_CRYPTO_eddsa_ecdh (id_key, /* A */
2072 &msg->ephemeral_key, /* B0 */
2073 &key_material[1]);
2074
2075
2076 }
2077
2078 /* ECDH A0 B0 */
2079 /* (This is the triple-DH, we could probably safely skip this,
2080 as A0/B0 are already in the key material.) */
2081 GNUNET_CRYPTO_ecc_ecdh (ax->kx_0, /* A0 or B0 */
2082 &msg->ephemeral_key, /* B0 or A0 */
2083 &key_material[2]);
2084
2085 #if DUMP_KEYS_TO_STDERR
2086 {
2087 unsigned int i;
2088 for (i = 0; i < 3; i++)
2089 LOG (GNUNET_ERROR_TYPE_INFO, "km[%u]: %s\n",
2090 i, GNUNET_h2s (&key_material[i]));
2091 }
2092 #endif
2093
2094 /* KDF */
2095 GNUNET_CRYPTO_kdf (keys, sizeof (keys),
2096 salt, sizeof (salt),
2097 &key_material, sizeof (key_material), NULL);
2098
2099 if (0 == memcmp (&ax->RK, &keys[0], sizeof(ax->RK)))
2100 {
2101 LOG (GNUNET_ERROR_TYPE_INFO, " known handshake key, exit\n");
2102 return;
2103 }
2104 ax->RK = keys[0];
2105 if (GNUNET_YES == am_I_alice)
2106 {
2107 ax->HKr = keys[1];
2108 ax->NHKs = keys[2];
2109 ax->NHKr = keys[3];
2110 ax->CKr = keys[4];
2111 ax->ratchet_flag = GNUNET_YES;
2112 }
2113 else
2114 {
2115 ax->HKs = keys[1];
2116 ax->NHKr = keys[2];
2117 ax->NHKs = keys[3];
2118 ax->CKs = keys[4];
2119 ax->ratchet_flag = GNUNET_NO;
2120 ax->ratchet_allowed = GNUNET_NO;
2121 ax->ratchet_counter = 0;
2122 ax->ratchet_expiration =
2123 GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(), ratchet_time);
2124 }
2125 ax->PNs = 0;
2126 ax->Nr = 0;
2127 ax->Ns = 0;
2128
2129 GCT_change_estate (t, CADET_TUNNEL_KEY_PING);
2130 send_queued_data (t);
2131
2132 CADET_TIMING_END;
2133}
2134
2135/**
2136 * Initialize the tunnel subsystem.
2137 *
2138 * @param c Configuration handle.
2139 * @param key ECC private key, to derive all other keys and do crypto.
2140 */
2141void
2142GCT_init (const struct GNUNET_CONFIGURATION_Handle *c,
2143 const struct GNUNET_CRYPTO_EddsaPrivateKey *key)
2144{
2145 unsigned int expected_overhead;
2146
2147 LOG (GNUNET_ERROR_TYPE_DEBUG, "init\n");
2148
2149 expected_overhead = 0;
2150 expected_overhead += sizeof (struct GNUNET_CADET_TunnelEncryptedMessage);
2151 expected_overhead += sizeof (struct GNUNET_CADET_ChannelAppDataMessage);
2152 expected_overhead += sizeof (struct GNUNET_CADET_ConnectionEncryptedAckMessage);
2153 GNUNET_assert (GNUNET_CONSTANTS_CADET_P2P_OVERHEAD == expected_overhead);
2154
2155 if (GNUNET_OK !=
2156 GNUNET_CONFIGURATION_get_value_number (c,
2157 "CADET",
2158 "RATCHET_MESSAGES",
2159 &ratchet_messages))
2160 {
2161 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
2162 "CADET",
2163 "RATCHET_MESSAGES",
2164 "USING DEFAULT");
2165 ratchet_messages = 64;
2166 }
2167 if (GNUNET_OK !=
2168 GNUNET_CONFIGURATION_get_value_time (c,
2169 "CADET",
2170 "RATCHET_TIME",
2171 &ratchet_time))
2172 {
2173 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
2174 "CADET", "RATCHET_TIME", "USING DEFAULT");
2175 ratchet_time = GNUNET_TIME_UNIT_HOURS;
2176 }
2177
2178
2179 id_key = key;
2180 tunnels = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_YES);
2181}
2182
2183
2184/**
2185 * Shut down the tunnel subsystem.
2186 */
2187void
2188GCT_shutdown (void)
2189{
2190 LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down tunnels\n");
2191 GNUNET_CONTAINER_multipeermap_iterate (tunnels, &destroy_iterator, NULL);
2192 GNUNET_CONTAINER_multipeermap_destroy (tunnels);
2193}
2194
2195
2196/**
2197 * Create a tunnel.
2198 *
2199 * @param destination Peer this tunnel is towards.
2200 */
2201struct CadetTunnel *
2202GCT_new (struct CadetPeer *destination)
2203{
2204 struct CadetTunnel *t;
2205
2206 t = GNUNET_new (struct CadetTunnel);
2207 t->next_ctn.cn = 0;
2208 t->peer = destination;
2209
2210 if (GNUNET_OK !=
2211 GNUNET_CONTAINER_multipeermap_put (tunnels, GCP_get_id (destination), t,
2212 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
2213 {
2214 GNUNET_break (0);
2215 GNUNET_free (t);
2216 return NULL;
2217 }
2218 t->ax = GNUNET_new (struct CadetTunnelAxolotl);
2219 new_ephemeral (t);
2220 t->ax->kx_0 = GNUNET_CRYPTO_ecdhe_key_create ();
2221 return t;
2222}
2223
2224
2225/**
2226 * Change the tunnel's connection state.
2227 *
2228 * @param t Tunnel whose connection state to change.
2229 * @param cstate New connection state.
2230 */
2231void
2232GCT_change_cstate (struct CadetTunnel* t, enum CadetTunnelCState cstate)
2233{
2234 if (NULL == t)
2235 return;
2236 LOG (GNUNET_ERROR_TYPE_DEBUG, "Tunnel %s cstate %s => %s\n",
2237 GCP_2s (t->peer), cstate2s (t->cstate), cstate2s (cstate));
2238 if (myid != GCP_get_short_id (t->peer) &&
2239 CADET_TUNNEL_READY != t->cstate &&
2240 CADET_TUNNEL_READY == cstate)
2241 {
2242 t->cstate = cstate;
2243 if (CADET_TUNNEL_KEY_OK == t->estate)
2244 {
2245 LOG (GNUNET_ERROR_TYPE_DEBUG, " cstate triggered send queued data\n");
2246 send_queued_data (t);
2247 }
2248 else if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate)
2249 {
2250 LOG (GNUNET_ERROR_TYPE_DEBUG, " cstate triggered KX\n");
2251 GCT_send_kx (t, GNUNET_NO);
2252 }
2253 else
2254 {
2255 LOG (GNUNET_ERROR_TYPE_DEBUG, "estate %s\n", estate2s (t->estate));
2256 }
2257 }
2258 t->cstate = cstate;
2259
2260 if (CADET_TUNNEL_READY == cstate
2261 && CONNECTIONS_PER_TUNNEL <= GCT_count_connections (t))
2262 {
2263 LOG (GNUNET_ERROR_TYPE_DEBUG, " cstate triggered stop dht\n");
2264 GCP_stop_search (t->peer);
2265 }
2266}
2267
2268
2269/**
2270 * Change the tunnel encryption state.
2271 *
2272 * If the encryption state changes to OK, stop the rekey task.
2273 *
2274 * @param t Tunnel whose encryption state to change, or NULL.
2275 * @param state New encryption state.
2276 */
2277void
2278GCT_change_estate (struct CadetTunnel* t, enum CadetTunnelEState state)
2279{
2280 enum CadetTunnelEState old;
2281
2282 if (NULL == t)
2283 return;
2284
2285 old = t->estate;
2286 t->estate = state;
2287 LOG (GNUNET_ERROR_TYPE_DEBUG, "Tunnel %s estate was %s\n",
2288 GCP_2s (t->peer), estate2s (old));
2289 LOG (GNUNET_ERROR_TYPE_DEBUG, "Tunnel %s estate is now %s\n",
2290 GCP_2s (t->peer), estate2s (t->estate));
2291
2292 if (CADET_TUNNEL_KEY_OK != old && CADET_TUNNEL_KEY_OK == t->estate)
2293 {
2294 if (NULL != t->rekey_task)
2295 {
2296 GNUNET_SCHEDULER_cancel (t->rekey_task);
2297 t->rekey_task = NULL;
2298 }
2299 /* Send queued data if tunnel is not loopback */
2300 if (myid != GCP_get_short_id (t->peer))
2301 send_queued_data (t);
2302 }
2303}
2304
2305
2306/**
2307 * @brief Check if tunnel has too many connections, and remove one if necessary.
2308 *
2309 * Currently this means the newest connection, unless it is a direct one.
2310 * Implemented as a task to avoid freeing a connection that is in the middle
2311 * of being created/processed.
2312 *
2313 * @param cls Closure (Tunnel to check).
2314 */
2315static void
2316trim_connections (void *cls)
2317{
2318 struct CadetTunnel *t = cls;
2319
2320 t->trim_connections_task = NULL;
2321 if (GCT_count_connections (t) > 2 * CONNECTIONS_PER_TUNNEL)
2322 {
2323 struct CadetTConnection *iter;
2324 struct CadetTConnection *c;
2325
2326 for (c = iter = t->connection_head; NULL != iter; iter = iter->next)
2327 {
2328 if ((iter->created.abs_value_us > c->created.abs_value_us)
2329 && GNUNET_NO == GCC_is_direct (iter->c))
2330 {
2331 c = iter;
2332 }
2333 }
2334 if (NULL != c)
2335 {
2336 LOG (GNUNET_ERROR_TYPE_DEBUG, "Too many connections on tunnel %s\n",
2337 GCT_2s (t));
2338 LOG (GNUNET_ERROR_TYPE_DEBUG, "Destroying connection %s\n",
2339 GCC_2s (c->c));
2340 GCC_destroy (c->c);
2341 }
2342 else
2343 {
2344 GNUNET_break (0);
2345 }
2346 }
2347}
2348
2349
2350/**
2351 * Add a connection to a tunnel.
2352 *
2353 * @param t Tunnel.
2354 * @param c Connection.
2355 */
2356void
2357GCT_add_connection (struct CadetTunnel *t, struct CadetConnection *c)
2358{
2359 struct CadetTConnection *aux;
2360
2361 GNUNET_assert (NULL != c);
2362
2363 LOG (GNUNET_ERROR_TYPE_DEBUG, "add connection %s\n", GCC_2s (c));
2364 LOG (GNUNET_ERROR_TYPE_DEBUG, " to tunnel %s\n", GCT_2s (t));
2365 for (aux = t->connection_head; aux != NULL; aux = aux->next)
2366 if (aux->c == c)
2367 return;
2368
2369 aux = GNUNET_new (struct CadetTConnection);
2370 aux->c = c;
2371 aux->created = GNUNET_TIME_absolute_get ();
2372
2373 GNUNET_CONTAINER_DLL_insert (t->connection_head, t->connection_tail, aux);
2374
2375 if (CADET_TUNNEL_SEARCHING == t->cstate)
2376 GCT_change_cstate (t, CADET_TUNNEL_WAITING);
2377
2378 if (NULL != t->trim_connections_task)
2379 t->trim_connections_task = GNUNET_SCHEDULER_add_now (&trim_connections, t);
2380}
2381
2382
2383/**
2384 * Remove a connection from a tunnel.
2385 *
2386 * @param t Tunnel.
2387 * @param c Connection.
2388 */
2389void
2390GCT_remove_connection (struct CadetTunnel *t,
2391 struct CadetConnection *c)
2392{
2393 struct CadetTConnection *aux;
2394 struct CadetTConnection *next;
2395 unsigned int conns;
2396
2397 LOG (GNUNET_ERROR_TYPE_DEBUG, "Removing connection %s from tunnel %s\n",
2398 GCC_2s (c), GCT_2s (t));
2399 for (aux = t->connection_head; aux != NULL; aux = next)
2400 {
2401 next = aux->next;
2402 if (aux->c == c)
2403 {
2404 GNUNET_CONTAINER_DLL_remove (t->connection_head, t->connection_tail, aux);
2405 GNUNET_free (aux);
2406 }
2407 }
2408
2409 conns = GCT_count_connections (t);
2410 if (0 == conns
2411 && NULL == t->destroy_task
2412 && CADET_TUNNEL_SHUTDOWN != t->cstate
2413 && GNUNET_NO == shutting_down)
2414 {
2415 if (0 == GCT_count_any_connections (t))
2416 GCT_change_cstate (t, CADET_TUNNEL_SEARCHING);
2417 else
2418 GCT_change_cstate (t, CADET_TUNNEL_WAITING);
2419 }
2420
2421 /* Start new connections if needed */
2422 if (CONNECTIONS_PER_TUNNEL > conns
2423 && CADET_TUNNEL_SHUTDOWN != t->cstate
2424 && GNUNET_NO == shutting_down)
2425 {
2426 LOG (GNUNET_ERROR_TYPE_DEBUG, " too few connections, getting new ones\n");
2427 GCP_connect (t->peer); /* Will change cstate to WAITING when possible */
2428 return;
2429 }
2430
2431 /* If not marked as ready, no change is needed */
2432 if (CADET_TUNNEL_READY != t->cstate)
2433 return;
2434
2435 /* Check if any connection is ready to maintain cstate */
2436 for (aux = t->connection_head; aux != NULL; aux = aux->next)
2437 if (CADET_CONNECTION_READY == GCC_get_state (aux->c))
2438 return;
2439}
2440
2441
2442/**
2443 * Add a channel to a tunnel.
2444 *
2445 * @param t Tunnel.
2446 * @param ch Channel.
2447 */
2448void
2449GCT_add_channel (struct CadetTunnel *t,
2450 struct CadetChannel *ch)
2451{
2452 struct CadetTChannel *aux;
2453
2454 GNUNET_assert (NULL != ch);
2455
2456 LOG (GNUNET_ERROR_TYPE_DEBUG, "Adding channel %p to tunnel %p\n", ch, t);
2457
2458 for (aux = t->channel_head; aux != NULL; aux = aux->next)
2459 {
2460 LOG (GNUNET_ERROR_TYPE_DEBUG, " already there %p\n", aux->ch);
2461 if (aux->ch == ch)
2462 return;
2463 }
2464
2465 aux = GNUNET_new (struct CadetTChannel);
2466 aux->ch = ch;
2467 LOG (GNUNET_ERROR_TYPE_DEBUG,
2468 " adding %p to %p\n", aux, t->channel_head);
2469 GNUNET_CONTAINER_DLL_insert_tail (t->channel_head,
2470 t->channel_tail,
2471 aux);
2472
2473 if (NULL != t->destroy_task)
2474 {
2475 GNUNET_SCHEDULER_cancel (t->destroy_task);
2476 t->destroy_task = NULL;
2477 LOG (GNUNET_ERROR_TYPE_DEBUG, " undo destroy!\n");
2478 }
2479}
2480
2481
2482/**
2483 * Remove a channel from a tunnel.
2484 *
2485 * @param t Tunnel.
2486 * @param ch Channel.
2487 */
2488void
2489GCT_remove_channel (struct CadetTunnel *t, struct CadetChannel *ch)
2490{
2491 struct CadetTChannel *aux;
2492
2493 LOG (GNUNET_ERROR_TYPE_DEBUG, "Removing channel %p from tunnel %p\n", ch, t);
2494 for (aux = t->channel_head; aux != NULL; aux = aux->next)
2495 {
2496 if (aux->ch == ch)
2497 {
2498 LOG (GNUNET_ERROR_TYPE_DEBUG, " found! %s\n", GCCH_2s (ch));
2499 GNUNET_CONTAINER_DLL_remove (t->channel_head,
2500 t->channel_tail,
2501 aux);
2502 GNUNET_free (aux);
2503 return;
2504 }
2505 }
2506}
2507
2508
2509/**
2510 * Search for a channel by global ID.
2511 *
2512 * @param t Tunnel containing the channel.
2513 * @param ctn Public channel number.
2514 *
2515 * @return channel handler, NULL if doesn't exist
2516 */
2517struct CadetChannel *
2518GCT_get_channel (struct CadetTunnel *t,
2519 struct GNUNET_CADET_ChannelTunnelNumber ctn)
2520{
2521 struct CadetTChannel *iter;
2522
2523 if (NULL == t)
2524 return NULL;
2525
2526 for (iter = t->channel_head; NULL != iter; iter = iter->next)
2527 {
2528 if (GCCH_get_id (iter->ch).cn == ctn.cn)
2529 break;
2530 }
2531
2532 return NULL == iter ? NULL : iter->ch;
2533}
2534
2535
2536/**
2537 * @brief Destroy a tunnel and free all resources.
2538 *
2539 * Should only be called a while after the tunnel has been marked as destroyed,
2540 * in case there is a new channel added to the same peer shortly after marking
2541 * the tunnel. This way we avoid a new public key handshake.
2542 *
2543 * @param cls Closure (tunnel to destroy).
2544 */
2545static void
2546delayed_destroy (void *cls)
2547{
2548 struct CadetTunnel *t = cls;
2549 struct CadetTConnection *iter;
2550
2551 t->destroy_task = NULL;
2552 LOG (GNUNET_ERROR_TYPE_DEBUG,
2553 "delayed destroying tunnel %p\n",
2554 t);
2555 t->cstate = CADET_TUNNEL_SHUTDOWN;
2556 for (iter = t->connection_head; NULL != iter; iter = iter->next)
2557 {
2558 GCC_send_destroy (iter->c);
2559 }
2560 GCT_destroy (t);
2561}
2562
2563
2564/**
2565 * Tunnel is empty: destroy it.
2566 *
2567 * Notifies all connections about the destruction.
2568 *
2569 * @param t Tunnel to destroy.
2570 */
2571void
2572GCT_destroy_empty (struct CadetTunnel *t)
2573{
2574 if (GNUNET_YES == shutting_down)
2575 return; /* Will be destroyed immediately anyway */
2576
2577 if (NULL != t->destroy_task)
2578 {
2579 LOG (GNUNET_ERROR_TYPE_WARNING,
2580 "Tunnel %s is already scheduled for destruction. Tunnel debug dump:\n",
2581 GCT_2s (t));
2582 GCT_debug (t, GNUNET_ERROR_TYPE_WARNING);
2583 GNUNET_break (0);
2584 /* should never happen, tunnel can only become empty once, and the
2585 * task identifier should be NO_TASK (cleaned when the tunnel was created
2586 * or became un-empty)
2587 */
2588 return;
2589 }
2590
2591 LOG (GNUNET_ERROR_TYPE_DEBUG, "Tunnel %s empty: scheduling destruction\n",
2592 GCT_2s (t));
2593
2594 // FIXME make delay a config option
2595 t->destroy_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
2596 &delayed_destroy, t);
2597 LOG (GNUNET_ERROR_TYPE_DEBUG, "Scheduled destroy of %p as %p\n",
2598 t, t->destroy_task);
2599}
2600
2601
2602/**
2603 * Destroy tunnel if empty (no more channels).
2604 *
2605 * @param t Tunnel to destroy if empty.
2606 */
2607void
2608GCT_destroy_if_empty (struct CadetTunnel *t)
2609{
2610 LOG (GNUNET_ERROR_TYPE_DEBUG, "Tunnel %s destroy if empty\n", GCT_2s (t));
2611 if (0 < GCT_count_channels (t))
2612 return;
2613
2614 GCT_destroy_empty (t);
2615}
2616
2617
2618/**
2619 * Destroy the tunnel.
2620 *
2621 * This function does not generate any warning traffic to clients or peers.
2622 *
2623 * Tasks:
2624 * Cancel messages belonging to this tunnel queued to neighbors.
2625 * Free any allocated resources linked to the tunnel.
2626 *
2627 * @param t The tunnel to destroy.
2628 */
2629void
2630GCT_destroy (struct CadetTunnel *t)
2631{
2632 struct CadetTConnection *iter_c;
2633 struct CadetTConnection *next_c;
2634 struct CadetTChannel *iter_ch;
2635 struct CadetTChannel *next_ch;
2636 unsigned int keepalives_queued;
2637
2638 if (NULL == t)
2639 return;
2640
2641 LOG (GNUNET_ERROR_TYPE_DEBUG,
2642 "destroying tunnel %s\n",
2643 GCP_2s (t->peer));
2644 GNUNET_break (GNUNET_YES ==
2645 GNUNET_CONTAINER_multipeermap_remove (tunnels,
2646 GCP_get_id (t->peer), t));
2647
2648 for (iter_c = t->connection_head; NULL != iter_c; iter_c = next_c)
2649 {
2650 next_c = iter_c->next;
2651 GCC_destroy (iter_c->c);
2652 }
2653 for (iter_ch = t->channel_head; NULL != iter_ch; iter_ch = next_ch)
2654 {
2655 next_ch = iter_ch->next;
2656 GCCH_destroy (iter_ch->ch);
2657 /* Should only happen on shutdown, but it's ok. */
2658 }
2659 keepalives_queued = 0;
2660 while (NULL != t->tq_head)
2661 {
2662 /* Should have been cleaned by destuction of channel. */
2663 struct GNUNET_MessageHeader *mh;
2664 uint16_t type;
2665
2666 mh = (struct GNUNET_MessageHeader *) &t->tq_head[1];
2667 type = ntohs (mh->type);
2668 if (0 == keepalives_queued && GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE == type)
2669 {
2670 keepalives_queued = 1;
2671 LOG (GNUNET_ERROR_TYPE_DEBUG,
2672 "one keepalive left behind on tunnel shutdown\n");
2673 }
2674 else if (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY == type)
2675 {
2676 LOG (GNUNET_ERROR_TYPE_WARNING,
2677 "tunnel destroyed before a CHANNEL_DESTROY was sent to peer\n");
2678 }
2679 else
2680 {
2681 GNUNET_break (0);
2682 LOG (GNUNET_ERROR_TYPE_ERROR,
2683 "message left behind on tunnel shutdown: %s\n",
2684 GC_m2s (type));
2685 }
2686 unqueue_data (t->tq_head);
2687 }
2688
2689
2690 if (NULL != t->destroy_task)
2691 {
2692 LOG (GNUNET_ERROR_TYPE_DEBUG,
2693 "cancelling dest: %p\n",
2694 t->destroy_task);
2695 GNUNET_SCHEDULER_cancel (t->destroy_task);
2696 t->destroy_task = NULL;
2697 }
2698
2699 if (NULL != t->trim_connections_task)
2700 {
2701 LOG (GNUNET_ERROR_TYPE_DEBUG, "cancelling trim: %p\n",
2702 t->trim_connections_task);
2703 GNUNET_SCHEDULER_cancel (t->trim_connections_task);
2704 t->trim_connections_task = NULL;
2705 }
2706
2707 GNUNET_STATISTICS_update (stats, "# tunnels", -1, GNUNET_NO);
2708 GCP_set_tunnel (t->peer, NULL);
2709
2710 if (NULL != t->rekey_task)
2711 {
2712 GNUNET_SCHEDULER_cancel (t->rekey_task);
2713 t->rekey_task = NULL;
2714 }
2715 if (NULL != t->ax)
2716 destroy_ax (t);
2717
2718 GNUNET_free (t);
2719}
2720
2721
2722/**
2723 * @brief Use the given path for the tunnel.
2724 * Update the next and prev hops (and RCs).
2725 * (Re)start the path refresh in case the tunnel is locally owned.
2726 *
2727 * @param t Tunnel to update.
2728 * @param p Path to use.
2729 *
2730 * @return Connection created.
2731 */
2732struct CadetConnection *
2733GCT_use_path (struct CadetTunnel *t, struct CadetPeerPath *path)
2734{
2735 struct CadetConnection *c;
2736 struct GNUNET_CADET_ConnectionTunnelIdentifier cid;
2737 unsigned int own_pos;
2738
2739 if (NULL == t || NULL == path)
2740 {
2741 GNUNET_break (0);
2742 return NULL;
2743 }
2744
2745 if (CADET_TUNNEL_SHUTDOWN == t->cstate)
2746 {
2747 GNUNET_break (0);
2748 return NULL;
2749 }
2750
2751 for (own_pos = 0; own_pos < path->length; own_pos++)
2752 {
2753 if (path->peers[own_pos] == myid)
2754 break;
2755 }
2756 if (own_pos >= path->length)
2757 {
2758 GNUNET_break_op (0);
2759 return NULL;
2760 }
2761
2762 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, &cid, sizeof (cid));
2763 c = GCC_new (&cid, t, path, own_pos);
2764 if (NULL == c)
2765 {
2766 /* Path was flawed */
2767 return NULL;
2768 }
2769 GCT_add_connection (t, c);
2770 return c;
2771}
2772
2773
2774/**
2775 * Count all created connections of a tunnel. Not necessarily ready connections!
2776 *
2777 * @param t Tunnel on which to count.
2778 *
2779 * @return Number of connections created, either being established or ready.
2780 */
2781unsigned int
2782GCT_count_any_connections (struct CadetTunnel *t)
2783{
2784 struct CadetTConnection *iter;
2785 unsigned int count;
2786
2787 if (NULL == t)
2788 return 0;
2789
2790 for (count = 0, iter = t->connection_head; NULL != iter; iter = iter->next)
2791 count++;
2792
2793 return count;
2794}
2795
2796
2797/**
2798 * Count established (ready) connections of a tunnel.
2799 *
2800 * @param t Tunnel on which to count.
2801 *
2802 * @return Number of connections.
2803 */
2804unsigned int
2805GCT_count_connections (struct CadetTunnel *t)
2806{
2807 struct CadetTConnection *iter;
2808 unsigned int count;
2809
2810 if (NULL == t)
2811 return 0;
2812
2813 for (count = 0, iter = t->connection_head; NULL != iter; iter = iter->next)
2814 if (CADET_CONNECTION_READY == GCC_get_state (iter->c))
2815 count++;
2816
2817 return count;
2818}
2819
2820
2821/**
2822 * Count channels of a tunnel.
2823 *
2824 * @param t Tunnel on which to count.
2825 *
2826 * @return Number of channels.
2827 */
2828unsigned int
2829GCT_count_channels (struct CadetTunnel *t)
2830{
2831 struct CadetTChannel *iter;
2832 unsigned int count;
2833
2834 for (count = 0, iter = t->channel_head;
2835 NULL != iter;
2836 iter = iter->next, count++) /* skip */;
2837
2838 return count;
2839}
2840
2841
2842/**
2843 * Get the connectivity state of a tunnel.
2844 *
2845 * @param t Tunnel.
2846 *
2847 * @return Tunnel's connectivity state.
2848 */
2849enum CadetTunnelCState
2850GCT_get_cstate (struct CadetTunnel *t)
2851{
2852 if (NULL == t)
2853 {
2854 GNUNET_assert (0);
2855 return (enum CadetTunnelCState) -1;
2856 }
2857 return t->cstate;
2858}
2859
2860
2861/**
2862 * Get the encryption state of a tunnel.
2863 *
2864 * @param t Tunnel.
2865 *
2866 * @return Tunnel's encryption state.
2867 */
2868enum CadetTunnelEState
2869GCT_get_estate (struct CadetTunnel *t)
2870{
2871 if (NULL == t)
2872 {
2873 GNUNET_break (0);
2874 return (enum CadetTunnelEState) -1;
2875 }
2876 return t->estate;
2877}
2878
2879/**
2880 * Get the maximum buffer space for a tunnel towards a local client.
2881 *
2882 * @param t Tunnel.
2883 *
2884 * @return Biggest buffer space offered by any channel in the tunnel.
2885 */
2886unsigned int
2887GCT_get_channels_buffer (struct CadetTunnel *t)
2888{
2889 struct CadetTChannel *iter;
2890 unsigned int buffer;
2891 unsigned int ch_buf;
2892
2893 if (NULL == t->channel_head)
2894 {
2895 /* Probably getting buffer for a channel create/handshake. */
2896 LOG (GNUNET_ERROR_TYPE_DEBUG, " no channels, allow max\n");
2897 return MIN_TUNNEL_BUFFER;
2898 }
2899
2900 buffer = 0;
2901 for (iter = t->channel_head; NULL != iter; iter = iter->next)
2902 {
2903 ch_buf = get_channel_buffer (iter);
2904 if (ch_buf > buffer)
2905 buffer = ch_buf;
2906 }
2907 if (MIN_TUNNEL_BUFFER > buffer)
2908 return MIN_TUNNEL_BUFFER;
2909
2910 if (MAX_TUNNEL_BUFFER < buffer)
2911 {
2912 GNUNET_break (0);
2913 return MAX_TUNNEL_BUFFER;
2914 }
2915 return buffer;
2916}
2917
2918
2919/**
2920 * Get the total buffer space for a tunnel for P2P traffic.
2921 *
2922 * @param t Tunnel.
2923 *
2924 * @return Buffer space offered by all connections in the tunnel.
2925 */
2926unsigned int
2927GCT_get_connections_buffer (struct CadetTunnel *t)
2928{
2929 struct CadetTConnection *iter;
2930 unsigned int buffer;
2931
2932 if (GNUNET_NO == is_ready (t))
2933 {
2934 if (count_queued_data (t) >= 3)
2935 return 0;
2936 else
2937 return 1;
2938 }
2939
2940 buffer = 0;
2941 for (iter = t->connection_head; NULL != iter; iter = iter->next)
2942 {
2943 if (GCC_get_state (iter->c) != CADET_CONNECTION_READY)
2944 {
2945 continue;
2946 }
2947 buffer += get_connection_buffer (iter);
2948 }
2949
2950 return buffer;
2951}
2952
2953
2954/**
2955 * Get the tunnel's destination.
2956 *
2957 * @param t Tunnel.
2958 *
2959 * @return ID of the destination peer.
2960 */
2961const struct GNUNET_PeerIdentity *
2962GCT_get_destination (struct CadetTunnel *t)
2963{
2964 return GCP_get_id (t->peer);
2965}
2966
2967
2968/**
2969 * Get the tunnel's next free global channel ID.
2970 *
2971 * @param t Tunnel.
2972 *
2973 * @return GID of a channel free to use.
2974 */
2975struct GNUNET_CADET_ChannelTunnelNumber
2976GCT_get_next_ctn (struct CadetTunnel *t)
2977{
2978 struct GNUNET_CADET_ChannelTunnelNumber ctn;
2979 struct GNUNET_CADET_ChannelTunnelNumber mask;
2980 int result;
2981
2982 /* Set bit 30 depending on the ID relationship. Bit 31 is always 0 for GID.
2983 * If our ID is bigger or loopback tunnel, start at 0, bit 30 = 0
2984 * If peer's ID is bigger, start at 0x4... bit 30 = 1
2985 */
2986 result = GNUNET_CRYPTO_cmp_peer_identity (&my_full_id, GCP_get_id (t->peer));
2987 if (0 > result)
2988 mask.cn = htonl (0x40000000);
2989 else
2990 mask.cn = 0x0;
2991 t->next_ctn.cn |= mask.cn;
2992
2993 while (NULL != GCT_get_channel (t, t->next_ctn))
2994 {
2995 LOG (GNUNET_ERROR_TYPE_DEBUG,
2996 "Channel %u exists...\n",
2997 t->next_ctn.cn);
2998 t->next_ctn.cn = htonl ((ntohl (t->next_ctn.cn) + 1) & ~GNUNET_CADET_LOCAL_CHANNEL_ID_CLI);
2999 t->next_ctn.cn |= mask.cn;
3000 }
3001 ctn = t->next_ctn;
3002 t->next_ctn.cn = (t->next_ctn.cn + 1) & ~GNUNET_CADET_LOCAL_CHANNEL_ID_CLI;
3003 t->next_ctn.cn |= mask.cn;
3004
3005 return ctn;
3006}
3007
3008
3009/**
3010 * Send ACK on one or more channels due to buffer in connections.
3011 *
3012 * @param t Channel which has some free buffer space.
3013 */
3014void
3015GCT_unchoke_channels (struct CadetTunnel *t)
3016{
3017 struct CadetTChannel *iter;
3018 unsigned int buffer;
3019 unsigned int channels = GCT_count_channels (t);
3020 unsigned int choked_n;
3021 struct CadetChannel *choked[channels];
3022
3023 LOG (GNUNET_ERROR_TYPE_DEBUG, "GCT_unchoke_channels on %s\n", GCT_2s (t));
3024 LOG (GNUNET_ERROR_TYPE_DEBUG, " head: %p\n", t->channel_head);
3025 if (NULL != t->channel_head)
3026 LOG (GNUNET_ERROR_TYPE_DEBUG, " head ch: %p\n", t->channel_head->ch);
3027
3028 if (NULL != t->tq_head)
3029 send_queued_data (t);
3030
3031 /* Get buffer space */
3032 buffer = GCT_get_connections_buffer (t);
3033 if (0 == buffer)
3034 {
3035 return;
3036 }
3037
3038 /* Count and remember choked channels */
3039 choked_n = 0;
3040 for (iter = t->channel_head; NULL != iter; iter = iter->next)
3041 {
3042 if (GNUNET_NO == get_channel_allowed (iter))
3043 {
3044 choked[choked_n++] = iter->ch;
3045 }
3046 }
3047
3048 /* Unchoke random channels */
3049 while (0 < buffer && 0 < choked_n)
3050 {
3051 unsigned int r = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
3052 choked_n);
3053 GCCH_allow_client (choked[r], GCCH_is_origin (choked[r], GNUNET_YES));
3054 choked_n--;
3055 buffer--;
3056 choked[r] = choked[choked_n];
3057 }
3058}
3059
3060
3061/**
3062 * Send ACK on one or more connections due to buffer space to the client.
3063 *
3064 * Iterates all connections of the tunnel and sends ACKs appropriately.
3065 *
3066 * @param t Tunnel.
3067 */
3068void
3069GCT_send_connection_acks (struct CadetTunnel *t)
3070{
3071 struct CadetTConnection *iter;
3072 uint32_t allowed;
3073 uint32_t to_allow;
3074 uint32_t allow_per_connection;
3075 unsigned int cs;
3076 unsigned int buffer;
3077
3078 LOG (GNUNET_ERROR_TYPE_DEBUG, "Tunnel send connection ACKs on %s\n",
3079 GCT_2s (t));
3080
3081 if (NULL == t)
3082 {
3083 GNUNET_break (0);
3084 return;
3085 }
3086
3087 if (CADET_TUNNEL_READY != t->cstate)
3088 return;
3089
3090 buffer = GCT_get_channels_buffer (t);
3091 LOG (GNUNET_ERROR_TYPE_DEBUG, " buffer %u\n", buffer);
3092
3093 /* Count connections, how many messages are already allowed */
3094 cs = GCT_count_connections (t);
3095 for (allowed = 0, iter = t->connection_head; NULL != iter; iter = iter->next)
3096 {
3097 allowed += get_connection_allowed (iter);
3098 }
3099 LOG (GNUNET_ERROR_TYPE_DEBUG, " allowed %u\n", allowed);
3100
3101 /* Make sure there is no overflow */
3102 if (allowed > buffer)
3103 return;
3104
3105 /* Authorize connections to send more data */
3106 to_allow = buffer - allowed;
3107
3108 for (iter = t->connection_head;
3109 NULL != iter && to_allow > 0;
3110 iter = iter->next)
3111 {
3112 if (CADET_CONNECTION_READY != GCC_get_state (iter->c)
3113 || get_connection_allowed (iter) > 64 / 3)
3114 {
3115 continue;
3116 }
3117 GNUNET_assert(cs != 0);
3118 allow_per_connection = to_allow/cs;
3119 to_allow -= allow_per_connection;
3120 cs--;
3121 GCC_allow (iter->c, allow_per_connection,
3122 GCC_is_origin (iter->c, GNUNET_NO));
3123 }
3124
3125 if (0 != to_allow)
3126 {
3127 /* Since we don't allow if it's allowed to send 64/3, this can happen. */
3128 LOG (GNUNET_ERROR_TYPE_DEBUG, " reminding to_allow: %u\n", to_allow);
3129 }
3130}
3131
3132
3133/**
3134 * Cancel a previously sent message while it's in the queue.
3135 *
3136 * ONLY can be called before the continuation given to the send function
3137 * is called. Once the continuation is called, the message is no longer in the
3138 * queue.
3139 *
3140 * @param q Handle to the queue.
3141 */
3142void
3143GCT_cancel (struct CadetTunnelQueue *q)
3144{
3145 if (NULL != q->cq)
3146 {
3147 GNUNET_assert (NULL == q->tqd);
3148 GCC_cancel (q->cq);
3149 /* tun_message_sent() will be called and free q */
3150 }
3151 else if (NULL != q->tqd)
3152 {
3153 unqueue_data (q->tqd);
3154 q->tqd = NULL;
3155 if (NULL != q->cont)
3156 q->cont (q->cont_cls, NULL, q, 0, 0);
3157 GNUNET_free (q);
3158 }
3159 else
3160 {
3161 GNUNET_break (0);
3162 }
3163}
3164
3165
3166/**
3167 * Check if the tunnel has queued traffic.
3168 *
3169 * @param t Tunnel to check.
3170 *
3171 * @return #GNUNET_YES if there is queued traffic
3172 * #GNUNET_NO otherwise
3173 */
3174int
3175GCT_has_queued_traffic (struct CadetTunnel *t)
3176{
3177 return (NULL != t->tq_head) ? GNUNET_YES : GNUNET_NO;
3178}
3179
3180
3181/**
3182 * Sends an already built message on a tunnel, encrypting it and
3183 * choosing the best connection if not provided.
3184 *
3185 * @param message Message to send. Function modifies it.
3186 * @param t Tunnel on which this message is transmitted.
3187 * @param c Connection to use (autoselect if NULL).
3188 * @param force Force the tunnel to take the message (buffer overfill).
3189 * @param cont Continuation to call once message is really sent.
3190 * @param cont_cls Closure for @c cont.
3191 *
3192 * @return Handle to cancel message. NULL if @c cont is NULL.
3193 */
3194struct CadetTunnelQueue *
3195GCT_send_prebuilt_message (const struct GNUNET_MessageHeader *message,
3196 struct CadetTunnel *t,
3197 struct CadetConnection *c,
3198 int force, GCT_sent cont, void *cont_cls)
3199{
3200 return send_prebuilt_message (message, t, c, force, cont, cont_cls, NULL);
3201}
3202
3203
3204/**
3205 * Send a KX message.
3206 *
3207 * @param t Tunnel on which to send it.
3208 * @param force_reply Force the other peer to reply with a KX message.
3209 */
3210void
3211GCT_send_kx (struct CadetTunnel *t, int force_reply)
3212{
3213 static struct CadetEncryptedMessageIdentifier zero;
3214 struct CadetConnection *c;
3215 struct GNUNET_CADET_TunnelKeyExchangeMessage msg;
3216 enum GNUNET_CADET_KX_Flags flags;
3217
3218 LOG (GNUNET_ERROR_TYPE_INFO, "==> { KX} on %s\n", GCT_2s (t));
3219 if (NULL != t->ephm_h)
3220 {
3221 LOG (GNUNET_ERROR_TYPE_INFO, " already queued, nop\n");
3222 return;
3223 }
3224 GNUNET_assert (GNUNET_NO == GCT_is_loopback (t));
3225
3226 c = tunnel_get_connection (t);
3227 if (NULL == c)
3228 {
3229 if (NULL == t->destroy_task && CADET_TUNNEL_READY == t->cstate)
3230 {
3231 GNUNET_break (0);
3232 GCT_debug (t, GNUNET_ERROR_TYPE_ERROR);
3233 }
3234 return;
3235 }
3236
3237 msg.header.size = htons (sizeof (msg));
3238 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX);
3239 flags = GNUNET_CADET_KX_FLAG_NONE;
3240 if (GNUNET_YES == force_reply)
3241 flags |= GNUNET_CADET_KX_FLAG_FORCE_REPLY;
3242 msg.flags = htonl (flags);
3243 msg.cid = *GCC_get_id (c);
3244 GNUNET_CRYPTO_ecdhe_key_get_public (t->ax->kx_0, &msg.ephemeral_key);
3245 GNUNET_CRYPTO_ecdhe_key_get_public (t->ax->DHRs, &msg.ratchet_key);
3246
3247 t->ephm_h = GCC_send_prebuilt_message (&msg.header,
3248 UINT16_MAX,
3249 zero,
3250 c,
3251 GCC_is_origin (c, GNUNET_YES),
3252 GNUNET_YES, &ephm_sent, t);
3253 if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate)
3254 GCT_change_estate (t, CADET_TUNNEL_KEY_SENT);
3255}
3256
3257
3258/**
3259 * Is the tunnel directed towards the local peer?
3260 *
3261 * @param t Tunnel.
3262 *
3263 * @return #GNUNET_YES if it is loopback.
3264 */
3265int
3266GCT_is_loopback (const struct CadetTunnel *t)
3267{
3268 return (myid == GCP_get_short_id (t->peer));
3269}
3270
3271
3272/**
3273 * Is the tunnel this path already?
3274 *
3275 * @param t Tunnel.
3276 * @param p Path.
3277 *
3278 * @return #GNUNET_YES a connection uses this path.
3279 */
3280int
3281GCT_is_path_used (const struct CadetTunnel *t, const struct CadetPeerPath *p)
3282{
3283 struct CadetTConnection *iter;
3284
3285 for (iter = t->connection_head; NULL != iter; iter = iter->next)
3286 if (path_equivalent (GCC_get_path (iter->c), p))
3287 return GNUNET_YES;
3288
3289 return GNUNET_NO;
3290}
3291
3292
3293/**
3294 * Get a cost of a path for a tunnel considering existing connections.
3295 *
3296 * @param t Tunnel.
3297 * @param path Candidate path.
3298 *
3299 * @return Cost of the path (path length + number of overlapping nodes)
3300 */
3301unsigned int
3302GCT_get_path_cost (const struct CadetTunnel *t,
3303 const struct CadetPeerPath *path)
3304{
3305 struct CadetTConnection *iter;
3306 const struct CadetPeerPath *aux;
3307 unsigned int overlap;
3308 unsigned int i;
3309 unsigned int j;
3310
3311 if (NULL == path)
3312 return 0;
3313
3314 overlap = 0;
3315 GNUNET_assert (NULL != t);
3316
3317 for (i = 0; i < path->length; i++)
3318 {
3319 for (iter = t->connection_head; NULL != iter; iter = iter->next)
3320 {
3321 aux = GCC_get_path (iter->c);
3322 if (NULL == aux)
3323 continue;
3324
3325 for (j = 0; j < aux->length; j++)
3326 {
3327 if (path->peers[i] == aux->peers[j])
3328 {
3329 overlap++;
3330 break;
3331 }
3332 }
3333 }
3334 }
3335 return path->length + overlap;
3336}
3337
3338
3339/**
3340 * Get the static string for the peer this tunnel is directed.
3341 *
3342 * @param t Tunnel.
3343 *
3344 * @return Static string the destination peer's ID.
3345 */
3346const char *
3347GCT_2s (const struct CadetTunnel *t)
3348{
3349 if (NULL == t)
3350 return "(NULL)";
3351
3352 return GCP_2s (t->peer);
3353}
3354
3355
3356/******************************************************************************/
3357/***************************** INFO/DEBUG *******************************/
3358/******************************************************************************/
3359
3360static void
3361ax_debug (const struct CadetTunnelAxolotl *ax, enum GNUNET_ErrorType level)
3362{
3363 struct GNUNET_CRYPTO_EcdhePublicKey pub;
3364 struct CadetTunnelSkippedKey *iter;
3365
3366 LOG2 (level, "TTT RK \t %s\n",
3367 GNUNET_i2s ((struct GNUNET_PeerIdentity *) &ax->RK));
3368
3369 LOG2 (level, "TTT HKs \t %s\n",
3370 GNUNET_i2s ((struct GNUNET_PeerIdentity *) &ax->HKs));
3371 LOG2 (level, "TTT HKr \t %s\n",
3372 GNUNET_i2s ((struct GNUNET_PeerIdentity *) &ax->HKr));
3373 LOG2 (level, "TTT NHKs\t %s\n",
3374 GNUNET_i2s ((struct GNUNET_PeerIdentity *) &ax->NHKs));
3375 LOG2 (level, "TTT NHKr\t %s\n",
3376 GNUNET_i2s ((struct GNUNET_PeerIdentity *) &ax->NHKr));
3377
3378 LOG2 (level, "TTT CKs \t %s\n",
3379 GNUNET_i2s ((struct GNUNET_PeerIdentity *) &ax->CKs));
3380 LOG2 (level, "TTT CKr \t %s\n",
3381 GNUNET_i2s ((struct GNUNET_PeerIdentity *) &ax->CKr));
3382
3383 GNUNET_CRYPTO_ecdhe_key_get_public (ax->DHRs, &pub);
3384 LOG2 (level, "TTT DHRs\t %s\n",
3385 GNUNET_i2s ((struct GNUNET_PeerIdentity *) &pub));
3386 LOG2 (level, "TTT DHRr\t %s\n",
3387 GNUNET_i2s ((struct GNUNET_PeerIdentity *) &ax->DHRr));
3388
3389 LOG2 (level, "TTT Nr\t %u\tNs\t%u\n", ax->Nr, ax->Ns);
3390 LOG2 (level, "TTT PNs\t %u\tSkipped\t%u\n", ax->PNs, ax->skipped);
3391 LOG2 (level, "TTT Ratchet\t%u\n", ax->ratchet_flag);
3392
3393 for (iter = ax->skipped_head; NULL != iter; iter = iter->next)
3394 {
3395 LOG2 (level, "TTT HK\t %s\n",
3396 GNUNET_i2s ((struct GNUNET_PeerIdentity *) &iter->HK));
3397 LOG2 (level, "TTT MK\t %s\n",
3398 GNUNET_i2s ((struct GNUNET_PeerIdentity *) &iter->MK));
3399 }
3400}
3401
3402/**
3403 * Log all possible info about the tunnel state.
3404 *
3405 * @param t Tunnel to debug.
3406 * @param level Debug level to use.
3407 */
3408void
3409GCT_debug (const struct CadetTunnel *t, enum GNUNET_ErrorType level)
3410{
3411 struct CadetTChannel *iter_ch;
3412 struct CadetTConnection *iter_c;
3413 int do_log;
3414
3415 do_log = GNUNET_get_log_call_status (level & (~GNUNET_ERROR_TYPE_BULK),
3416 "cadet-tun",
3417 __FILE__, __FUNCTION__, __LINE__);
3418 if (0 == do_log)
3419 return;
3420
3421 LOG2 (level, "TTT DEBUG TUNNEL TOWARDS %s\n", GCT_2s (t));
3422 LOG2 (level, "TTT cstate %s, estate %s\n",
3423 cstate2s (t->cstate), estate2s (t->estate));
3424#if DUMP_KEYS_TO_STDERR
3425 ax_debug (t->ax, level);
3426#endif
3427 LOG2 (level, "TTT tq_head %p, tq_tail %p\n", t->tq_head, t->tq_tail);
3428 LOG2 (level, "TTT destroy %p\n", t->destroy_task);
3429 LOG2 (level, "TTT channels:\n");
3430 for (iter_ch = t->channel_head; NULL != iter_ch; iter_ch = iter_ch->next)
3431 {
3432 GCCH_debug (iter_ch->ch, level);
3433 }
3434
3435 LOG2 (level, "TTT connections:\n");
3436 for (iter_c = t->connection_head; NULL != iter_c; iter_c = iter_c->next)
3437 {
3438 GCC_debug (iter_c->c, level);
3439 }
3440
3441 LOG2 (level, "TTT DEBUG TUNNEL END\n");
3442}
3443
3444
3445/**
3446 * Iterate all tunnels.
3447 *
3448 * @param iter Iterator.
3449 * @param cls Closure for @c iter.
3450 */
3451void
3452GCT_iterate_all (GNUNET_CONTAINER_PeerMapIterator iter, void *cls)
3453{
3454 GNUNET_CONTAINER_multipeermap_iterate (tunnels, iter, cls);
3455}
3456
3457
3458/**
3459 * Count all tunnels.
3460 *
3461 * @return Number of tunnels to remote peers kept by this peer.
3462 */
3463unsigned int
3464GCT_count_all (void)
3465{
3466 return GNUNET_CONTAINER_multipeermap_size (tunnels);
3467}
3468
3469
3470/**
3471 * Iterate all connections of a tunnel.
3472 *
3473 * @param t Tunnel whose connections to iterate.
3474 * @param iter Iterator.
3475 * @param cls Closure for @c iter.
3476 */
3477void
3478GCT_iterate_connections (struct CadetTunnel *t, GCT_conn_iter iter, void *cls)
3479{
3480 struct CadetTConnection *ct;
3481
3482 for (ct = t->connection_head; NULL != ct; ct = ct->next)
3483 iter (cls, ct->c);
3484}
3485
3486
3487/**
3488 * Iterate all channels of a tunnel.
3489 *
3490 * @param t Tunnel whose channels to iterate.
3491 * @param iter Iterator.
3492 * @param cls Closure for @c iter.
3493 */
3494void
3495GCT_iterate_channels (struct CadetTunnel *t, GCT_chan_iter iter, void *cls)
3496{
3497 struct CadetTChannel *cht;
3498
3499 for (cht = t->channel_head; NULL != cht; cht = cht->next)
3500 iter (cls, cht->ch);
3501}
diff --git a/src/cadet/gnunet-service-cadet_tunnel.h b/src/cadet/gnunet-service-cadet_tunnel.h
deleted file mode 100644
index 0abdc02ce..000000000
--- a/src/cadet/gnunet-service-cadet_tunnel.h
+++ /dev/null
@@ -1,616 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2013 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 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 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file cadet/gnunet-service-cadet_tunnel.h
23 * @brief cadet service; dealing with tunnels and crypto
24 * @author Bartlomiej Polot
25 *
26 * All functions in this file should use the prefix GMT (Gnunet Cadet Tunnel)
27 */
28
29#ifndef GNUNET_SERVICE_CADET_TUNNEL_H
30#define GNUNET_SERVICE_CADET_TUNNEL_H
31
32#ifdef __cplusplus
33extern "C"
34{
35#if 0 /* keep Emacsens' auto-indent happy */
36}
37#endif
38#endif
39
40#include "platform.h"
41#include "gnunet_util_lib.h"
42
43#define CONNECTIONS_PER_TUNNEL 3
44
45/**
46 * All the connectivity states a tunnel can be in.
47 */
48enum CadetTunnelCState
49{
50 /**
51 * Uninitialized status, should never appear in operation.
52 */
53 CADET_TUNNEL_NEW,
54
55 /**
56 * No path to the peer known yet.
57 */
58 CADET_TUNNEL_SEARCHING,
59
60 /**
61 * Request sent, not yet answered.
62 */
63 CADET_TUNNEL_WAITING,
64
65 /**
66 * Peer connected and ready to accept data.
67 */
68 CADET_TUNNEL_READY,
69
70 /**
71 * Tunnel being shut down, don't try to keep it alive.
72 */
73 CADET_TUNNEL_SHUTDOWN
74};
75
76
77/**
78 * All the encryption states a tunnel can be in.
79 */
80enum CadetTunnelEState
81{
82 /**
83 * Uninitialized status, should never appear in operation.
84 */
85 CADET_TUNNEL_KEY_UNINITIALIZED,
86
87 /**
88 * Ephemeral key sent, waiting for peer's key.
89 */
90 CADET_TUNNEL_KEY_SENT,
91
92 /**
93 * In OTR: New ephemeral key and ping sent, waiting for pong.
94 *
95 * This means that we DO have the peer's ephemeral key, otherwise the
96 * state would be KEY_SENT. We DO NOT have a valid session key (either no
97 * previous key or previous key expired).
98 *
99 *
100 * In Axolotl: Key sent and received but no deciphered traffic yet.
101 *
102 * This means that we can send traffic (otherwise we would never complete
103 * the handshake), but we don't have complete confirmation. Since the first
104 * traffic MUST be a complete channel creation 3-way handshake, no payload
105 * will be sent before confirmation.
106 */
107 CADET_TUNNEL_KEY_PING,
108
109 /**
110 * Handshake completed: session key available.
111 */
112 CADET_TUNNEL_KEY_OK,
113
114 /**
115 * New ephemeral key and ping sent, waiting for pong. Unlike KEY_PING,
116 * we still have a valid session key and therefore we *can* still send
117 * traffic on the tunnel.
118 */
119 CADET_TUNNEL_KEY_REKEY
120};
121
122/**
123 * Struct containing all information regarding a given peer
124 */
125struct CadetTunnel;
126
127
128#include "gnunet-service-cadet_channel.h"
129#include "gnunet-service-cadet_connection.h"
130#include "gnunet-service-cadet_peer.h"
131
132/**
133 * Handle for messages queued but not yet sent.
134 */
135struct CadetTunnelQueue;
136
137/**
138 * Callback called when a queued message is sent.
139 *
140 * @param cls Closure.
141 * @param t Tunnel this message was on.
142 * @param type Type of message sent.
143 * @param size Size of the message.
144 */
145typedef void
146(*GCT_sent) (void *cls,
147 struct CadetTunnel *t,
148 struct CadetTunnelQueue *q,
149 uint16_t type, size_t size);
150
151typedef void
152(*GCT_conn_iter) (void *cls, struct CadetConnection *c);
153
154
155typedef void
156(*GCT_chan_iter) (void *cls, struct CadetChannel *ch);
157
158
159/******************************************************************************/
160/******************************** API ***********************************/
161/******************************************************************************/
162
163/**
164 * Initialize tunnel subsystem.
165 *
166 * @param c Configuration handle.
167 * @param key ECC private key, to derive all other keys and do crypto.
168 */
169void
170GCT_init (const struct GNUNET_CONFIGURATION_Handle *c,
171 const struct GNUNET_CRYPTO_EddsaPrivateKey *key);
172
173
174/**
175 * Shut down the tunnel subsystem.
176 */
177void
178GCT_shutdown (void);
179
180
181/**
182 * Create a tunnel.
183 *
184 * @param destination Peer this tunnel is towards.
185 */
186struct CadetTunnel *
187GCT_new (struct CadetPeer *destination);
188
189
190/**
191 * Tunnel is empty: destroy it.
192 *
193 * Notifies all connections about the destruction.
194 *
195 * @param t Tunnel to destroy.
196 */
197void
198GCT_destroy_empty (struct CadetTunnel *t);
199
200
201/**
202 * Destroy tunnel if empty (no more channels).
203 *
204 * @param t Tunnel to destroy if empty.
205 */
206void
207GCT_destroy_if_empty (struct CadetTunnel *t);
208
209
210/**
211 * Destroy the tunnel.
212 *
213 * This function does not generate any warning traffic to clients or peers.
214 *
215 * Tasks:
216 * Cancel messages belonging to this tunnel queued to neighbors.
217 * Free any allocated resources linked to the tunnel.
218 *
219 * @param t The tunnel to destroy.
220 */
221void
222GCT_destroy (struct CadetTunnel *t);
223
224
225/**
226 * Change the tunnel's connection state.
227 *
228 * @param t Tunnel whose connection state to change.
229 * @param cstate New connection state.
230 */
231void
232GCT_change_cstate (struct CadetTunnel* t, enum CadetTunnelCState cstate);
233
234
235/**
236 * Change the tunnel encryption state.
237 *
238 * @param t Tunnel whose encryption state to change.
239 * @param state New encryption state.
240 */
241void
242GCT_change_estate (struct CadetTunnel* t, enum CadetTunnelEState state);
243
244
245/**
246 * Add a connection to a tunnel.
247 *
248 * @param t Tunnel.
249 * @param c Connection.
250 */
251void
252GCT_add_connection (struct CadetTunnel *t, struct CadetConnection *c);
253
254
255/**
256 * Remove a connection from a tunnel.
257 *
258 * @param t Tunnel.
259 * @param c Connection.
260 */
261void
262GCT_remove_connection (struct CadetTunnel *t, struct CadetConnection *c);
263
264
265/**
266 * Add a channel to a tunnel.
267 *
268 * @param t Tunnel.
269 * @param ch Channel.
270 */
271void
272GCT_add_channel (struct CadetTunnel *t, struct CadetChannel *ch);
273
274
275/**
276 * Remove a channel from a tunnel.
277 *
278 * @param t Tunnel.
279 * @param ch Channel.
280 */
281void
282GCT_remove_channel (struct CadetTunnel *t, struct CadetChannel *ch);
283
284
285/**
286 * Search for a channel by global ID.
287 *
288 * @param t Tunnel containing the channel.
289 * @param ctn Public channel number.
290 *
291 * @return channel handler, NULL if doesn't exist
292 */
293struct CadetChannel *
294GCT_get_channel (struct CadetTunnel *t, struct GNUNET_CADET_ChannelTunnelNumber ctn);
295
296
297/**
298 * Decrypt and process an encrypted message.
299 *
300 * Calls the appropriate handler for a message in a channel of a local tunnel.
301 *
302 * @param t Tunnel this message came on.
303 * @param msg Message header.
304 */
305void
306GCT_handle_encrypted (struct CadetTunnel *t,
307 const struct GNUNET_CADET_TunnelEncryptedMessage *msg);
308
309
310/**
311 * Handle a Key eXchange message.
312 *
313 * @param t Tunnel on which the message came.
314 * @param msg KX message itself.
315 */
316void
317GCT_handle_kx (struct CadetTunnel *t,
318 const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg);
319
320
321/**
322 * @brief Use the given path for the tunnel.
323 * Update the next and prev hops (and RCs).
324 * (Re)start the path refresh in case the tunnel is locally owned.
325 *
326 * @param t Tunnel to update.
327 * @param p Path to use.
328 *
329 * @return Connection created.
330 */
331struct CadetConnection *
332GCT_use_path (struct CadetTunnel *t, struct CadetPeerPath *p);
333
334
335/**
336 * Count all created connections of a tunnel. Not necessarily ready connections!
337 *
338 * @param t Tunnel on which to count.
339 *
340 * @return Number of connections created, either being established or ready.
341 */
342unsigned int
343GCT_count_any_connections (struct CadetTunnel *t);
344
345
346/**
347 * Count established (ready) connections of a tunnel.
348 *
349 * @param t Tunnel on which to count.
350 *
351 * @return Number of connections.
352 */
353unsigned int
354GCT_count_connections (struct CadetTunnel *t);
355
356
357/**
358 * Count channels of a tunnel.
359 *
360 * @param t Tunnel on which to count.
361 *
362 * @return Number of channels.
363 */
364unsigned int
365GCT_count_channels (struct CadetTunnel *t);
366
367
368/**
369 * Get the connectivity state of a tunnel.
370 *
371 * @param t Tunnel.
372 *
373 * @return Tunnel's connectivity state.
374 */
375enum CadetTunnelCState
376GCT_get_cstate (struct CadetTunnel *t);
377
378
379/**
380 * Get the encryption state of a tunnel.
381 *
382 * @param t Tunnel.
383 *
384 * @return Tunnel's encryption state.
385 */
386enum CadetTunnelEState
387GCT_get_estate (struct CadetTunnel *t);
388
389
390/**
391 * Get the maximum buffer space for a tunnel towards a local client.
392 *
393 * @param t Tunnel.
394 *
395 * @return Biggest buffer space offered by any channel in the tunnel.
396 */
397unsigned int
398GCT_get_channels_buffer (struct CadetTunnel *t);
399
400
401/**
402 * Get the total buffer space for a tunnel for P2P traffic.
403 *
404 * @param t Tunnel.
405 *
406 * @return Buffer space offered by all connections in the tunnel.
407 */
408unsigned int
409GCT_get_connections_buffer (struct CadetTunnel *t);
410
411
412/**
413 * Get the tunnel's destination.
414 *
415 * @param t Tunnel.
416 *
417 * @return ID of the destination peer.
418 */
419const struct GNUNET_PeerIdentity *
420GCT_get_destination (struct CadetTunnel *t);
421
422
423/**
424 * Get the tunnel's next free Channel ID.
425 *
426 * @param t Tunnel.
427 *
428 * @return ID of a channel free to use.
429 */
430struct GNUNET_CADET_ChannelTunnelNumber
431GCT_get_next_ctn (struct CadetTunnel *t);
432
433
434/**
435 * Send ACK on one or more channels due to buffer in connections.
436 *
437 * @param t Channel which has some free buffer space.
438 */
439void
440GCT_unchoke_channels (struct CadetTunnel *t);
441
442
443/**
444 * Send ACK on one or more connections due to buffer space to the client.
445 *
446 * Iterates all connections of the tunnel and sends ACKs appropriately.
447 *
448 * @param t Tunnel which has some free buffer space.
449 */
450void
451GCT_send_connection_acks (struct CadetTunnel *t);
452
453
454/**
455 * Cancel a previously sent message while it's in the queue.
456 *
457 * ONLY can be called before the continuation given to the send function
458 * is called. Once the continuation is called, the message is no longer in the
459 * queue.
460 *
461 * @param q Handle to the queue.
462 */
463void
464GCT_cancel (struct CadetTunnelQueue *q);
465
466
467/**
468 * Check if the tunnel has queued traffic.
469 *
470 * @param t Tunnel to check.
471 *
472 * @return #GNUNET_YES if there is queued traffic
473 * #GNUNET_NO otherwise
474 */
475int
476GCT_has_queued_traffic (struct CadetTunnel *t);
477
478/**
479 * Sends an already built message on a tunnel, encrypting it and
480 * choosing the best connection.
481 *
482 * @param message Message to send. Function modifies it.
483 * @param t Tunnel on which this message is transmitted.
484 * @param c Connection to use (autoselect if NULL).
485 * @param force Force the tunnel to take the message (buffer overfill).
486 * @param cont Continuation to call once message is really sent.
487 * @param cont_cls Closure for @c cont.
488 *
489 * @return Handle to cancel message. NULL if @c cont is NULL.
490 */
491struct CadetTunnelQueue *
492GCT_send_prebuilt_message (const struct GNUNET_MessageHeader *message,
493 struct CadetTunnel *t, struct CadetConnection *c,
494 int force, GCT_sent cont, void *cont_cls);
495
496
497/**
498 * Send a KX message.
499 *
500 * @param t Tunnel on which to send it.
501 * @param force_reply Force the other peer to reply with a KX message.
502 */
503void
504GCT_send_kx (struct CadetTunnel *t, int force_reply);
505
506
507/**
508 * Is the tunnel directed towards the local peer?
509 *
510 * @param t Tunnel.
511 *
512 * @return #GNUNET_YES if it is loopback.
513 */
514int
515GCT_is_loopback (const struct CadetTunnel *t);
516
517
518/**
519 * Is the tunnel using this path already?
520 *
521 * @param t Tunnel.
522 * @param p Path.
523 *
524 * @return #GNUNET_YES a connection uses this path.
525 */
526int
527GCT_is_path_used (const struct CadetTunnel *t, const struct CadetPeerPath *p);
528
529
530/**
531 * Get a cost of a path for a tunnel considering existing connections.
532 *
533 * @param t Tunnel.
534 * @param path Candidate path.
535 *
536 * @return Cost of the path (path length + number of overlapping nodes)
537 */
538unsigned int
539GCT_get_path_cost (const struct CadetTunnel *t,
540 const struct CadetPeerPath *path);
541
542
543/**
544 * Get the static string for the peer this tunnel is directed.
545 *
546 * @param t Tunnel.
547 *
548 * @return Static string the destination peer's ID.
549 */
550const char *
551GCT_2s (const struct CadetTunnel *t);
552
553
554/**
555 * Log all possible info about the tunnel state.
556 *
557 * @param t Tunnel to debug.
558 * @param level Debug level to use.
559 */
560void
561GCT_debug (const struct CadetTunnel *t, enum GNUNET_ErrorType level);
562
563
564/**
565 * Iterate all tunnels.
566 *
567 * @param iter Iterator.
568 * @param cls Closure for @c iter.
569 */
570void
571GCT_iterate_all (GNUNET_CONTAINER_PeerMapIterator iter, void *cls);
572
573
574/**
575 * Count all tunnels.
576 *
577 * @return Number of tunnels to remote peers kept by this peer.
578 */
579unsigned int
580GCT_count_all (void);
581
582
583/**
584 * Iterate all connections of a tunnel.
585 *
586 * @param t Tunnel whose connections to iterate.
587 * @param iter Iterator.
588 * @param cls Closure for @c iter.
589 */
590void
591GCT_iterate_connections (struct CadetTunnel *t, GCT_conn_iter iter, void *cls);
592
593
594/**
595 * Iterate all channels of a tunnel.
596 *
597 * @param t Tunnel whose channels to iterate.
598 * @param iter Iterator.
599 * @param cls Closure for @c iter.
600 */
601void
602GCT_iterate_channels (struct CadetTunnel *t,
603 GCT_chan_iter iter,
604 void *cls);
605
606
607#if 0 /* keep Emacsens' auto-indent happy */
608{
609#endif
610#ifdef __cplusplus
611}
612#endif
613
614/* ifndef GNUNET_CADET_SERVICE_TUNNEL_H */
615#endif
616/* end of gnunet-cadet-service_tunnel.h */
diff --git a/src/cadet/gnunet-service-cadet-new_tunnels.c b/src/cadet/gnunet-service-cadet_tunnels.c
index fd8335486..28004debc 100644
--- a/src/cadet/gnunet-service-cadet-new_tunnels.c
+++ b/src/cadet/gnunet-service-cadet_tunnels.c
@@ -18,35 +18,38 @@
18 Boston, MA 02110-1301, USA. 18 Boston, MA 02110-1301, USA.
19*/ 19*/
20/** 20/**
21 * @file cadet/gnunet-service-cadet-new_tunnels.c 21 * @file cadet/gnunet-service-cadet_tunnels.c
22 * @brief Information we track per tunnel. 22 * @brief Information we track per tunnel.
23 * @author Bartlomiej Polot 23 * @author Bartlomiej Polot
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 * 25 *
26 * FIXME: 26 * FIXME:
27 * - check KX estate machine -- make sure it is never stuck! 27 * - proper connection evaluation during connection management:
28 * - clean up KX logic, including adding sender authentication 28 * + consider quality (or quality spread?) of current connection set
29 * - implement connection management (evaluate, kill old ones, 29 * when deciding how often to do maintenance
30 * search for new ones) 30 * + interact with PEER to drive DHT GET/PUT operations based
31 * - when managing connections, distinguish those that 31 * on how much we like our connections
32 * have (recently) had traffic from those that were
33 * never ready (or not recently)
34 */ 32 */
35#include "platform.h" 33#include "platform.h"
36#include "gnunet_util_lib.h" 34#include "gnunet_util_lib.h"
37#include "gnunet_statistics_service.h" 35#include "gnunet_statistics_service.h"
38#include "gnunet_signatures.h" 36#include "gnunet_signatures.h"
39#include "gnunet-service-cadet-new.h"
40#include "cadet_protocol.h" 37#include "cadet_protocol.h"
41#include "gnunet-service-cadet-new_channel.h" 38#include "gnunet-service-cadet_channel.h"
42#include "gnunet-service-cadet-new_connection.h" 39#include "gnunet-service-cadet_connection.h"
43#include "gnunet-service-cadet-new_tunnels.h" 40#include "gnunet-service-cadet_tunnels.h"
44#include "gnunet-service-cadet-new_peer.h" 41#include "gnunet-service-cadet_peer.h"
45#include "gnunet-service-cadet-new_paths.h" 42#include "gnunet-service-cadet_paths.h"
46 43
47 44
48#define LOG(level, ...) GNUNET_log_from(level,"cadet-tun",__VA_ARGS__) 45#define LOG(level, ...) GNUNET_log_from(level,"cadet-tun",__VA_ARGS__)
49 46
47/**
48 * How often do we try to decrypt payload with unverified key
49 * material? Used to limit CPU increase upon receiving bogus
50 * KX.
51 */
52#define MAX_UNVERIFIED_ATTEMPTS 16
50 53
51/** 54/**
52 * How long do we wait until tearing down an idle tunnel? 55 * How long do we wait until tearing down an idle tunnel?
@@ -54,12 +57,10 @@
54#define IDLE_DESTROY_DELAY GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 90) 57#define IDLE_DESTROY_DELAY GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 90)
55 58
56/** 59/**
57 * Yuck, replace by 'offsetof' expression? 60 * How long do we wait initially before retransmitting the KX?
58 * FIXME. 61 * TODO: replace by 2 RTT if/once we have connection-level RTT data!
59 */ 62 */
60#define AX_HEADER_SIZE (sizeof (uint32_t) * 2\ 63#define INITIAL_KX_RETRY_DELAY GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 250)
61 + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey))
62
63 64
64/** 65/**
65 * Maximum number of skipped keys we keep in memory per tunnel. 66 * Maximum number of skipped keys we keep in memory per tunnel.
@@ -133,52 +134,61 @@ struct CadetTunnelAxolotl
133 struct GNUNET_CRYPTO_SymmetricSessionKey RK; 134 struct GNUNET_CRYPTO_SymmetricSessionKey RK;
134 135
135 /** 136 /**
136 * 32-byte header key (send). 137 * 32-byte header key (currently used for sending).
137 */ 138 */
138 struct GNUNET_CRYPTO_SymmetricSessionKey HKs; 139 struct GNUNET_CRYPTO_SymmetricSessionKey HKs;
139 140
140 /** 141 /**
141 * 32-byte header key (recv) 142 * 32-byte header key (currently used for receiving)
142 */ 143 */
143 struct GNUNET_CRYPTO_SymmetricSessionKey HKr; 144 struct GNUNET_CRYPTO_SymmetricSessionKey HKr;
144 145
145 /** 146 /**
146 * 32-byte next header key (send). 147 * 32-byte next header key (for sending), used once the
148 * ratchet advances. We are sure that the sender has this
149 * key as well only after @e ratchet_allowed is #GNUNET_YES.
147 */ 150 */
148 struct GNUNET_CRYPTO_SymmetricSessionKey NHKs; 151 struct GNUNET_CRYPTO_SymmetricSessionKey NHKs;
149 152
150 /** 153 /**
151 * 32-byte next header key (recv). 154 * 32-byte next header key (for receiving). To be tried
155 * when decrypting with @e HKr fails and thus the sender
156 * may have advanced the ratchet.
152 */ 157 */
153 struct GNUNET_CRYPTO_SymmetricSessionKey NHKr; 158 struct GNUNET_CRYPTO_SymmetricSessionKey NHKr;
154 159
155 /** 160 /**
156 * 32-byte chain keys (used for forward-secrecy updating, send). 161 * 32-byte chain keys (used for forward-secrecy) for
162 * sending messages. Updated for every message.
157 */ 163 */
158 struct GNUNET_CRYPTO_SymmetricSessionKey CKs; 164 struct GNUNET_CRYPTO_SymmetricSessionKey CKs;
159 165
160 /** 166 /**
161 * 32-byte chain keys (used for forward-secrecy updating, recv). 167 * 32-byte chain keys (used for forward-secrecy) for
168 * receiving messages. Updated for every message. If
169 * messages are skipped, the respective derived MKs
170 * (and the current @HKr) are kept in the @e skipped_head DLL.
162 */ 171 */
163 struct GNUNET_CRYPTO_SymmetricSessionKey CKr; 172 struct GNUNET_CRYPTO_SymmetricSessionKey CKr;
164 173
165 /** 174 /**
166 * ECDH for key exchange (A0 / B0). 175 * ECDH for key exchange (A0 / B0).
167 */ 176 */
168 struct GNUNET_CRYPTO_EcdhePrivateKey *kx_0; 177 struct GNUNET_CRYPTO_EcdhePrivateKey kx_0;
169 178
170 /** 179 /**
171 * ECDH Ratchet key (send). 180 * ECDH Ratchet key (our private key in the current DH).
172 */ 181 */
173 struct GNUNET_CRYPTO_EcdhePrivateKey *DHRs; 182 struct GNUNET_CRYPTO_EcdhePrivateKey DHRs;
174 183
175 /** 184 /**
176 * ECDH Ratchet key (recv). 185 * ECDH Ratchet key (other peer's public key in the current DH).
177 */ 186 */
178 struct GNUNET_CRYPTO_EcdhePublicKey DHRr; 187 struct GNUNET_CRYPTO_EcdhePublicKey DHRr;
179 188
180 /** 189 /**
181 * When does this ratchet expire and a new one is triggered. 190 * Time when the current ratchet expires and a new one is triggered
191 * (if @e ratchet_allowed is #GNUNET_YES).
182 */ 192 */
183 struct GNUNET_TIME_Absolute ratchet_expiration; 193 struct GNUNET_TIME_Absolute ratchet_expiration;
184 194
@@ -208,16 +218,28 @@ struct CadetTunnelAxolotl
208 int ratchet_flag; 218 int ratchet_flag;
209 219
210 /** 220 /**
211 * Number of messages recieved since our last ratchet advance. 221 * True (#GNUNET_YES) if we have received a message from the
212 * - If this counter = 0, we cannot send a new ratchet key in next msg. 222 * other peer that uses the keys from our last ratchet step.
213 * - If this counter > 0, we can (but don't yet have to) send a new key. 223 * This implies that we are again allowed to advance the ratchet,
224 * otherwise we have to wait until the other peer sees our current
225 * ephemeral key and advances first.
226 *
227 * #GNUNET_NO if we have advanced the ratched but lack any evidence
228 * that the other peer has noticed this.
214 */ 229 */
215 unsigned int ratchet_allowed; 230 int ratchet_allowed;
216 231
217 /** 232 /**
218 * Number of messages recieved since our last ratchet advance. 233 * Number of messages recieved since our last ratchet advance.
219 * - If this counter = 0, we cannot send a new ratchet key in next msg. 234 *
220 * - If this counter > 0, we can (but don't yet have to) send a new key. 235 * If this counter = 0, we cannot send a new ratchet key in the next
236 * message.
237 *
238 * If this counter > 0, we could (but don't have to) send a new key.
239 *
240 * Once the @e ratchet_counter is larger than
241 * #ratchet_messages (or @e ratchet_expiration time has past), and
242 * @e ratchet_allowed is #GNUNET_YES, we advance the ratchet.
221 */ 243 */
222 unsigned int ratchet_counter; 244 unsigned int ratchet_counter;
223 245
@@ -247,7 +269,7 @@ struct CadetTunnelQueueEntry
247 /** 269 /**
248 * Continuation to call once sent (on the channel layer). 270 * Continuation to call once sent (on the channel layer).
249 */ 271 */
250 GNUNET_SCHEDULER_TaskCallback cont; 272 GCT_SendContinuation cont;
251 273
252 /** 274 /**
253 * Closure for @c cont. 275 * Closure for @c cont.
@@ -299,6 +321,15 @@ struct CadetTunnel
299 struct CadetTunnelAxolotl ax; 321 struct CadetTunnelAxolotl ax;
300 322
301 /** 323 /**
324 * Unverified Axolotl info, used only if we got a fresh KX (not a
325 * KX_AUTH) while our end of the tunnel was still up. In this case,
326 * we keep the fresh KX around but do not put it into action until
327 * we got encrypted payload that assures us of the authenticity of
328 * the KX.
329 */
330 struct CadetTunnelAxolotl *unverified_ax;
331
332 /**
302 * Task scheduled if there are no more channels using the tunnel. 333 * Task scheduled if there are no more channels using the tunnel.
303 */ 334 */
304 struct GNUNET_SCHEDULER_Task *destroy_task; 335 struct GNUNET_SCHEDULER_Task *destroy_task;
@@ -329,14 +360,24 @@ struct CadetTunnel
329 struct GNUNET_MQ_Handle *mq; 360 struct GNUNET_MQ_Handle *mq;
330 361
331 /** 362 /**
332 * DLL of connections that are actively used to reach the destination peer. 363 * DLL of ready connections that are actively used to reach the destination peer.
333 */ 364 */
334 struct CadetTConnection *connection_head; 365 struct CadetTConnection *connection_ready_head;
335 366
336 /** 367 /**
337 * DLL of connections that are actively used to reach the destination peer. 368 * DLL of ready connections that are actively used to reach the destination peer.
338 */ 369 */
339 struct CadetTConnection *connection_tail; 370 struct CadetTConnection *connection_ready_tail;
371
372 /**
373 * DLL of connections that we maintain that might be used to reach the destination peer.
374 */
375 struct CadetTConnection *connection_busy_head;
376
377 /**
378 * DLL of connections that we maintain that might be used to reach the destination peer.
379 */
380 struct CadetTConnection *connection_busy_tail;
340 381
341 /** 382 /**
342 * Channels inside this tunnel. Maps 383 * Channels inside this tunnel. Maps
@@ -359,16 +400,12 @@ struct CadetTunnel
359 */ 400 */
360 struct CadetTunnelQueueEntry *tq_tail; 401 struct CadetTunnelQueueEntry *tq_tail;
361 402
362
363 /**
364 * Ephemeral message in the queue (to avoid queueing more than one).
365 */
366 struct CadetConnectionQueue *ephm_hKILL;
367
368 /** 403 /**
369 * Pong message in the queue. 404 * Identification of the connection from which we are currently processing
405 * a message. Only valid (non-NULL) during #handle_decrypted() and the
406 * handle-*()-functions called from our @e mq during that function.
370 */ 407 */
371 struct CadetConnectionQueue *pong_hKILL; 408 struct CadetTConnection *current_ct;
372 409
373 /** 410 /**
374 * How long do we wait until we retry the KX? 411 * How long do we wait until we retry the KX?
@@ -381,9 +418,21 @@ struct CadetTunnel
381 struct GNUNET_TIME_Absolute next_kx_attempt; 418 struct GNUNET_TIME_Absolute next_kx_attempt;
382 419
383 /** 420 /**
384 * Number of connections in the @e connection_head DLL. 421 * Number of connections in the @e connection_ready_head DLL.
385 */ 422 */
386 unsigned int num_connections; 423 unsigned int num_ready_connections;
424
425 /**
426 * Number of connections in the @e connection_busy_head DLL.
427 */
428 unsigned int num_busy_connections;
429
430 /**
431 * How often have we tried and failed to decrypt a message using
432 * the unverified KX material from @e unverified_ax? Used to
433 * stop trying after #MAX_UNVERIFIED_ATTEMPTS.
434 */
435 unsigned int unverified_attempts;
387 436
388 /** 437 /**
389 * Number of entries in the @e tq_head DLL. 438 * Number of entries in the @e tq_head DLL.
@@ -395,10 +444,40 @@ struct CadetTunnel
395 */ 444 */
396 enum CadetTunnelEState estate; 445 enum CadetTunnelEState estate;
397 446
447 /**
448 * Force triggering KX_AUTH independent of @e estate.
449 */
450 int kx_auth_requested;
451
398}; 452};
399 453
400 454
401/** 455/**
456 * Connection @a ct is now unready, clear it's ready flag
457 * and move it from the ready DLL to the busy DLL.
458 *
459 * @param ct connection to move to unready status
460 */
461static void
462mark_connection_unready (struct CadetTConnection *ct)
463{
464 struct CadetTunnel *t = ct->t;
465
466 GNUNET_assert (GNUNET_YES == ct->is_ready);
467 GNUNET_CONTAINER_DLL_remove (t->connection_ready_head,
468 t->connection_ready_tail,
469 ct);
470 GNUNET_assert (0 < t->num_ready_connections);
471 t->num_ready_connections--;
472 ct->is_ready = GNUNET_NO;
473 GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
474 t->connection_busy_tail,
475 ct);
476 t->num_busy_connections++;
477}
478
479
480/**
402 * Get the static string for the peer this tunnel is directed. 481 * Get the static string for the peer this tunnel is directed.
403 * 482 *
404 * @param t Tunnel. 483 * @param t Tunnel.
@@ -434,19 +513,24 @@ estate2s (enum CadetTunnelEState es)
434 513
435 switch (es) 514 switch (es)
436 { 515 {
437 case CADET_TUNNEL_KEY_UNINITIALIZED: 516 case CADET_TUNNEL_KEY_UNINITIALIZED:
438 return "CADET_TUNNEL_KEY_UNINITIALIZED"; 517 return "CADET_TUNNEL_KEY_UNINITIALIZED";
439 case CADET_TUNNEL_KEY_SENT: 518 case CADET_TUNNEL_KEY_AX_RECV:
440 return "CADET_TUNNEL_KEY_SENT"; 519 return "CADET_TUNNEL_KEY_AX_RECV";
441 case CADET_TUNNEL_KEY_PING: 520 case CADET_TUNNEL_KEY_AX_SENT:
442 return "CADET_TUNNEL_KEY_PING"; 521 return "CADET_TUNNEL_KEY_AX_SENT";
443 case CADET_TUNNEL_KEY_OK: 522 case CADET_TUNNEL_KEY_AX_SENT_AND_RECV:
444 return "CADET_TUNNEL_KEY_OK"; 523 return "CADET_TUNNEL_KEY_AX_SENT_AND_RECV";
445 case CADET_TUNNEL_KEY_REKEY: 524 case CADET_TUNNEL_KEY_AX_AUTH_SENT:
446 return "CADET_TUNNEL_KEY_REKEY"; 525 return "CADET_TUNNEL_KEY_AX_AUTH_SENT";
447 default: 526 case CADET_TUNNEL_KEY_OK:
448 SPRINTF (buf, "%u (UNKNOWN STATE)", es); 527 return "CADET_TUNNEL_KEY_OK";
449 return buf; 528 default:
529 GNUNET_snprintf (buf,
530 sizeof (buf),
531 "%u (UNKNOWN STATE)",
532 es);
533 return buf;
450 } 534 }
451} 535}
452 536
@@ -502,9 +586,9 @@ lookup_channel (struct CadetTunnel *t,
502 * @return Number of connections created, either being established or ready. 586 * @return Number of connections created, either being established or ready.
503 */ 587 */
504unsigned int 588unsigned int
505GCT_count_any_connections (struct CadetTunnel *t) 589GCT_count_any_connections (const struct CadetTunnel *t)
506{ 590{
507 return t->num_connections; 591 return t->num_ready_connections + t->num_busy_connections;
508} 592}
509 593
510 594
@@ -518,25 +602,11 @@ GCT_count_any_connections (struct CadetTunnel *t)
518static struct CadetTConnection * 602static struct CadetTConnection *
519get_ready_connection (struct CadetTunnel *t) 603get_ready_connection (struct CadetTunnel *t)
520{ 604{
521 for (struct CadetTConnection *pos = t->connection_head; 605 struct CadetTConnection *hd = t->connection_ready_head;
522 NULL != pos; 606
523 pos = pos->next) 607 GNUNET_assert ( (NULL == hd) ||
524 if (GNUNET_YES == pos->is_ready) 608 (GNUNET_YES == hd->is_ready) );
525 { 609 return hd;
526 if (pos != t->connection_tail)
527 {
528 /* move 'pos' to the end, so we try other ready connections
529 first next time (round-robin, modulo availability) */
530 GNUNET_CONTAINER_DLL_remove (t->connection_head,
531 t->connection_tail,
532 pos);
533 GNUNET_CONTAINER_DLL_insert_tail (t->connection_head,
534 t->connection_tail,
535 pos);
536 }
537 return pos;
538 }
539 return NULL;
540} 610}
541 611
542 612
@@ -555,20 +625,6 @@ GCT_get_estate (struct CadetTunnel *t)
555 625
556 626
557/** 627/**
558 * Create a new Axolotl ephemeral (ratchet) key.
559 *
560 * @param t Tunnel.
561 */
562static void
563new_ephemeral (struct CadetTunnel *t)
564{
565 GNUNET_free_non_null (t->ax.DHRs);
566 t->ax.DHRs = GNUNET_CRYPTO_ecdhe_key_create ();
567}
568
569
570
571/**
572 * Called when either we have a new connection, or a new message in the 628 * Called when either we have a new connection, or a new message in the
573 * queue, or some existing connection has transmission capacity. Looks 629 * queue, or some existing connection has transmission capacity. Looks
574 * at our message queue and if there is a message, picks a connection 630 * at our message queue and if there is a message, picks a connection
@@ -584,6 +640,21 @@ trigger_transmissions (void *cls);
584 640
585 641
586/** 642/**
643 * Create a new Axolotl ephemeral (ratchet) key.
644 *
645 * @param ax key material to update
646 */
647static void
648new_ephemeral (struct CadetTunnelAxolotl *ax)
649{
650 LOG (GNUNET_ERROR_TYPE_DEBUG,
651 "Creating new ephemeral ratchet key (DHRs)\n");
652 GNUNET_assert (GNUNET_OK ==
653 GNUNET_CRYPTO_ecdhe_key_create2 (&ax->DHRs));
654}
655
656
657/**
587 * Calculate HMAC. 658 * Calculate HMAC.
588 * 659 *
589 * @param plaintext Content to HMAC. 660 * @param plaintext Content to HMAC.
@@ -609,7 +680,8 @@ t_hmac (const void *plaintext,
609 key, sizeof (*key), 680 key, sizeof (*key),
610 ctx, sizeof (ctx), 681 ctx, sizeof (ctx),
611 NULL); 682 NULL);
612 /* Two step: CADET_Hash is only 256 bits, HashCode is 512. */ 683 /* Two step: GNUNET_ShortHash is only 256 bits,
684 GNUNET_HashCode is 512, so we truncate. */
613 GNUNET_CRYPTO_hmac (&auth_key, 685 GNUNET_CRYPTO_hmac (&auth_key,
614 plaintext, 686 plaintext,
615 size, 687 size,
@@ -624,7 +696,7 @@ t_hmac (const void *plaintext,
624 * Perform a HMAC. 696 * Perform a HMAC.
625 * 697 *
626 * @param key Key to use. 698 * @param key Key to use.
627 * @param hash[out] Resulting HMAC. 699 * @param[out] hash Resulting HMAC.
628 * @param source Source key material (data to HMAC). 700 * @param source Source key material (data to HMAC).
629 * @param len Length of @a source. 701 * @param len Length of @a source.
630 */ 702 */
@@ -679,23 +751,21 @@ t_hmac_derive_key (const struct GNUNET_CRYPTO_SymmetricSessionKey *key,
679/** 751/**
680 * Encrypt data with the axolotl tunnel key. 752 * Encrypt data with the axolotl tunnel key.
681 * 753 *
682 * @param t Tunnel whose key to use. 754 * @param ax key material to use.
683 * @param dst Destination with @a size bytes for the encrypted data. 755 * @param dst Destination with @a size bytes for the encrypted data.
684 * @param src Source of the plaintext. Can overlap with @c dst, must contain @a size bytes 756 * @param src Source of the plaintext. Can overlap with @c dst, must contain @a size bytes
685 * @param size Size of the buffers at @a src and @a dst 757 * @param size Size of the buffers at @a src and @a dst
686 */ 758 */
687static void 759static void
688t_ax_encrypt (struct CadetTunnel *t, 760t_ax_encrypt (struct CadetTunnelAxolotl *ax,
689 void *dst, 761 void *dst,
690 const void *src, 762 const void *src,
691 size_t size) 763 size_t size)
692{ 764{
693 struct GNUNET_CRYPTO_SymmetricSessionKey MK; 765 struct GNUNET_CRYPTO_SymmetricSessionKey MK;
694 struct GNUNET_CRYPTO_SymmetricInitializationVector iv; 766 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
695 struct CadetTunnelAxolotl *ax;
696 size_t out_size; 767 size_t out_size;
697 768
698 ax = &t->ax;
699 ax->ratchet_counter++; 769 ax->ratchet_counter++;
700 if ( (GNUNET_YES == ax->ratchet_allowed) && 770 if ( (GNUNET_YES == ax->ratchet_allowed) &&
701 ( (ratchet_messages <= ax->ratchet_counter) || 771 ( (ratchet_messages <= ax->ratchet_counter) ||
@@ -711,11 +781,11 @@ t_ax_encrypt (struct CadetTunnel *t,
711 struct GNUNET_HashCode hmac; 781 struct GNUNET_HashCode hmac;
712 static const char ctx[] = "axolotl ratchet"; 782 static const char ctx[] = "axolotl ratchet";
713 783
714 new_ephemeral (t); 784 new_ephemeral (ax);
715 ax->HKs = ax->NHKs; 785 ax->HKs = ax->NHKs;
716 786
717 /* RK, NHKs, CKs = KDF( HMAC-HASH(RK, DH(DHRs, DHRr)) ) */ 787 /* RK, NHKs, CKs = KDF( HMAC-HASH(RK, DH(DHRs, DHRr)) ) */
718 GNUNET_CRYPTO_ecc_ecdh (ax->DHRs, 788 GNUNET_CRYPTO_ecc_ecdh (&ax->DHRs,
719 &ax->DHRr, 789 &ax->DHRr,
720 &dh); 790 &dh);
721 t_ax_hmac_hash (&ax->RK, 791 t_ax_hmac_hash (&ax->RK,
@@ -765,23 +835,21 @@ t_ax_encrypt (struct CadetTunnel *t,
765/** 835/**
766 * Decrypt data with the axolotl tunnel key. 836 * Decrypt data with the axolotl tunnel key.
767 * 837 *
768 * @param t Tunnel whose key to use. 838 * @param ax key material to use.
769 * @param dst Destination for the decrypted data, must contain @a size bytes. 839 * @param dst Destination for the decrypted data, must contain @a size bytes.
770 * @param src Source of the ciphertext. Can overlap with @c dst, must contain @a size bytes. 840 * @param src Source of the ciphertext. Can overlap with @c dst, must contain @a size bytes.
771 * @param size Size of the @a src and @a dst buffers 841 * @param size Size of the @a src and @a dst buffers
772 */ 842 */
773static void 843static void
774t_ax_decrypt (struct CadetTunnel *t, 844t_ax_decrypt (struct CadetTunnelAxolotl *ax,
775 void *dst, 845 void *dst,
776 const void *src, 846 const void *src,
777 size_t size) 847 size_t size)
778{ 848{
779 struct GNUNET_CRYPTO_SymmetricSessionKey MK; 849 struct GNUNET_CRYPTO_SymmetricSessionKey MK;
780 struct GNUNET_CRYPTO_SymmetricInitializationVector iv; 850 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
781 struct CadetTunnelAxolotl *ax;
782 size_t out_size; 851 size_t out_size;
783 852
784 ax = &t->ax;
785 t_hmac_derive_key (&ax->CKr, 853 t_hmac_derive_key (&ax->CKr,
786 &MK, 854 &MK,
787 "0", 855 "0",
@@ -807,76 +875,72 @@ t_ax_decrypt (struct CadetTunnel *t,
807/** 875/**
808 * Encrypt header with the axolotl header key. 876 * Encrypt header with the axolotl header key.
809 * 877 *
810 * @param t Tunnel whose key to use. 878 * @param ax key material to use.
811 * @param msg Message whose header to encrypt. 879 * @param[in|out] msg Message whose header to encrypt.
812 */ 880 */
813static void 881static void
814t_h_encrypt (struct CadetTunnel *t, 882t_h_encrypt (struct CadetTunnelAxolotl *ax,
815 struct GNUNET_CADET_TunnelEncryptedMessage *msg) 883 struct GNUNET_CADET_TunnelEncryptedMessage *msg)
816{ 884{
817 struct GNUNET_CRYPTO_SymmetricInitializationVector iv; 885 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
818 struct CadetTunnelAxolotl *ax;
819 size_t out_size; 886 size_t out_size;
820 887
821 ax = &t->ax;
822 GNUNET_CRYPTO_symmetric_derive_iv (&iv, 888 GNUNET_CRYPTO_symmetric_derive_iv (&iv,
823 &ax->HKs, 889 &ax->HKs,
824 NULL, 0, 890 NULL, 0,
825 NULL); 891 NULL);
826 out_size = GNUNET_CRYPTO_symmetric_encrypt (&msg->Ns, 892 out_size = GNUNET_CRYPTO_symmetric_encrypt (&msg->ax_header,
827 AX_HEADER_SIZE, 893 sizeof (struct GNUNET_CADET_AxHeader),
828 &ax->HKs, 894 &ax->HKs,
829 &iv, 895 &iv,
830 &msg->Ns); 896 &msg->ax_header);
831 GNUNET_assert (AX_HEADER_SIZE == out_size); 897 GNUNET_assert (sizeof (struct GNUNET_CADET_AxHeader) == out_size);
832} 898}
833 899
834 900
835/** 901/**
836 * Decrypt header with the current axolotl header key. 902 * Decrypt header with the current axolotl header key.
837 * 903 *
838 * @param t Tunnel whose current ax HK to use. 904 * @param ax key material to use.
839 * @param src Message whose header to decrypt. 905 * @param src Message whose header to decrypt.
840 * @param dst Where to decrypt header to. 906 * @param dst Where to decrypt header to.
841 */ 907 */
842static void 908static void
843t_h_decrypt (struct CadetTunnel *t, 909t_h_decrypt (struct CadetTunnelAxolotl *ax,
844 const struct GNUNET_CADET_TunnelEncryptedMessage *src, 910 const struct GNUNET_CADET_TunnelEncryptedMessage *src,
845 struct GNUNET_CADET_TunnelEncryptedMessage *dst) 911 struct GNUNET_CADET_TunnelEncryptedMessage *dst)
846{ 912{
847 struct GNUNET_CRYPTO_SymmetricInitializationVector iv; 913 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
848 struct CadetTunnelAxolotl *ax;
849 size_t out_size; 914 size_t out_size;
850 915
851 ax = &t->ax;
852 GNUNET_CRYPTO_symmetric_derive_iv (&iv, 916 GNUNET_CRYPTO_symmetric_derive_iv (&iv,
853 &ax->HKr, 917 &ax->HKr,
854 NULL, 0, 918 NULL, 0,
855 NULL); 919 NULL);
856 out_size = GNUNET_CRYPTO_symmetric_decrypt (&src->Ns, 920 out_size = GNUNET_CRYPTO_symmetric_decrypt (&src->ax_header.Ns,
857 AX_HEADER_SIZE, 921 sizeof (struct GNUNET_CADET_AxHeader),
858 &ax->HKr, 922 &ax->HKr,
859 &iv, 923 &iv,
860 &dst->Ns); 924 &dst->ax_header.Ns);
861 GNUNET_assert (AX_HEADER_SIZE == out_size); 925 GNUNET_assert (sizeof (struct GNUNET_CADET_AxHeader) == out_size);
862} 926}
863 927
864 928
865/** 929/**
866 * Delete a key from the list of skipped keys. 930 * Delete a key from the list of skipped keys.
867 * 931 *
868 * @param t Tunnel to delete from. 932 * @param ax key material to delete @a key from.
869 * @param key Key to delete. 933 * @param key Key to delete.
870 */ 934 */
871static void 935static void
872delete_skipped_key (struct CadetTunnel *t, 936delete_skipped_key (struct CadetTunnelAxolotl *ax,
873 struct CadetTunnelSkippedKey *key) 937 struct CadetTunnelSkippedKey *key)
874{ 938{
875 GNUNET_CONTAINER_DLL_remove (t->ax.skipped_head, 939 GNUNET_CONTAINER_DLL_remove (ax->skipped_head,
876 t->ax.skipped_tail, 940 ax->skipped_tail,
877 key); 941 key);
878 GNUNET_free (key); 942 GNUNET_free (key);
879 t->ax.skipped--; 943 ax->skipped--;
880} 944}
881 945
882 946
@@ -884,14 +948,14 @@ delete_skipped_key (struct CadetTunnel *t,
884 * Decrypt and verify data with the appropriate tunnel key and verify that the 948 * Decrypt and verify data with the appropriate tunnel key and verify that the
885 * data has not been altered since it was sent by the remote peer. 949 * data has not been altered since it was sent by the remote peer.
886 * 950 *
887 * @param t Tunnel whose key to use. 951 * @param ax key material to use.
888 * @param dst Destination for the plaintext. 952 * @param dst Destination for the plaintext.
889 * @param src Source of the message. Can overlap with @c dst. 953 * @param src Source of the message. Can overlap with @c dst.
890 * @param size Size of the message. 954 * @param size Size of the message.
891 * @return Size of the decrypted data, -1 if an error was encountered. 955 * @return Size of the decrypted data, -1 if an error was encountered.
892 */ 956 */
893static ssize_t 957static ssize_t
894try_old_ax_keys (struct CadetTunnel *t, 958try_old_ax_keys (struct CadetTunnelAxolotl *ax,
895 void *dst, 959 void *dst,
896 const struct GNUNET_CADET_TunnelEncryptedMessage *src, 960 const struct GNUNET_CADET_TunnelEncryptedMessage *src,
897 size_t size) 961 size_t size)
@@ -913,10 +977,10 @@ try_old_ax_keys (struct CadetTunnel *t,
913 977
914 /* Find a correct Header Key */ 978 /* Find a correct Header Key */
915 valid_HK = NULL; 979 valid_HK = NULL;
916 for (key = t->ax.skipped_head; NULL != key; key = key->next) 980 for (key = ax->skipped_head; NULL != key; key = key->next)
917 { 981 {
918 t_hmac (&src->Ns, 982 t_hmac (&src->ax_header,
919 AX_HEADER_SIZE + esize, 983 sizeof (struct GNUNET_CADET_AxHeader) + esize,
920 0, 984 0,
921 &key->HK, 985 &key->HK,
922 hmac); 986 hmac);
@@ -941,15 +1005,15 @@ try_old_ax_keys (struct CadetTunnel *t,
941 &key->HK, 1005 &key->HK,
942 NULL, 0, 1006 NULL, 0,
943 NULL); 1007 NULL);
944 res = GNUNET_CRYPTO_symmetric_decrypt (&src->Ns, 1008 res = GNUNET_CRYPTO_symmetric_decrypt (&src->ax_header.Ns,
945 AX_HEADER_SIZE, 1009 sizeof (struct GNUNET_CADET_AxHeader),
946 &key->HK, 1010 &key->HK,
947 &iv, 1011 &iv,
948 &plaintext_header.Ns); 1012 &plaintext_header.ax_header.Ns);
949 GNUNET_assert (AX_HEADER_SIZE == res); 1013 GNUNET_assert (sizeof (struct GNUNET_CADET_AxHeader) == res);
950 1014
951 /* Find the correct message key */ 1015 /* Find the correct message key */
952 N = ntohl (plaintext_header.Ns); 1016 N = ntohl (plaintext_header.ax_header.Ns);
953 while ( (NULL != key) && 1017 while ( (NULL != key) &&
954 (N != key->Kn) ) 1018 (N != key->Kn) )
955 key = key->next; 1019 key = key->next;
@@ -970,7 +1034,7 @@ try_old_ax_keys (struct CadetTunnel *t,
970 &key->MK, 1034 &key->MK,
971 &iv, 1035 &iv,
972 dst); 1036 dst);
973 delete_skipped_key (t, 1037 delete_skipped_key (ax,
974 key); 1038 key);
975 return res; 1039 return res;
976} 1040}
@@ -979,32 +1043,32 @@ try_old_ax_keys (struct CadetTunnel *t,
979/** 1043/**
980 * Delete a key from the list of skipped keys. 1044 * Delete a key from the list of skipped keys.
981 * 1045 *
982 * @param t Tunnel to delete from. 1046 * @param ax key material to delete from.
983 * @param HKr Header Key to use. 1047 * @param HKr Header Key to use.
984 */ 1048 */
985static void 1049static void
986store_skipped_key (struct CadetTunnel *t, 1050store_skipped_key (struct CadetTunnelAxolotl *ax,
987 const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr) 1051 const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr)
988{ 1052{
989 struct CadetTunnelSkippedKey *key; 1053 struct CadetTunnelSkippedKey *key;
990 1054
991 key = GNUNET_new (struct CadetTunnelSkippedKey); 1055 key = GNUNET_new (struct CadetTunnelSkippedKey);
992 key->timestamp = GNUNET_TIME_absolute_get (); 1056 key->timestamp = GNUNET_TIME_absolute_get ();
993 key->Kn = t->ax.Nr; 1057 key->Kn = ax->Nr;
994 key->HK = t->ax.HKr; 1058 key->HK = ax->HKr;
995 t_hmac_derive_key (&t->ax.CKr, 1059 t_hmac_derive_key (&ax->CKr,
996 &key->MK, 1060 &key->MK,
997 "0", 1061 "0",
998 1); 1062 1);
999 t_hmac_derive_key (&t->ax.CKr, 1063 t_hmac_derive_key (&ax->CKr,
1000 &t->ax.CKr, 1064 &ax->CKr,
1001 "1", 1065 "1",
1002 1); 1066 1);
1003 GNUNET_CONTAINER_DLL_insert (t->ax.skipped_head, 1067 GNUNET_CONTAINER_DLL_insert (ax->skipped_head,
1004 t->ax.skipped_tail, 1068 ax->skipped_tail,
1005 key); 1069 key);
1006 t->ax.skipped++; 1070 ax->skipped++;
1007 t->ax.Nr++; 1071 ax->Nr++;
1008} 1072}
1009 1073
1010 1074
@@ -1012,33 +1076,33 @@ store_skipped_key (struct CadetTunnel *t,
1012 * Stage skipped AX keys and calculate the message key. 1076 * Stage skipped AX keys and calculate the message key.
1013 * Stores each HK and MK for skipped messages. 1077 * Stores each HK and MK for skipped messages.
1014 * 1078 *
1015 * @param t Tunnel where to stage the keys. 1079 * @param ax key material to use
1016 * @param HKr Header key. 1080 * @param HKr Header key.
1017 * @param Np Received meesage number. 1081 * @param Np Received meesage number.
1018 * @return #GNUNET_OK if keys were stored. 1082 * @return #GNUNET_OK if keys were stored.
1019 * #GNUNET_SYSERR if an error ocurred (Np not expected). 1083 * #GNUNET_SYSERR if an error ocurred (@a Np not expected).
1020 */ 1084 */
1021static int 1085static int
1022store_ax_keys (struct CadetTunnel *t, 1086store_ax_keys (struct CadetTunnelAxolotl *ax,
1023 const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr, 1087 const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr,
1024 uint32_t Np) 1088 uint32_t Np)
1025{ 1089{
1026 int gap; 1090 int gap;
1027 1091
1028 gap = Np - t->ax.Nr; 1092 gap = Np - ax->Nr;
1029 LOG (GNUNET_ERROR_TYPE_DEBUG, 1093 LOG (GNUNET_ERROR_TYPE_DEBUG,
1030 "Storing skipped keys [%u, %u)\n", 1094 "Storing skipped keys [%u, %u)\n",
1031 t->ax.Nr, 1095 ax->Nr,
1032 Np); 1096 Np);
1033 if (MAX_KEY_GAP < gap) 1097 if (MAX_KEY_GAP < gap)
1034 { 1098 {
1035 /* Avoid DoS (forcing peer to do 2^33 chain HMAC operations) */ 1099 /* Avoid DoS (forcing peer to do more than #MAX_KEY_GAP HMAC operations) */
1036 /* TODO: start new key exchange on return */ 1100 /* TODO: start new key exchange on return */
1037 GNUNET_break_op (0); 1101 GNUNET_break_op (0);
1038 LOG (GNUNET_ERROR_TYPE_WARNING, 1102 LOG (GNUNET_ERROR_TYPE_WARNING,
1039 "Got message %u, expected %u+\n", 1103 "Got message %u, expected %u+\n",
1040 Np, 1104 Np,
1041 t->ax.Nr); 1105 ax->Nr);
1042 return GNUNET_SYSERR; 1106 return GNUNET_SYSERR;
1043 } 1107 }
1044 if (0 > gap) 1108 if (0 > gap)
@@ -1047,13 +1111,13 @@ store_ax_keys (struct CadetTunnel *t,
1047 return GNUNET_SYSERR; 1111 return GNUNET_SYSERR;
1048 } 1112 }
1049 1113
1050 while (t->ax.Nr < Np) 1114 while (ax->Nr < Np)
1051 store_skipped_key (t, 1115 store_skipped_key (ax,
1052 HKr); 1116 HKr);
1053 1117
1054 while (t->ax.skipped > MAX_SKIPPED_KEYS) 1118 while (ax->skipped > MAX_SKIPPED_KEYS)
1055 delete_skipped_key (t, 1119 delete_skipped_key (ax,
1056 t->ax.skipped_tail); 1120 ax->skipped_tail);
1057 return GNUNET_OK; 1121 return GNUNET_OK;
1058} 1122}
1059 1123
@@ -1062,19 +1126,18 @@ store_ax_keys (struct CadetTunnel *t,
1062 * Decrypt and verify data with the appropriate tunnel key and verify that the 1126 * Decrypt and verify data with the appropriate tunnel key and verify that the
1063 * data has not been altered since it was sent by the remote peer. 1127 * data has not been altered since it was sent by the remote peer.
1064 * 1128 *
1065 * @param t Tunnel whose key to use. 1129 * @param ax key material to use
1066 * @param dst Destination for the plaintext. 1130 * @param dst Destination for the plaintext.
1067 * @param src Source of the message. Can overlap with @c dst. 1131 * @param src Source of the message. Can overlap with @c dst.
1068 * @param size Size of the message. 1132 * @param size Size of the message.
1069 * @return Size of the decrypted data, -1 if an error was encountered. 1133 * @return Size of the decrypted data, -1 if an error was encountered.
1070 */ 1134 */
1071static ssize_t 1135static ssize_t
1072t_ax_decrypt_and_validate (struct CadetTunnel *t, 1136t_ax_decrypt_and_validate (struct CadetTunnelAxolotl *ax,
1073 void *dst, 1137 void *dst,
1074 const struct GNUNET_CADET_TunnelEncryptedMessage *src, 1138 const struct GNUNET_CADET_TunnelEncryptedMessage *src,
1075 size_t size) 1139 size_t size)
1076{ 1140{
1077 struct CadetTunnelAxolotl *ax;
1078 struct GNUNET_ShortHashCode msg_hmac; 1141 struct GNUNET_ShortHashCode msg_hmac;
1079 struct GNUNET_HashCode hmac; 1142 struct GNUNET_HashCode hmac;
1080 struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header; 1143 struct GNUNET_CADET_TunnelEncryptedMessage plaintext_header;
@@ -1083,11 +1146,10 @@ t_ax_decrypt_and_validate (struct CadetTunnel *t,
1083 size_t esize; /* Size of encryped payload */ 1146 size_t esize; /* Size of encryped payload */
1084 1147
1085 esize = size - sizeof (struct GNUNET_CADET_TunnelEncryptedMessage); 1148 esize = size - sizeof (struct GNUNET_CADET_TunnelEncryptedMessage);
1086 ax = &t->ax;
1087 1149
1088 /* Try current HK */ 1150 /* Try current HK */
1089 t_hmac (&src->Ns, 1151 t_hmac (&src->ax_header,
1090 AX_HEADER_SIZE + esize, 1152 sizeof (struct GNUNET_CADET_AxHeader) + esize,
1091 0, &ax->HKr, 1153 0, &ax->HKr,
1092 &msg_hmac); 1154 &msg_hmac);
1093 if (0 != memcmp (&msg_hmac, 1155 if (0 != memcmp (&msg_hmac,
@@ -1101,8 +1163,8 @@ t_ax_decrypt_and_validate (struct CadetTunnel *t,
1101 struct GNUNET_CRYPTO_EcdhePublicKey *DHRp; 1163 struct GNUNET_CRYPTO_EcdhePublicKey *DHRp;
1102 1164
1103 /* Try Next HK */ 1165 /* Try Next HK */
1104 t_hmac (&src->Ns, 1166 t_hmac (&src->ax_header,
1105 AX_HEADER_SIZE + esize, 1167 sizeof (struct GNUNET_CADET_AxHeader) + esize,
1106 0, 1168 0,
1107 &ax->NHKr, 1169 &ax->NHKr,
1108 &msg_hmac); 1170 &msg_hmac);
@@ -1111,25 +1173,25 @@ t_ax_decrypt_and_validate (struct CadetTunnel *t,
1111 sizeof (msg_hmac))) 1173 sizeof (msg_hmac)))
1112 { 1174 {
1113 /* Try the skipped keys, if that fails, we're out of luck. */ 1175 /* Try the skipped keys, if that fails, we're out of luck. */
1114 return try_old_ax_keys (t, 1176 return try_old_ax_keys (ax,
1115 dst, 1177 dst,
1116 src, 1178 src,
1117 size); 1179 size);
1118 } 1180 }
1119 HK = ax->HKr; 1181 HK = ax->HKr;
1120 ax->HKr = ax->NHKr; 1182 ax->HKr = ax->NHKr;
1121 t_h_decrypt (t, 1183 t_h_decrypt (ax,
1122 src, 1184 src,
1123 &plaintext_header); 1185 &plaintext_header);
1124 Np = ntohl (plaintext_header.Ns); 1186 Np = ntohl (plaintext_header.ax_header.Ns);
1125 PNp = ntohl (plaintext_header.PNs); 1187 PNp = ntohl (plaintext_header.ax_header.PNs);
1126 DHRp = &plaintext_header.DHRs; 1188 DHRp = &plaintext_header.ax_header.DHRs;
1127 store_ax_keys (t, 1189 store_ax_keys (ax,
1128 &HK, 1190 &HK,
1129 PNp); 1191 PNp);
1130 1192
1131 /* RKp, NHKp, CKp = KDF (HMAC-HASH (RK, DH (DHRp, DHRs))) */ 1193 /* RKp, NHKp, CKp = KDF (HMAC-HASH (RK, DH (DHRp, DHRs))) */
1132 GNUNET_CRYPTO_ecc_ecdh (ax->DHRs, 1194 GNUNET_CRYPTO_ecc_ecdh (&ax->DHRs,
1133 DHRp, 1195 DHRp,
1134 &dh); 1196 &dh);
1135 t_ax_hmac_hash (&ax->RK, 1197 t_ax_hmac_hash (&ax->RK,
@@ -1150,25 +1212,25 @@ t_ax_decrypt_and_validate (struct CadetTunnel *t,
1150 } 1212 }
1151 else 1213 else
1152 { 1214 {
1153 t_h_decrypt (t, 1215 t_h_decrypt (ax,
1154 src, 1216 src,
1155 &plaintext_header); 1217 &plaintext_header);
1156 Np = ntohl (plaintext_header.Ns); 1218 Np = ntohl (plaintext_header.ax_header.Ns);
1157 PNp = ntohl (plaintext_header.PNs); 1219 PNp = ntohl (plaintext_header.ax_header.PNs);
1158 } 1220 }
1159 if ( (Np != ax->Nr) && 1221 if ( (Np != ax->Nr) &&
1160 (GNUNET_OK != store_ax_keys (t, 1222 (GNUNET_OK != store_ax_keys (ax,
1161 &ax->HKr, 1223 &ax->HKr,
1162 Np)) ) 1224 Np)) )
1163 { 1225 {
1164 /* Try the skipped keys, if that fails, we're out of luck. */ 1226 /* Try the skipped keys, if that fails, we're out of luck. */
1165 return try_old_ax_keys (t, 1227 return try_old_ax_keys (ax,
1166 dst, 1228 dst,
1167 src, 1229 src,
1168 size); 1230 size);
1169 } 1231 }
1170 1232
1171 t_ax_decrypt (t, 1233 t_ax_decrypt (ax,
1172 dst, 1234 dst,
1173 &src[1], 1235 &src[1],
1174 esize); 1236 esize);
@@ -1213,10 +1275,10 @@ GCT_change_estate (struct CadetTunnel *t,
1213 1275
1214 t->estate = state; 1276 t->estate = state;
1215 LOG (GNUNET_ERROR_TYPE_DEBUG, 1277 LOG (GNUNET_ERROR_TYPE_DEBUG,
1216 "Tunnel %s estate changed from %d to %d\n", 1278 "%s estate changed from %s to %s\n",
1217 GCT_2s (t), 1279 GCT_2s (t),
1218 old, 1280 estate2s (old),
1219 state); 1281 estate2s (state));
1220 1282
1221 if ( (CADET_TUNNEL_KEY_OK != old) && 1283 if ( (CADET_TUNNEL_KEY_OK != old) &&
1222 (CADET_TUNNEL_KEY_OK == t->estate) ) 1284 (CADET_TUNNEL_KEY_OK == t->estate) )
@@ -1226,15 +1288,14 @@ GCT_change_estate (struct CadetTunnel *t,
1226 GNUNET_SCHEDULER_cancel (t->kx_task); 1288 GNUNET_SCHEDULER_cancel (t->kx_task);
1227 t->kx_task = NULL; 1289 t->kx_task = NULL;
1228 } 1290 }
1229 if (CADET_TUNNEL_KEY_REKEY != old) 1291 /* notify all channels that have been waiting */
1230 { 1292 GNUNET_CONTAINER_multihashmap32_iterate (t->channels,
1231 /* notify all channels that have been waiting */ 1293 &notify_tunnel_up_cb,
1232 GNUNET_CONTAINER_multihashmap32_iterate (t->channels, 1294 t);
1233 &notify_tunnel_up_cb, 1295 if (NULL != t->send_task)
1234 t); 1296 GNUNET_SCHEDULER_cancel (t->send_task);
1235 } 1297 t->send_task = GNUNET_SCHEDULER_add_now (&trigger_transmissions,
1236 1298 t);
1237 /* FIXME: schedule rekey task! */
1238 } 1299 }
1239} 1300}
1240 1301
@@ -1242,80 +1303,179 @@ GCT_change_estate (struct CadetTunnel *t,
1242/** 1303/**
1243 * Send a KX message. 1304 * Send a KX message.
1244 * 1305 *
1245 * FIXME: does not take care of sender-authentication yet! 1306 * @param t tunnel on which to send the KX_AUTH
1246 * 1307 * @param ct Tunnel and connection on which to send the KX_AUTH, NULL if
1247 * @param t Tunnel on which to send it. 1308 * we are to find one that is ready.
1248 * @param force_reply Force the other peer to reply with a KX message. 1309 * @param ax axolotl key context to use
1249 */ 1310 */
1250static void 1311static void
1251send_kx (struct CadetTunnel *t, 1312send_kx (struct CadetTunnel *t,
1252 int force_reply) 1313 struct CadetTConnection *ct,
1314 struct CadetTunnelAxolotl *ax)
1253{ 1315{
1254 struct CadetTunnelAxolotl *ax = &t->ax;
1255 struct CadetTConnection *ct;
1256 struct CadetConnection *cc; 1316 struct CadetConnection *cc;
1257 struct GNUNET_MQ_Envelope *env; 1317 struct GNUNET_MQ_Envelope *env;
1258 struct GNUNET_CADET_TunnelKeyExchangeMessage *msg; 1318 struct GNUNET_CADET_TunnelKeyExchangeMessage *msg;
1259 enum GNUNET_CADET_KX_Flags flags; 1319 enum GNUNET_CADET_KX_Flags flags;
1260 1320
1261 ct = get_ready_connection (t); 1321 if ( (NULL == ct) ||
1322 (GNUNET_NO == ct->is_ready) )
1323 ct = get_ready_connection (t);
1262 if (NULL == ct) 1324 if (NULL == ct)
1263 { 1325 {
1264 LOG (GNUNET_ERROR_TYPE_DEBUG, 1326 LOG (GNUNET_ERROR_TYPE_DEBUG,
1265 "Wanted to send KX on tunnel %s, but no connection is ready, deferring\n", 1327 "Wanted to send %s in state %s, but no connection is ready, deferring\n",
1266 GCT_2s (t)); 1328 GCT_2s (t),
1329 estate2s (t->estate));
1330 t->next_kx_attempt = GNUNET_TIME_absolute_get ();
1267 return; 1331 return;
1268 } 1332 }
1269 cc = ct->cc; 1333 cc = ct->cc;
1270 LOG (GNUNET_ERROR_TYPE_DEBUG, 1334 LOG (GNUNET_ERROR_TYPE_DEBUG,
1271 "Sending KX on tunnel %s using connection %s\n", 1335 "Sending KX on %s via %s in state %s\n",
1272 GCT_2s (t), 1336 GCT_2s (t),
1273 GCC_2s (ct->cc)); 1337 GCC_2s (cc),
1274 1338 estate2s (t->estate));
1275 // GNUNET_assert (GNUNET_NO == GCT_is_loopback (t));
1276 env = GNUNET_MQ_msg (msg, 1339 env = GNUNET_MQ_msg (msg,
1277 GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX); 1340 GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX);
1278 flags = GNUNET_CADET_KX_FLAG_NONE; 1341 flags = GNUNET_CADET_KX_FLAG_FORCE_REPLY; /* always for KX */
1279 if (GNUNET_YES == force_reply)
1280 flags |= GNUNET_CADET_KX_FLAG_FORCE_REPLY;
1281 msg->flags = htonl (flags); 1342 msg->flags = htonl (flags);
1282 msg->cid = *GCC_get_id (cc); 1343 msg->cid = *GCC_get_id (cc);
1283 GNUNET_CRYPTO_ecdhe_key_get_public (ax->kx_0, 1344 GNUNET_CRYPTO_ecdhe_key_get_public (&ax->kx_0,
1284 &msg->ephemeral_key); 1345 &msg->ephemeral_key);
1285 GNUNET_CRYPTO_ecdhe_key_get_public (ax->DHRs, 1346 GNUNET_CRYPTO_ecdhe_key_get_public (&ax->DHRs,
1286 &msg->ratchet_key); 1347 &msg->ratchet_key);
1287 ct->is_ready = GNUNET_NO; 1348 mark_connection_unready (ct);
1288 GCC_transmit (cc,
1289 env);
1290 t->kx_retry_delay = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay); 1349 t->kx_retry_delay = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay);
1291 t->next_kx_attempt = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay); 1350 t->next_kx_attempt = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay);
1292 if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) 1351 if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate)
1293 GCT_change_estate (t, 1352 GCT_change_estate (t,
1294 CADET_TUNNEL_KEY_SENT); 1353 CADET_TUNNEL_KEY_AX_SENT);
1354 else if (CADET_TUNNEL_KEY_AX_RECV == t->estate)
1355 GCT_change_estate (t,
1356 CADET_TUNNEL_KEY_AX_SENT_AND_RECV);
1357 GCC_transmit (cc,
1358 env);
1359}
1360
1361
1362/**
1363 * Send a KX_AUTH message.
1364 *
1365 * @param t tunnel on which to send the KX_AUTH
1366 * @param ct Tunnel and connection on which to send the KX_AUTH, NULL if
1367 * we are to find one that is ready.
1368 * @param ax axolotl key context to use
1369 * @param force_reply Force the other peer to reply with a KX_AUTH message
1370 * (set if we would like to transmit right now, but cannot)
1371 */
1372static void
1373send_kx_auth (struct CadetTunnel *t,
1374 struct CadetTConnection *ct,
1375 struct CadetTunnelAxolotl *ax,
1376 int force_reply)
1377{
1378 struct CadetConnection *cc;
1379 struct GNUNET_MQ_Envelope *env;
1380 struct GNUNET_CADET_TunnelKeyExchangeAuthMessage *msg;
1381 enum GNUNET_CADET_KX_Flags flags;
1382
1383 if ( (NULL == ct) ||
1384 (GNUNET_NO == ct->is_ready) )
1385 ct = get_ready_connection (t);
1386 if (NULL == ct)
1387 {
1388 LOG (GNUNET_ERROR_TYPE_DEBUG,
1389 "Wanted to send KX_AUTH on %s, but no connection is ready, deferring\n",
1390 GCT_2s (t));
1391 t->next_kx_attempt = GNUNET_TIME_absolute_get ();
1392 t->kx_auth_requested = GNUNET_YES; /* queue KX_AUTH independent of estate */
1393 return;
1394 }
1395 t->kx_auth_requested = GNUNET_NO; /* clear flag */
1396 cc = ct->cc;
1397 LOG (GNUNET_ERROR_TYPE_DEBUG,
1398 "Sending KX_AUTH on %s using %s\n",
1399 GCT_2s (t),
1400 GCC_2s (ct->cc));
1401
1402 env = GNUNET_MQ_msg (msg,
1403 GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX_AUTH);
1404 flags = GNUNET_CADET_KX_FLAG_NONE;
1405 if (GNUNET_YES == force_reply)
1406 flags |= GNUNET_CADET_KX_FLAG_FORCE_REPLY;
1407 msg->kx.flags = htonl (flags);
1408 msg->kx.cid = *GCC_get_id (cc);
1409 GNUNET_CRYPTO_ecdhe_key_get_public (&ax->kx_0,
1410 &msg->kx.ephemeral_key);
1411 GNUNET_CRYPTO_ecdhe_key_get_public (&ax->DHRs,
1412 &msg->kx.ratchet_key);
1413 /* Compute authenticator (this is the main difference to #send_kx()) */
1414 GNUNET_CRYPTO_hash (&ax->RK,
1415 sizeof (ax->RK),
1416 &msg->auth);
1417
1418 /* Compute when to be triggered again; actual job will
1419 be scheduled via #connection_ready_cb() */
1420 t->kx_retry_delay
1421 = GNUNET_TIME_STD_BACKOFF (t->kx_retry_delay);
1422 t->next_kx_attempt
1423 = GNUNET_TIME_relative_to_absolute (t->kx_retry_delay);
1424
1425 /* Send via cc, mark it as unready */
1426 mark_connection_unready (ct);
1427
1428 /* Update state machine, unless we are already OK */
1429 if (CADET_TUNNEL_KEY_OK != t->estate)
1430 GCT_change_estate (t,
1431 CADET_TUNNEL_KEY_AX_AUTH_SENT);
1432
1433 GCC_transmit (cc,
1434 env);
1295} 1435}
1296 1436
1297 1437
1298/** 1438/**
1299 * Handle KX message. 1439 * Cleanup state used by @a ax.
1300 * 1440 *
1301 * FIXME: sender-authentication in KX is missing! 1441 * @param ax state to free, but not memory of @a ax itself
1442 */
1443static void
1444cleanup_ax (struct CadetTunnelAxolotl *ax)
1445{
1446 while (NULL != ax->skipped_head)
1447 delete_skipped_key (ax,
1448 ax->skipped_head);
1449 GNUNET_assert (0 == ax->skipped);
1450 GNUNET_CRYPTO_ecdhe_key_clear (&ax->kx_0);
1451 GNUNET_CRYPTO_ecdhe_key_clear (&ax->DHRs);
1452}
1453
1454
1455/**
1456 * Update our Axolotl key state based on the KX data we received.
1457 * Computes the new chain keys, and root keys, etc, and also checks
1458 * wether this is a replay of the current chain.
1302 * 1459 *
1303 * @param ct connection/tunnel combo that received encrypted message 1460 * @param[in|out] axolotl chain key state to recompute
1304 * @param msg the key exchange message 1461 * @param pid peer identity of the other peer
1462 * @param ephemeral_key ephemeral public key of the other peer
1463 * @param ratchet_key senders next ephemeral public key
1464 * @return #GNUNET_OK on success, #GNUNET_NO if the resulting
1465 * root key is already in @a ax and thus the KX is useless;
1466 * #GNUNET_SYSERR on hard errors (i.e. @a pid is #my_full_id)
1305 */ 1467 */
1306void 1468static int
1307GCT_handle_kx (struct CadetTConnection *ct, 1469update_ax_by_kx (struct CadetTunnelAxolotl *ax,
1308 const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg) 1470 const struct GNUNET_PeerIdentity *pid,
1471 const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral_key,
1472 const struct GNUNET_CRYPTO_EcdhePublicKey *ratchet_key)
1309{ 1473{
1310 struct CadetTunnel *t = ct->t;
1311 struct CadetTunnelAxolotl *ax = &t->ax;
1312 struct GNUNET_HashCode key_material[3]; 1474 struct GNUNET_HashCode key_material[3];
1313 struct GNUNET_CRYPTO_SymmetricSessionKey keys[5]; 1475 struct GNUNET_CRYPTO_SymmetricSessionKey keys[5];
1314 const char salt[] = "CADET Axolotl salt"; 1476 const char salt[] = "CADET Axolotl salt";
1315 const struct GNUNET_PeerIdentity *pid;
1316 int am_I_alice; 1477 int am_I_alice;
1317 1478
1318 pid = GCP_get_id (t->destination);
1319 if (0 > GNUNET_CRYPTO_cmp_peer_identity (&my_full_id, 1479 if (0 > GNUNET_CRYPTO_cmp_peer_identity (&my_full_id,
1320 pid)) 1480 pid))
1321 am_I_alice = GNUNET_YES; 1481 am_I_alice = GNUNET_YES;
@@ -1325,41 +1485,30 @@ GCT_handle_kx (struct CadetTConnection *ct,
1325 else 1485 else
1326 { 1486 {
1327 GNUNET_break_op (0); 1487 GNUNET_break_op (0);
1328 return; 1488 return GNUNET_SYSERR;
1329 }
1330
1331 if (0 != (GNUNET_CADET_KX_FLAG_FORCE_REPLY & ntohl (msg->flags)))
1332 {
1333 if (NULL != t->kx_task)
1334 {
1335 GNUNET_SCHEDULER_cancel (t->kx_task);
1336 t->kx_task = NULL;
1337 }
1338 send_kx (t,
1339 GNUNET_NO);
1340 } 1489 }
1341 1490
1342 if (0 == memcmp (&ax->DHRr, 1491 if (0 == memcmp (&ax->DHRr,
1343 &msg->ratchet_key, 1492 ratchet_key,
1344 sizeof (msg->ratchet_key))) 1493 sizeof (*ratchet_key)))
1345 { 1494 {
1346 LOG (GNUNET_ERROR_TYPE_DEBUG, 1495 LOG (GNUNET_ERROR_TYPE_DEBUG,
1347 " known ratchet key, exit\n"); 1496 "Ratchet key already known. Ignoring KX.\n");
1348 return; 1497 return GNUNET_NO;
1349 } 1498 }
1350 1499
1351 ax->DHRr = msg->ratchet_key; 1500 ax->DHRr = *ratchet_key;
1352 1501
1353 /* ECDH A B0 */ 1502 /* ECDH A B0 */
1354 if (GNUNET_YES == am_I_alice) 1503 if (GNUNET_YES == am_I_alice)
1355 { 1504 {
1356 GNUNET_CRYPTO_eddsa_ecdh (my_private_key, /* A */ 1505 GNUNET_CRYPTO_eddsa_ecdh (my_private_key, /* A */
1357 &msg->ephemeral_key, /* B0 */ 1506 ephemeral_key, /* B0 */
1358 &key_material[0]); 1507 &key_material[0]);
1359 } 1508 }
1360 else 1509 else
1361 { 1510 {
1362 GNUNET_CRYPTO_ecdh_eddsa (ax->kx_0, /* B0 */ 1511 GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* B0 */
1363 &pid->public_key, /* A */ 1512 &pid->public_key, /* A */
1364 &key_material[0]); 1513 &key_material[0]);
1365 } 1514 }
@@ -1367,14 +1516,14 @@ GCT_handle_kx (struct CadetTConnection *ct,
1367 /* ECDH A0 B */ 1516 /* ECDH A0 B */
1368 if (GNUNET_YES == am_I_alice) 1517 if (GNUNET_YES == am_I_alice)
1369 { 1518 {
1370 GNUNET_CRYPTO_ecdh_eddsa (ax->kx_0, /* A0 */ 1519 GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* A0 */
1371 &pid->public_key, /* B */ 1520 &pid->public_key, /* B */
1372 &key_material[1]); 1521 &key_material[1]);
1373 } 1522 }
1374 else 1523 else
1375 { 1524 {
1376 GNUNET_CRYPTO_eddsa_ecdh (my_private_key, /* A */ 1525 GNUNET_CRYPTO_eddsa_ecdh (my_private_key, /* A */
1377 &msg->ephemeral_key, /* B0 */ 1526 ephemeral_key, /* B0 */
1378 &key_material[1]); 1527 &key_material[1]);
1379 1528
1380 1529
@@ -1383,8 +1532,8 @@ GCT_handle_kx (struct CadetTConnection *ct,
1383 /* ECDH A0 B0 */ 1532 /* ECDH A0 B0 */
1384 /* (This is the triple-DH, we could probably safely skip this, 1533 /* (This is the triple-DH, we could probably safely skip this,
1385 as A0/B0 are already in the key material.) */ 1534 as A0/B0 are already in the key material.) */
1386 GNUNET_CRYPTO_ecc_ecdh (ax->kx_0, /* A0 or B0 */ 1535 GNUNET_CRYPTO_ecc_ecdh (&ax->kx_0, /* A0 or B0 */
1387 &msg->ephemeral_key, /* B0 or A0 */ 1536 ephemeral_key, /* B0 or A0 */
1388 &key_material[2]); 1537 &key_material[2]);
1389 1538
1390 /* KDF */ 1539 /* KDF */
@@ -1397,13 +1546,10 @@ GCT_handle_kx (struct CadetTConnection *ct,
1397 &keys[0], 1546 &keys[0],
1398 sizeof (ax->RK))) 1547 sizeof (ax->RK)))
1399 { 1548 {
1400 LOG (GNUNET_ERROR_TYPE_INFO, 1549 LOG (GNUNET_ERROR_TYPE_DEBUG,
1401 " known handshake key, exit\n"); 1550 "Root key of handshake already known. Ignoring KX.\n");
1402 return; 1551 return GNUNET_NO;
1403 } 1552 }
1404 LOG (GNUNET_ERROR_TYPE_DEBUG,
1405 "Handling KX message for tunnel %s\n",
1406 GCT_2s (t));
1407 1553
1408 ax->RK = keys[0]; 1554 ax->RK = keys[0];
1409 if (GNUNET_YES == am_I_alice) 1555 if (GNUNET_YES == am_I_alice)
@@ -1421,45 +1567,305 @@ GCT_handle_kx (struct CadetTConnection *ct,
1421 ax->NHKs = keys[3]; 1567 ax->NHKs = keys[3];
1422 ax->CKs = keys[4]; 1568 ax->CKs = keys[4];
1423 ax->ratchet_flag = GNUNET_NO; 1569 ax->ratchet_flag = GNUNET_NO;
1424 ax->ratchet_allowed = GNUNET_NO;
1425 ax->ratchet_counter = 0;
1426 ax->ratchet_expiration 1570 ax->ratchet_expiration
1427 = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(), 1571 = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(),
1428 ratchet_time); 1572 ratchet_time);
1429 } 1573 }
1430 ax->PNs = 0; 1574 return GNUNET_OK;
1431 ax->Nr = 0; 1575}
1432 ax->Ns = 0;
1433 1576
1577
1578/**
1579 * Try to redo the KX or KX_AUTH handshake, if we can.
1580 *
1581 * @param cls the `struct CadetTunnel` to do KX for.
1582 */
1583static void
1584retry_kx (void *cls)
1585{
1586 struct CadetTunnel *t = cls;
1587 struct CadetTunnelAxolotl *ax;
1588
1589 t->kx_task = NULL;
1590 LOG (GNUNET_ERROR_TYPE_DEBUG,
1591 "Trying to make KX progress on %s in state %s\n",
1592 GCT_2s (t),
1593 estate2s (t->estate));
1434 switch (t->estate) 1594 switch (t->estate)
1435 { 1595 {
1436 case CADET_TUNNEL_KEY_UNINITIALIZED: 1596 case CADET_TUNNEL_KEY_UNINITIALIZED: /* first attempt */
1597 case CADET_TUNNEL_KEY_AX_SENT: /* trying again */
1598 send_kx (t,
1599 NULL,
1600 &t->ax);
1601 break;
1602 case CADET_TUNNEL_KEY_AX_RECV:
1603 case CADET_TUNNEL_KEY_AX_SENT_AND_RECV:
1604 /* We are responding, so only require reply
1605 if WE have a channel waiting. */
1606 if (NULL != t->unverified_ax)
1607 {
1608 /* Send AX_AUTH so we might get this one verified */
1609 ax = t->unverified_ax;
1610 }
1611 else
1612 {
1613 /* How can this be? */
1614 GNUNET_break (0);
1615 ax = &t->ax;
1616 }
1617 send_kx_auth (t,
1618 NULL,
1619 ax,
1620 (0 == GCT_count_channels (t))
1621 ? GNUNET_NO
1622 : GNUNET_YES);
1623 break;
1624 case CADET_TUNNEL_KEY_AX_AUTH_SENT:
1625 /* We are responding, so only require reply
1626 if WE have a channel waiting. */
1627 if (NULL != t->unverified_ax)
1628 {
1629 /* Send AX_AUTH so we might get this one verified */
1630 ax = t->unverified_ax;
1631 }
1632 else
1633 {
1634 /* How can this be? */
1635 GNUNET_break (0);
1636 ax = &t->ax;
1637 }
1638 send_kx_auth (t,
1639 NULL,
1640 ax,
1641 (0 == GCT_count_channels (t))
1642 ? GNUNET_NO
1643 : GNUNET_YES);
1644 break;
1645 case CADET_TUNNEL_KEY_OK:
1646 /* Must have been the *other* peer asking us to
1647 respond with a KX_AUTH. */
1648 if (NULL != t->unverified_ax)
1649 {
1650 /* Sending AX_AUTH in response to AX so we might get this one verified */
1651 ax = t->unverified_ax;
1652 }
1653 else
1654 {
1655 /* Sending AX_AUTH in response to AX_AUTH */
1656 ax = &t->ax;
1657 }
1658 send_kx_auth (t,
1659 NULL,
1660 ax,
1661 GNUNET_NO);
1662 break;
1663 }
1664}
1665
1666
1667/**
1668 * Handle KX message that lacks authentication (and which will thus
1669 * only be considered authenticated after we respond with our own
1670 * KX_AUTH and finally successfully decrypt payload).
1671 *
1672 * @param ct connection/tunnel combo that received encrypted message
1673 * @param msg the key exchange message
1674 */
1675void
1676GCT_handle_kx (struct CadetTConnection *ct,
1677 const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg)
1678{
1679 struct CadetTunnel *t = ct->t;
1680 struct CadetTunnelAxolotl *ax;
1681 int ret;
1682
1683 if (0 ==
1684 memcmp (&t->ax.DHRr,
1685 &msg->ratchet_key,
1686 sizeof (msg->ratchet_key)))
1687 {
1688 LOG (GNUNET_ERROR_TYPE_DEBUG,
1689 "Got duplicate KX. Firing back KX_AUTH.\n");
1690 send_kx_auth (t,
1691 ct,
1692 &t->ax,
1693 GNUNET_NO);
1694 return;
1695 }
1696
1697 /* We only keep ONE unverified KX around, so if there is an existing one,
1698 clean it up. */
1699 if (NULL != t->unverified_ax)
1700 {
1701 if (0 ==
1702 memcmp (&t->unverified_ax->DHRr,
1703 &msg->ratchet_key,
1704 sizeof (msg->ratchet_key)))
1705 {
1706 LOG (GNUNET_ERROR_TYPE_DEBUG,
1707 "Got duplicate unverified KX on %s. Fire back KX_AUTH again.\n",
1708 GCT_2s (t));
1709 send_kx_auth (t,
1710 ct,
1711 t->unverified_ax,
1712 GNUNET_NO);
1713 return;
1714 }
1715 LOG (GNUNET_ERROR_TYPE_DEBUG,
1716 "Dropping old unverified KX state. Got a fresh KX for %s.\n",
1717 GCT_2s (t));
1718 memset (t->unverified_ax,
1719 0,
1720 sizeof (struct CadetTunnelAxolotl));
1721 t->unverified_ax->DHRs = t->ax.DHRs;
1722 t->unverified_ax->kx_0 = t->ax.kx_0;
1723 }
1724 else
1725 {
1726 LOG (GNUNET_ERROR_TYPE_DEBUG,
1727 "Creating fresh unverified KX for %s.\n",
1728 GCT_2s (t));
1729 t->unverified_ax = GNUNET_new (struct CadetTunnelAxolotl);
1730 t->unverified_ax->DHRs = t->ax.DHRs;
1731 t->unverified_ax->kx_0 = t->ax.kx_0;
1732 }
1733 /* Set as the 'current' RK/DHRr the one we are currently using,
1734 so that the duplicate-detection logic of
1735 #update_ax_by_kx can work. */
1736 t->unverified_ax->RK = t->ax.RK;
1737 t->unverified_ax->DHRr = t->ax.DHRr;
1738 t->unverified_attempts = 0;
1739 ax = t->unverified_ax;
1740
1741 /* Update 'ax' by the new key material */
1742 ret = update_ax_by_kx (ax,
1743 GCP_get_id (t->destination),
1744 &msg->ephemeral_key,
1745 &msg->ratchet_key);
1746 GNUNET_break (GNUNET_SYSERR != ret);
1747 if (GNUNET_OK != ret)
1748 return; /* duplicate KX, nothing to do */
1749
1750 /* move ahead in our state machine */
1751 if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate)
1752 GCT_change_estate (t,
1753 CADET_TUNNEL_KEY_AX_RECV);
1754 else if (CADET_TUNNEL_KEY_AX_SENT == t->estate)
1437 GCT_change_estate (t, 1755 GCT_change_estate (t,
1438 CADET_TUNNEL_KEY_PING); 1756 CADET_TUNNEL_KEY_AX_SENT_AND_RECV);
1757
1758 /* KX is still not done, try again our end. */
1759 if (CADET_TUNNEL_KEY_OK != t->estate)
1760 {
1761 if (NULL != t->kx_task)
1762 GNUNET_SCHEDULER_cancel (t->kx_task);
1763 t->kx_task
1764 = GNUNET_SCHEDULER_add_now (&retry_kx,
1765 t);
1766 }
1767}
1768
1769
1770/**
1771 * Handle KX_AUTH message.
1772 *
1773 * @param ct connection/tunnel combo that received encrypted message
1774 * @param msg the key exchange message
1775 */
1776void
1777GCT_handle_kx_auth (struct CadetTConnection *ct,
1778 const struct GNUNET_CADET_TunnelKeyExchangeAuthMessage *msg)
1779{
1780 struct CadetTunnel *t = ct->t;
1781 struct CadetTunnelAxolotl ax_tmp;
1782 struct GNUNET_HashCode kx_auth;
1783 int ret;
1784
1785 if ( (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) ||
1786 (CADET_TUNNEL_KEY_AX_RECV == t->estate) )
1787 {
1788 /* Confusing, we got a KX_AUTH before we even send our own
1789 KX. This should not happen. We'll send our own KX ASAP anyway,
1790 so let's ignore this here. */
1791 GNUNET_break_op (0);
1792 return;
1793 }
1794 LOG (GNUNET_ERROR_TYPE_DEBUG,
1795 "Handling KX_AUTH message for %s\n",
1796 GCT_2s (t));
1797
1798 /* We do everything in ax_tmp until we've checked the authentication
1799 so we don't clobber anything we care about by accident. */
1800 ax_tmp = t->ax;
1801
1802 /* Update 'ax' by the new key material */
1803 ret = update_ax_by_kx (&ax_tmp,
1804 GCP_get_id (t->destination),
1805 &msg->kx.ephemeral_key,
1806 &msg->kx.ratchet_key);
1807 if (GNUNET_OK != ret)
1808 {
1809 if (GNUNET_NO == ret)
1810 GNUNET_STATISTICS_update (stats,
1811 "# redundant KX_AUTH received",
1812 1,
1813 GNUNET_NO);
1814 else
1815 GNUNET_break (0); /* connect to self!? */
1816 return;
1817 }
1818 GNUNET_CRYPTO_hash (&ax_tmp.RK,
1819 sizeof (ax_tmp.RK),
1820 &kx_auth);
1821 if (0 != memcmp (&kx_auth,
1822 &msg->auth,
1823 sizeof (kx_auth)))
1824 {
1825 /* This KX_AUTH is not using the latest KX/KX_AUTH data
1826 we transmitted to the sender, refuse it, try KX again. */
1827 GNUNET_STATISTICS_update (stats,
1828 "# KX_AUTH not using our last KX received (auth failure)",
1829 1,
1830 GNUNET_NO);
1831 send_kx (t,
1832 ct,
1833 &t->ax);
1834 return;
1835 }
1836 /* Yep, we're good. */
1837 t->ax = ax_tmp;
1838 if (NULL != t->unverified_ax)
1839 {
1840 /* We got some "stale" KX before, drop that. */
1841 cleanup_ax (t->unverified_ax);
1842 GNUNET_free (t->unverified_ax);
1843 t->unverified_ax = NULL;
1844 }
1845
1846 /* move ahead in our state machine */
1847 switch (t->estate)
1848 {
1849 case CADET_TUNNEL_KEY_UNINITIALIZED:
1850 case CADET_TUNNEL_KEY_AX_RECV:
1851 /* Checked above, this is impossible. */
1852 GNUNET_assert (0);
1439 break; 1853 break;
1440 case CADET_TUNNEL_KEY_SENT: 1854 case CADET_TUNNEL_KEY_AX_SENT: /* This is the normal case */
1441 /* Got a response to us sending our key; now 1855 case CADET_TUNNEL_KEY_AX_SENT_AND_RECV: /* both peers started KX */
1442 we can start transmitting! */ 1856 case CADET_TUNNEL_KEY_AX_AUTH_SENT: /* both peers now did KX_AUTH */
1443 GCT_change_estate (t, 1857 GCT_change_estate (t,
1444 CADET_TUNNEL_KEY_OK); 1858 CADET_TUNNEL_KEY_OK);
1445 if (NULL != t->send_task)
1446 GNUNET_SCHEDULER_cancel (t->send_task);
1447 t->send_task = GNUNET_SCHEDULER_add_now (&trigger_transmissions,
1448 t);
1449 break;
1450 case CADET_TUNNEL_KEY_PING:
1451 /* Got a key yet again; need encrypted payload to advance */
1452 break; 1859 break;
1453 case CADET_TUNNEL_KEY_OK: 1860 case CADET_TUNNEL_KEY_OK:
1454 /* Did not expect a key, but so what. */ 1861 /* Did not expect another KX_AUTH, but so what, still acceptable.
1455 break; 1862 Nothing to do here. */
1456 case CADET_TUNNEL_KEY_REKEY:
1457 /* Got a key yet again; need encrypted payload to advance */
1458 break; 1863 break;
1459 } 1864 }
1460} 1865}
1461 1866
1462 1867
1868
1463/* ************************************** end core crypto ***************************** */ 1869/* ************************************** end core crypto ***************************** */
1464 1870
1465 1871
@@ -1489,12 +1895,12 @@ get_next_free_ctn (struct CadetTunnel *t)
1489 ctn = ntohl (t->next_ctn.cn); 1895 ctn = ntohl (t->next_ctn.cn);
1490 while (NULL != 1896 while (NULL !=
1491 GNUNET_CONTAINER_multihashmap32_get (t->channels, 1897 GNUNET_CONTAINER_multihashmap32_get (t->channels,
1492 ctn)) 1898 ctn | highbit))
1493 { 1899 {
1494 ctn = ((ctn + 1) & (~ HIGH_BIT)) | highbit; 1900 ctn = ((ctn + 1) & (~ HIGH_BIT));
1495 } 1901 }
1496 t->next_ctn.cn = htonl (((ctn + 1) & (~ HIGH_BIT)) | highbit); 1902 t->next_ctn.cn = htonl ((ctn + 1) & (~ HIGH_BIT));
1497 ret.cn = ntohl (ctn); 1903 ret.cn = htonl (ctn | highbit);
1498 return ret; 1904 return ret;
1499} 1905}
1500 1906
@@ -1515,23 +1921,97 @@ GCT_add_channel (struct CadetTunnel *t,
1515 struct GNUNET_CADET_ChannelTunnelNumber ctn; 1921 struct GNUNET_CADET_ChannelTunnelNumber ctn;
1516 1922
1517 ctn = get_next_free_ctn (t); 1923 ctn = get_next_free_ctn (t);
1924 if (NULL != t->destroy_task)
1925 {
1926 GNUNET_SCHEDULER_cancel (t->destroy_task);
1927 t->destroy_task = NULL;
1928 }
1518 GNUNET_assert (GNUNET_YES == 1929 GNUNET_assert (GNUNET_YES ==
1519 GNUNET_CONTAINER_multihashmap32_put (t->channels, 1930 GNUNET_CONTAINER_multihashmap32_put (t->channels,
1520 ntohl (ctn.cn), 1931 ntohl (ctn.cn),
1521 ch, 1932 ch,
1522 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 1933 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1523 LOG (GNUNET_ERROR_TYPE_DEBUG, 1934 LOG (GNUNET_ERROR_TYPE_DEBUG,
1524 "Adding channel %s to tunnel %s\n", 1935 "Adding %s to %s\n",
1525 GCCH_2s (ch), 1936 GCCH_2s (ch),
1526 GCT_2s (t)); 1937 GCT_2s (t));
1527 if ( (CADET_TUNNEL_KEY_OK == t->estate) || 1938 switch (t->estate)
1528 (CADET_TUNNEL_KEY_REKEY == t->estate) ) 1939 {
1940 case CADET_TUNNEL_KEY_UNINITIALIZED:
1941 /* waiting for connection to start KX */
1942 break;
1943 case CADET_TUNNEL_KEY_AX_RECV:
1944 case CADET_TUNNEL_KEY_AX_SENT:
1945 case CADET_TUNNEL_KEY_AX_SENT_AND_RECV:
1946 /* we're currently waiting for KX to complete */
1947 break;
1948 case CADET_TUNNEL_KEY_AX_AUTH_SENT:
1949 /* waiting for OTHER peer to send us data,
1950 we might need to prompt more aggressively! */
1951 if (NULL == t->kx_task)
1952 t->kx_task
1953 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
1954 &retry_kx,
1955 t);
1956 break;
1957 case CADET_TUNNEL_KEY_OK:
1958 /* We are ready. Tell the new channel that we are up. */
1529 GCCH_tunnel_up (ch); 1959 GCCH_tunnel_up (ch);
1960 break;
1961 }
1530 return ctn; 1962 return ctn;
1531} 1963}
1532 1964
1533 1965
1534/** 1966/**
1967 * We lost a connection, remove it from our list and clean up
1968 * the connection object itself.
1969 *
1970 * @param ct binding of connection to tunnel of the connection that was lost.
1971 */
1972void
1973GCT_connection_lost (struct CadetTConnection *ct)
1974{
1975 struct CadetTunnel *t = ct->t;
1976
1977 if (GNUNET_YES == ct->is_ready)
1978 {
1979 GNUNET_CONTAINER_DLL_remove (t->connection_ready_head,
1980 t->connection_ready_tail,
1981 ct);
1982 t->num_ready_connections--;
1983 }
1984 else
1985 {
1986 GNUNET_CONTAINER_DLL_remove (t->connection_busy_head,
1987 t->connection_busy_tail,
1988 ct);
1989 t->num_busy_connections--;
1990 }
1991 GNUNET_free (ct);
1992}
1993
1994
1995/**
1996 * Clean up connection @a ct of a tunnel.
1997 *
1998 * @param cls the `struct CadetTunnel`
1999 * @param ct connection to clean up
2000 */
2001static void
2002destroy_t_connection (void *cls,
2003 struct CadetTConnection *ct)
2004{
2005 struct CadetTunnel *t = cls;
2006 struct CadetConnection *cc = ct->cc;
2007
2008 GNUNET_assert (ct->t == t);
2009 GCT_connection_lost (ct);
2010 GCC_destroy_without_tunnel (cc);
2011}
2012
2013
2014/**
1535 * This tunnel is no longer used, destroy it. 2015 * This tunnel is no longer used, destroy it.
1536 * 2016 *
1537 * @param cls the idle tunnel 2017 * @param cls the idle tunnel
@@ -1540,27 +2020,23 @@ static void
1540destroy_tunnel (void *cls) 2020destroy_tunnel (void *cls)
1541{ 2021{
1542 struct CadetTunnel *t = cls; 2022 struct CadetTunnel *t = cls;
1543 struct CadetTConnection *ct;
1544 struct CadetTunnelQueueEntry *tq; 2023 struct CadetTunnelQueueEntry *tq;
1545 2024
1546 t->destroy_task = NULL; 2025 t->destroy_task = NULL;
1547 LOG (GNUNET_ERROR_TYPE_DEBUG, 2026 LOG (GNUNET_ERROR_TYPE_DEBUG,
1548 "Destroying idle tunnel %s\n", 2027 "Destroying idle %s\n",
1549 GCT_2s (t)); 2028 GCT_2s (t));
1550 GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap32_size (t->channels)); 2029 GNUNET_assert (0 == GCT_count_channels (t));
1551 while (NULL != (ct = t->connection_head)) 2030 GCT_iterate_connections (t,
1552 { 2031 &destroy_t_connection,
1553 GNUNET_assert (ct->t == t); 2032 t);
1554 GNUNET_CONTAINER_DLL_remove (t->connection_head, 2033 GNUNET_assert (NULL == t->connection_ready_head);
1555 t->connection_tail, 2034 GNUNET_assert (NULL == t->connection_busy_head);
1556 ct);
1557 GCC_destroy (ct->cc);
1558 GNUNET_free (ct);
1559 }
1560 while (NULL != (tq = t->tq_head)) 2035 while (NULL != (tq = t->tq_head))
1561 { 2036 {
1562 if (NULL != tq->cont) 2037 if (NULL != tq->cont)
1563 tq->cont (tq->cont_cls); 2038 tq->cont (tq->cont_cls,
2039 NULL);
1564 GCT_send_cancel (tq); 2040 GCT_send_cancel (tq);
1565 } 2041 }
1566 GCP_drop_tunnel (t->destination, 2042 GCP_drop_tunnel (t->destination,
@@ -1583,12 +2059,13 @@ destroy_tunnel (void *cls)
1583 } 2059 }
1584 GNUNET_MST_destroy (t->mst); 2060 GNUNET_MST_destroy (t->mst);
1585 GNUNET_MQ_destroy (t->mq); 2061 GNUNET_MQ_destroy (t->mq);
1586 while (NULL != t->ax.skipped_head) 2062 if (NULL != t->unverified_ax)
1587 delete_skipped_key (t, 2063 {
1588 t->ax.skipped_head); 2064 cleanup_ax (t->unverified_ax);
1589 GNUNET_assert (0 == t->ax.skipped); 2065 GNUNET_free (t->unverified_ax);
1590 GNUNET_free_non_null (t->ax.kx_0); 2066 }
1591 GNUNET_free_non_null (t->ax.DHRs); 2067 cleanup_ax (&t->ax);
2068 GNUNET_assert (NULL == t->destroy_task);
1592 GNUNET_free (t); 2069 GNUNET_free (t);
1593} 2070}
1594 2071
@@ -1606,19 +2083,21 @@ GCT_remove_channel (struct CadetTunnel *t,
1606 struct GNUNET_CADET_ChannelTunnelNumber ctn) 2083 struct GNUNET_CADET_ChannelTunnelNumber ctn)
1607{ 2084{
1608 LOG (GNUNET_ERROR_TYPE_DEBUG, 2085 LOG (GNUNET_ERROR_TYPE_DEBUG,
1609 "Removing channel %s from tunnel %s\n", 2086 "Removing %s from %s\n",
1610 GCCH_2s (ch), 2087 GCCH_2s (ch),
1611 GCT_2s (t)); 2088 GCT_2s (t));
1612 GNUNET_assert (GNUNET_YES == 2089 GNUNET_assert (GNUNET_YES ==
1613 GNUNET_CONTAINER_multihashmap32_remove (t->channels, 2090 GNUNET_CONTAINER_multihashmap32_remove (t->channels,
1614 ntohl (ctn.cn), 2091 ntohl (ctn.cn),
1615 ch)); 2092 ch));
1616 if (0 == 2093 if ( (0 ==
1617 GNUNET_CONTAINER_multihashmap32_size (t->channels)) 2094 GCT_count_channels (t)) &&
2095 (NULL == t->destroy_task) )
1618 { 2096 {
1619 t->destroy_task = GNUNET_SCHEDULER_add_delayed (IDLE_DESTROY_DELAY, 2097 t->destroy_task
1620 &destroy_tunnel, 2098 = GNUNET_SCHEDULER_add_delayed (IDLE_DESTROY_DELAY,
1621 t); 2099 &destroy_tunnel,
2100 t);
1622 } 2101 }
1623} 2102}
1624 2103
@@ -1638,7 +2117,8 @@ destroy_remaining_channels (void *cls,
1638{ 2117{
1639 struct CadetChannel *ch = value; 2118 struct CadetChannel *ch = value;
1640 2119
1641 GCCH_handle_remote_destroy (ch); 2120 GCCH_handle_remote_destroy (ch,
2121 NULL);
1642 return GNUNET_OK; 2122 return GNUNET_OK;
1643} 2123}
1644 2124
@@ -1656,7 +2136,7 @@ GCT_destroy_tunnel_now (struct CadetTunnel *t)
1656 &destroy_remaining_channels, 2136 &destroy_remaining_channels,
1657 t); 2137 t);
1658 GNUNET_assert (0 == 2138 GNUNET_assert (0 ==
1659 GNUNET_CONTAINER_multihashmap32_size (t->channels)); 2139 GCT_count_channels (t));
1660 if (NULL != t->destroy_task) 2140 if (NULL != t->destroy_task)
1661 { 2141 {
1662 GNUNET_SCHEDULER_cancel (t->destroy_task); 2142 GNUNET_SCHEDULER_cancel (t->destroy_task);
@@ -1667,25 +2147,6 @@ GCT_destroy_tunnel_now (struct CadetTunnel *t)
1667 2147
1668 2148
1669/** 2149/**
1670 * It's been a while, we should try to redo the KX, if we can.
1671 *
1672 * @param cls the `struct CadetTunnel` to do KX for.
1673 */
1674static void
1675retry_kx (void *cls)
1676{
1677 struct CadetTunnel *t = cls;
1678
1679 t->kx_task = NULL;
1680 send_kx (t,
1681 ( (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) ||
1682 (CADET_TUNNEL_KEY_SENT == t->estate) )
1683 ? GNUNET_YES
1684 : GNUNET_NO);
1685}
1686
1687
1688/**
1689 * Send normal payload from queue in @a t via connection @a ct. 2150 * Send normal payload from queue in @a t via connection @a ct.
1690 * Does nothing if our payload queue is empty. 2151 * Does nothing if our payload queue is empty.
1691 * 2152 *
@@ -1716,7 +2177,7 @@ try_send_normal_payload (struct CadetTunnel *t,
1716 tq); 2177 tq);
1717 if (NULL != tq->cid) 2178 if (NULL != tq->cid)
1718 *tq->cid = *GCC_get_id (ct->cc); 2179 *tq->cid = *GCC_get_id (ct->cc);
1719 ct->is_ready = GNUNET_NO; 2180 mark_connection_unready (ct);
1720 LOG (GNUNET_ERROR_TYPE_DEBUG, 2181 LOG (GNUNET_ERROR_TYPE_DEBUG,
1721 "Sending payload of %s on %s\n", 2182 "Sending payload of %s on %s\n",
1722 GCT_2s (t), 2183 GCT_2s (t),
@@ -1724,7 +2185,8 @@ try_send_normal_payload (struct CadetTunnel *t,
1724 GCC_transmit (ct->cc, 2185 GCC_transmit (ct->cc,
1725 tq->env); 2186 tq->env);
1726 if (NULL != tq->cont) 2187 if (NULL != tq->cont)
1727 tq->cont (tq->cont_cls); 2188 tq->cont (tq->cont_cls,
2189 GCC_get_id (ct->cc));
1728 GNUNET_free (tq); 2190 GNUNET_free (tq);
1729} 2191}
1730 2192
@@ -1747,44 +2209,74 @@ connection_ready_cb (void *cls,
1747 if (GNUNET_NO == is_ready) 2209 if (GNUNET_NO == is_ready)
1748 { 2210 {
1749 LOG (GNUNET_ERROR_TYPE_DEBUG, 2211 LOG (GNUNET_ERROR_TYPE_DEBUG,
1750 "Connection %s no longer ready for tunnel %s\n", 2212 "%s no longer ready for %s\n",
1751 GCC_2s (ct->cc), 2213 GCC_2s (ct->cc),
1752 GCT_2s (t)); 2214 GCT_2s (t));
1753 ct->is_ready = GNUNET_NO; 2215 mark_connection_unready (ct);
1754 return; 2216 return;
1755 } 2217 }
2218 GNUNET_assert (GNUNET_NO == ct->is_ready);
2219 GNUNET_CONTAINER_DLL_remove (t->connection_busy_head,
2220 t->connection_busy_tail,
2221 ct);
2222 GNUNET_assert (0 < t->num_busy_connections);
2223 t->num_busy_connections--;
1756 ct->is_ready = GNUNET_YES; 2224 ct->is_ready = GNUNET_YES;
2225 GNUNET_CONTAINER_DLL_insert_tail (t->connection_ready_head,
2226 t->connection_ready_tail,
2227 ct);
2228 t->num_ready_connections++;
2229
1757 LOG (GNUNET_ERROR_TYPE_DEBUG, 2230 LOG (GNUNET_ERROR_TYPE_DEBUG,
1758 "Connection %s now ready for tunnel %s in state %s\n", 2231 "%s now ready for %s in state %s\n",
1759 GCC_2s (ct->cc), 2232 GCC_2s (ct->cc),
1760 GCT_2s (t), 2233 GCT_2s (t),
1761 estate2s (t->estate)); 2234 estate2s (t->estate));
1762 switch (t->estate) 2235 switch (t->estate)
1763 { 2236 {
1764 case CADET_TUNNEL_KEY_UNINITIALIZED: 2237 case CADET_TUNNEL_KEY_UNINITIALIZED:
2238 /* Do not begin KX if WE have no channels waiting! */
2239 if (0 == GCT_count_channels (t))
2240 return;
2241 /* We are uninitialized, just transmit immediately,
2242 without undue delay. */
2243 if (NULL != t->kx_task)
2244 {
2245 GNUNET_SCHEDULER_cancel (t->kx_task);
2246 t->kx_task = NULL;
2247 }
1765 send_kx (t, 2248 send_kx (t,
1766 GNUNET_YES); 2249 ct,
2250 &t->ax);
1767 break; 2251 break;
1768 case CADET_TUNNEL_KEY_SENT: 2252 case CADET_TUNNEL_KEY_AX_RECV:
1769 case CADET_TUNNEL_KEY_PING: 2253 case CADET_TUNNEL_KEY_AX_SENT:
1770 /* opportunity to #retry_kx() starts now, schedule job */ 2254 case CADET_TUNNEL_KEY_AX_SENT_AND_RECV:
2255 case CADET_TUNNEL_KEY_AX_AUTH_SENT:
2256 /* we're currently waiting for KX to complete, schedule job */
1771 if (NULL == t->kx_task) 2257 if (NULL == t->kx_task)
1772 {
1773 t->kx_task 2258 t->kx_task
1774 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt, 2259 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
1775 &retry_kx, 2260 &retry_kx,
1776 t); 2261 t);
1777 }
1778 break; 2262 break;
1779 case CADET_TUNNEL_KEY_OK: 2263 case CADET_TUNNEL_KEY_OK:
2264 if (GNUNET_YES == t->kx_auth_requested)
2265 {
2266 if (NULL != t->kx_task)
2267 {
2268 GNUNET_SCHEDULER_cancel (t->kx_task);
2269 t->kx_task = NULL;
2270 }
2271 send_kx_auth (t,
2272 ct,
2273 &t->ax,
2274 GNUNET_NO);
2275 return;
2276 }
1780 try_send_normal_payload (t, 2277 try_send_normal_payload (t,
1781 ct); 2278 ct);
1782 break; 2279 break;
1783 case CADET_TUNNEL_KEY_REKEY:
1784 send_kx (t,
1785 GNUNET_NO);
1786 t->estate = CADET_TUNNEL_KEY_OK;
1787 break;
1788 } 2280 }
1789} 2281}
1790 2282
@@ -1815,6 +2307,118 @@ trigger_transmissions (void *cls)
1815 2307
1816 2308
1817/** 2309/**
2310 * Closure for #evaluate_connection. Used to assemble summary information
2311 * about the existing connections so we can evaluate a new path.
2312 */
2313struct EvaluationSummary
2314{
2315
2316 /**
2317 * Minimum length of any of our connections, `UINT_MAX` if we have none.
2318 */
2319 unsigned int min_length;
2320
2321 /**
2322 * Maximum length of any of our connections, 0 if we have none.
2323 */
2324 unsigned int max_length;
2325
2326 /**
2327 * Minimum desirability of any of our connections, UINT64_MAX if we have none.
2328 */
2329 GNUNET_CONTAINER_HeapCostType min_desire;
2330
2331 /**
2332 * Maximum desirability of any of our connections, 0 if we have none.
2333 */
2334 GNUNET_CONTAINER_HeapCostType max_desire;
2335
2336 /**
2337 * Path we are comparing against for #evaluate_connection, can be NULL.
2338 */
2339 struct CadetPeerPath *path;
2340
2341 /**
2342 * Connection deemed the "worst" so far encountered by #evaluate_connection,
2343 * NULL if we did not yet encounter any connections.
2344 */
2345 struct CadetTConnection *worst;
2346
2347 /**
2348 * Numeric score of @e worst, only set if @e worst is non-NULL.
2349 */
2350 double worst_score;
2351
2352 /**
2353 * Set to #GNUNET_YES if we have a connection over @e path already.
2354 */
2355 int duplicate;
2356
2357};
2358
2359
2360/**
2361 * Evaluate a connection, updating our summary information in @a cls about
2362 * what kinds of connections we have.
2363 *
2364 * @param cls the `struct EvaluationSummary *` to update
2365 * @param ct a connection to include in the summary
2366 */
2367static void
2368evaluate_connection (void *cls,
2369 struct CadetTConnection *ct)
2370{
2371 struct EvaluationSummary *es = cls;
2372 struct CadetConnection *cc = ct->cc;
2373 struct CadetPeerPath *ps = GCC_get_path (cc);
2374 const struct CadetConnectionMetrics *metrics;
2375 GNUNET_CONTAINER_HeapCostType ct_desirability;
2376 struct GNUNET_TIME_Relative uptime;
2377 struct GNUNET_TIME_Relative last_use;
2378 uint32_t ct_length;
2379 double score;
2380 double success_rate;
2381
2382 if (ps == es->path)
2383 {
2384 LOG (GNUNET_ERROR_TYPE_DEBUG,
2385 "Ignoring duplicate path %s.\n",
2386 GCPP_2s (es->path));
2387 es->duplicate = GNUNET_YES;
2388 return;
2389 }
2390 ct_desirability = GCPP_get_desirability (ps);
2391 ct_length = GCPP_get_length (ps);
2392 metrics = GCC_get_metrics (cc);
2393 uptime = GNUNET_TIME_absolute_get_duration (metrics->age);
2394 last_use = GNUNET_TIME_absolute_get_duration (metrics->last_use);
2395 /* We add 1.0 here to avoid division by zero. */
2396 success_rate = (metrics->num_acked_transmissions + 1.0) / (metrics->num_successes + 1.0);
2397 score
2398 = ct_desirability
2399 + 100.0 / (1.0 + ct_length) /* longer paths = better */
2400 + sqrt (uptime.rel_value_us / 60000000LL) /* larger uptime = better */
2401 - last_use.rel_value_us / 1000L; /* longer idle = worse */
2402 score *= success_rate; /* weigh overall by success rate */
2403
2404 if ( (NULL == es->worst) ||
2405 (score < es->worst_score) )
2406 {
2407 es->worst = ct;
2408 es->worst_score = score;
2409 }
2410 es->min_length = GNUNET_MIN (es->min_length,
2411 ct_length);
2412 es->max_length = GNUNET_MAX (es->max_length,
2413 ct_length);
2414 es->min_desire = GNUNET_MIN (es->min_desire,
2415 ct_desirability);
2416 es->max_desire = GNUNET_MAX (es->max_desire,
2417 ct_desirability);
2418}
2419
2420
2421/**
1818 * Consider using the path @a p for the tunnel @a t. 2422 * Consider using the path @a p for the tunnel @a t.
1819 * The tunnel destination is at offset @a off in path @a p. 2423 * The tunnel destination is at offset @a off in path @a p.
1820 * 2424 *
@@ -1829,31 +2433,24 @@ consider_path_cb (void *cls,
1829 unsigned int off) 2433 unsigned int off)
1830{ 2434{
1831 struct CadetTunnel *t = cls; 2435 struct CadetTunnel *t = cls;
1832 unsigned int min_length = UINT_MAX; 2436 struct EvaluationSummary es;
1833 GNUNET_CONTAINER_HeapCostType max_desire = 0;
1834 struct CadetTConnection *ct; 2437 struct CadetTConnection *ct;
1835 2438
1836 /* Check if we care about the new path. */ 2439 GNUNET_assert (off < GCPP_get_length (path));
1837 for (ct = t->connection_head; 2440 es.min_length = UINT_MAX;
1838 NULL != ct; 2441 es.max_length = 0;
1839 ct = ct->next) 2442 es.max_desire = 0;
1840 { 2443 es.min_desire = UINT64_MAX;
1841 struct CadetPeerPath *ps; 2444 es.path = path;
1842 2445 es.duplicate = GNUNET_NO;
1843 ps = GCC_get_path (ct->cc); 2446 es.worst = NULL;
1844 if (ps == path) 2447
1845 { 2448 /* Compute evaluation summary over existing connections. */
1846 LOG (GNUNET_ERROR_TYPE_DEBUG, 2449 GCT_iterate_connections (t,
1847 "Ignoring duplicate path %s for tunnel %s.\n", 2450 &evaluate_connection,
1848 GCPP_2s (path), 2451 &es);
1849 GCT_2s (t)); 2452 if (GNUNET_YES == es.duplicate)
1850 return GNUNET_YES; /* duplicate */ 2453 return GNUNET_YES;
1851 }
1852 min_length = GNUNET_MIN (min_length,
1853 GCPP_get_length (ps));
1854 max_desire = GNUNET_MAX (max_desire,
1855 GCPP_get_desirability (ps));
1856 }
1857 2454
1858 /* FIXME: not sure we should really just count 2455 /* FIXME: not sure we should really just count
1859 'num_connections' here, as they may all have 2456 'num_connections' here, as they may all have
@@ -1862,18 +2459,20 @@ consider_path_cb (void *cls,
1862 /* We iterate by increasing path length; if we have enough paths and 2459 /* We iterate by increasing path length; if we have enough paths and
1863 this one is more than twice as long than what we are currently 2460 this one is more than twice as long than what we are currently
1864 using, then ignore all of these super-long ones! */ 2461 using, then ignore all of these super-long ones! */
1865 if ( (t->num_connections > DESIRED_CONNECTIONS_PER_TUNNEL) && 2462 if ( (GCT_count_any_connections (t) > DESIRED_CONNECTIONS_PER_TUNNEL) &&
1866 (min_length * 2 < off) ) 2463 (es.min_length * 2 < off) &&
2464 (es.max_length < off) )
1867 { 2465 {
1868 LOG (GNUNET_ERROR_TYPE_DEBUG, 2466 LOG (GNUNET_ERROR_TYPE_DEBUG,
1869 "Ignoring paths of length %u, they are way too long.\n", 2467 "Ignoring paths of length %u, they are way too long.\n",
1870 min_length * 2); 2468 es.min_length * 2);
1871 return GNUNET_NO; 2469 return GNUNET_NO;
1872 } 2470 }
1873 /* If we have enough paths and this one looks no better, ignore it. */ 2471 /* If we have enough paths and this one looks no better, ignore it. */
1874 if ( (t->num_connections >= DESIRED_CONNECTIONS_PER_TUNNEL) && 2472 if ( (GCT_count_any_connections (t) >= DESIRED_CONNECTIONS_PER_TUNNEL) &&
1875 (min_length < GCPP_get_length (path)) && 2473 (es.min_length < GCPP_get_length (path)) &&
1876 (max_desire > GCPP_get_desirability (path)) ) 2474 (es.min_desire > GCPP_get_desirability (path)) &&
2475 (es.max_length < off) )
1877 { 2476 {
1878 LOG (GNUNET_ERROR_TYPE_DEBUG, 2477 LOG (GNUNET_ERROR_TYPE_DEBUG,
1879 "Ignoring path (%u/%llu) to %s, got something better already.\n", 2478 "Ignoring path (%u/%llu) to %s, got something better already.\n",
@@ -1890,19 +2489,22 @@ consider_path_cb (void *cls,
1890 ct->t = t; 2489 ct->t = t;
1891 ct->cc = GCC_create (t->destination, 2490 ct->cc = GCC_create (t->destination,
1892 path, 2491 path,
2492 off,
2493 GNUNET_CADET_OPTION_DEFAULT, /* FIXME: set based on what channels want/need! */
1893 ct, 2494 ct,
1894 &connection_ready_cb, 2495 &connection_ready_cb,
1895 ct); 2496 ct);
2497
1896 /* FIXME: schedule job to kill connection (and path?) if it takes 2498 /* FIXME: schedule job to kill connection (and path?) if it takes
1897 too long to get ready! (And track performance data on how long 2499 too long to get ready! (And track performance data on how long
1898 other connections took with the tunnel!) 2500 other connections took with the tunnel!)
1899 => Note: to be done within 'connection'-logic! */ 2501 => Note: to be done within 'connection'-logic! */
1900 GNUNET_CONTAINER_DLL_insert (t->connection_head, 2502 GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
1901 t->connection_tail, 2503 t->connection_busy_tail,
1902 ct); 2504 ct);
1903 t->num_connections++; 2505 t->num_busy_connections++;
1904 LOG (GNUNET_ERROR_TYPE_DEBUG, 2506 LOG (GNUNET_ERROR_TYPE_DEBUG,
1905 "Found interesting path %s for tunnel %s, created connection %s\n", 2507 "Found interesting path %s for %s, created %s\n",
1906 GCPP_2s (path), 2508 GCPP_2s (path),
1907 GCT_2s (t), 2509 GCT_2s (t),
1908 GCC_2s (ct->cc)); 2510 GCC_2s (ct->cc));
@@ -1927,17 +2529,50 @@ static void
1927maintain_connections_cb (void *cls) 2529maintain_connections_cb (void *cls)
1928{ 2530{
1929 struct CadetTunnel *t = cls; 2531 struct CadetTunnel *t = cls;
2532 struct GNUNET_TIME_Relative delay;
2533 struct EvaluationSummary es;
1930 2534
1931 t->maintain_connections_task = NULL; 2535 t->maintain_connections_task = NULL;
1932 LOG (GNUNET_ERROR_TYPE_DEBUG, 2536 LOG (GNUNET_ERROR_TYPE_DEBUG,
1933 "Performing connection maintenance for tunnel %s.\n", 2537 "Performing connection maintenance for %s.\n",
1934 GCT_2s (t)); 2538 GCT_2s (t));
1935 2539
2540 es.min_length = UINT_MAX;
2541 es.max_length = 0;
2542 es.max_desire = 0;
2543 es.min_desire = UINT64_MAX;
2544 es.path = NULL;
2545 es.worst = NULL;
2546 es.duplicate = GNUNET_NO;
2547 GCT_iterate_connections (t,
2548 &evaluate_connection,
2549 &es);
2550 if ( (NULL != es.worst) &&
2551 (GCT_count_any_connections (t) > DESIRED_CONNECTIONS_PER_TUNNEL) )
2552 {
2553 /* Clear out worst-performing connection 'es.worst'. */
2554 destroy_t_connection (t,
2555 es.worst);
2556 }
2557
2558 /* Consider additional paths */
1936 (void) GCP_iterate_paths (t->destination, 2559 (void) GCP_iterate_paths (t->destination,
1937 &consider_path_cb, 2560 &consider_path_cb,
1938 t); 2561 t);
1939 2562
1940 GNUNET_break (0); // FIXME: implement! 2563 /* FIXME: calculate when to try again based on how well we are doing;
2564 in particular, if we have to few connections, we might be able
2565 to do without this (as PATHS should tell us whenever a new path
2566 is available instantly; however, need to make sure this job is
2567 restarted after that happens).
2568 Furthermore, if the paths we do know are in a reasonably narrow
2569 quality band and are plentyful, we might also consider us stabilized
2570 and then reduce the frequency accordingly. */
2571 delay = GNUNET_TIME_UNIT_MINUTES;
2572 t->maintain_connections_task
2573 = GNUNET_SCHEDULER_add_delayed (delay,
2574 &maintain_connections_cb,
2575 t);
1941} 2576}
1942 2577
1943 2578
@@ -1954,6 +2589,10 @@ GCT_consider_path (struct CadetTunnel *t,
1954 struct CadetPeerPath *p, 2589 struct CadetPeerPath *p,
1955 unsigned int off) 2590 unsigned int off)
1956{ 2591{
2592 LOG (GNUNET_ERROR_TYPE_DEBUG,
2593 "Considering %s for %s\n",
2594 GCPP_2s (p),
2595 GCT_2s (t));
1957 (void) consider_path_cb (t, 2596 (void) consider_path_cb (t,
1958 p, 2597 p,
1959 off); 2598 off);
@@ -1961,7 +2600,7 @@ GCT_consider_path (struct CadetTunnel *t,
1961 2600
1962 2601
1963/** 2602/**
1964 * NOT IMPLEMENTED. 2603 * We got a keepalive. Track in statistics.
1965 * 2604 *
1966 * @param cls the `struct CadetTunnel` for which we decrypted the message 2605 * @param cls the `struct CadetTunnel` for which we decrypted the message
1967 * @param msg the message we received on the tunnel 2606 * @param msg the message we received on the tunnel
@@ -1972,7 +2611,13 @@ handle_plaintext_keepalive (void *cls,
1972{ 2611{
1973 struct CadetTunnel *t = cls; 2612 struct CadetTunnel *t = cls;
1974 2613
1975 GNUNET_break (0); // FIXME 2614 LOG (GNUNET_ERROR_TYPE_DEBUG,
2615 "Received KEEPALIVE on %s\n",
2616 GCT_2s (t));
2617 GNUNET_STATISTICS_update (stats,
2618 "# keepalives received",
2619 1,
2620 GNUNET_NO);
1976} 2621}
1977 2622
1978 2623
@@ -2012,7 +2657,7 @@ handle_plaintext_data (void *cls,
2012 /* We don't know about such a channel, might have been destroyed on our 2657 /* We don't know about such a channel, might have been destroyed on our
2013 end in the meantime, or never existed. Send back a DESTROY. */ 2658 end in the meantime, or never existed. Send back a DESTROY. */
2014 LOG (GNUNET_ERROR_TYPE_DEBUG, 2659 LOG (GNUNET_ERROR_TYPE_DEBUG,
2015 "Receicved %u bytes of application data for unknown channel %u, sending DESTROY\n", 2660 "Received %u bytes of application data for unknown channel %u, sending DESTROY\n",
2016 (unsigned int) (ntohs (msg->header.size) - sizeof (*msg)), 2661 (unsigned int) (ntohs (msg->header.size) - sizeof (*msg)),
2017 ntohl (msg->ctn.cn)); 2662 ntohl (msg->ctn.cn));
2018 GCT_send_channel_destroy (t, 2663 GCT_send_channel_destroy (t,
@@ -2020,6 +2665,7 @@ handle_plaintext_data (void *cls,
2020 return; 2665 return;
2021 } 2666 }
2022 GCCH_handle_channel_plaintext_data (ch, 2667 GCCH_handle_channel_plaintext_data (ch,
2668 GCC_get_id (t->current_ct->cc),
2023 msg); 2669 msg);
2024} 2670}
2025 2671
@@ -2046,13 +2692,14 @@ handle_plaintext_data_ack (void *cls,
2046 /* We don't know about such a channel, might have been destroyed on our 2692 /* We don't know about such a channel, might have been destroyed on our
2047 end in the meantime, or never existed. Send back a DESTROY. */ 2693 end in the meantime, or never existed. Send back a DESTROY. */
2048 LOG (GNUNET_ERROR_TYPE_DEBUG, 2694 LOG (GNUNET_ERROR_TYPE_DEBUG,
2049 "Receicved DATA_ACK for unknown channel %u, sending DESTROY\n", 2695 "Received DATA_ACK for unknown channel %u, sending DESTROY\n",
2050 ntohl (ack->ctn.cn)); 2696 ntohl (ack->ctn.cn));
2051 GCT_send_channel_destroy (t, 2697 GCT_send_channel_destroy (t,
2052 ack->ctn); 2698 ack->ctn);
2053 return; 2699 return;
2054 } 2700 }
2055 GCCH_handle_channel_plaintext_data_ack (ch, 2701 GCCH_handle_channel_plaintext_data_ack (ch,
2702 GCC_get_id (t->current_ct->cc),
2056 ack); 2703 ack);
2057} 2704}
2058 2705
@@ -2076,21 +2723,27 @@ handle_plaintext_channel_open (void *cls,
2076 if (NULL != ch) 2723 if (NULL != ch)
2077 { 2724 {
2078 LOG (GNUNET_ERROR_TYPE_DEBUG, 2725 LOG (GNUNET_ERROR_TYPE_DEBUG,
2079 "Receicved duplicate channel OPEN on port %s from %s (%s), resending ACK\n", 2726 "Received duplicate channel CHANNEL_OPEN on h_port %s from %s (%s), resending ACK\n",
2080 GNUNET_h2s (&copen->port), 2727 GNUNET_h2s (&copen->h_port),
2081 GCT_2s (t), 2728 GCT_2s (t),
2082 GCCH_2s (ch)); 2729 GCCH_2s (ch));
2083 GCCH_handle_duplicate_open (ch); 2730 GCCH_handle_duplicate_open (ch,
2731 GCC_get_id (t->current_ct->cc));
2084 return; 2732 return;
2085 } 2733 }
2086 LOG (GNUNET_ERROR_TYPE_DEBUG, 2734 LOG (GNUNET_ERROR_TYPE_DEBUG,
2087 "Receicved channel OPEN on port %s from %s\n", 2735 "Received CHANNEL_OPEN on h_port %s from %s\n",
2088 GNUNET_h2s (&copen->port), 2736 GNUNET_h2s (&copen->h_port),
2089 GCT_2s (t)); 2737 GCT_2s (t));
2090 ch = GCCH_channel_incoming_new (t, 2738 ch = GCCH_channel_incoming_new (t,
2091 copen->ctn, 2739 copen->ctn,
2092 &copen->port, 2740 &copen->h_port,
2093 ntohl (copen->opt)); 2741 ntohl (copen->opt));
2742 if (NULL != t->destroy_task)
2743 {
2744 GNUNET_SCHEDULER_cancel (t->destroy_task);
2745 t->destroy_task = NULL;
2746 }
2094 GNUNET_assert (GNUNET_OK == 2747 GNUNET_assert (GNUNET_OK ==
2095 GNUNET_CONTAINER_multihashmap32_put (t->channels, 2748 GNUNET_CONTAINER_multihashmap32_put (t->channels,
2096 ntohl (copen->ctn.cn), 2749 ntohl (copen->ctn.cn),
@@ -2109,7 +2762,7 @@ void
2109GCT_send_channel_destroy (struct CadetTunnel *t, 2762GCT_send_channel_destroy (struct CadetTunnel *t,
2110 struct GNUNET_CADET_ChannelTunnelNumber ctn) 2763 struct GNUNET_CADET_ChannelTunnelNumber ctn)
2111{ 2764{
2112 struct GNUNET_CADET_ChannelManageMessage msg; 2765 struct GNUNET_CADET_ChannelDestroyMessage msg;
2113 2766
2114 LOG (GNUNET_ERROR_TYPE_DEBUG, 2767 LOG (GNUNET_ERROR_TYPE_DEBUG,
2115 "Sending DESTORY message for channel ID %u\n", 2768 "Sending DESTORY message for channel ID %u\n",
@@ -2135,7 +2788,7 @@ GCT_send_channel_destroy (struct CadetTunnel *t,
2135 */ 2788 */
2136static void 2789static void
2137handle_plaintext_channel_open_ack (void *cls, 2790handle_plaintext_channel_open_ack (void *cls,
2138 const struct GNUNET_CADET_ChannelManageMessage *cm) 2791 const struct GNUNET_CADET_ChannelOpenAckMessage *cm)
2139{ 2792{
2140 struct CadetTunnel *t = cls; 2793 struct CadetTunnel *t = cls;
2141 struct CadetChannel *ch; 2794 struct CadetChannel *ch;
@@ -2157,7 +2810,9 @@ handle_plaintext_channel_open_ack (void *cls,
2157 "Received channel OPEN_ACK on channel %s from %s\n", 2810 "Received channel OPEN_ACK on channel %s from %s\n",
2158 GCCH_2s (ch), 2811 GCCH_2s (ch),
2159 GCT_2s (t)); 2812 GCT_2s (t));
2160 GCCH_handle_channel_open_ack (ch); 2813 GCCH_handle_channel_open_ack (ch,
2814 GCC_get_id (t->current_ct->cc),
2815 &cm->port);
2161} 2816}
2162 2817
2163 2818
@@ -2170,7 +2825,7 @@ handle_plaintext_channel_open_ack (void *cls,
2170 */ 2825 */
2171static void 2826static void
2172handle_plaintext_channel_destroy (void *cls, 2827handle_plaintext_channel_destroy (void *cls,
2173 const struct GNUNET_CADET_ChannelManageMessage *cm) 2828 const struct GNUNET_CADET_ChannelDestroyMessage *cm)
2174{ 2829{
2175 struct CadetTunnel *t = cls; 2830 struct CadetTunnel *t = cls;
2176 struct CadetChannel *ch; 2831 struct CadetChannel *ch;
@@ -2187,10 +2842,11 @@ handle_plaintext_channel_destroy (void *cls,
2187 return; 2842 return;
2188 } 2843 }
2189 LOG (GNUNET_ERROR_TYPE_DEBUG, 2844 LOG (GNUNET_ERROR_TYPE_DEBUG,
2190 "Receicved channel DESTROY on %s from %s\n", 2845 "Received channel DESTROY on %s from %s\n",
2191 GCCH_2s (ch), 2846 GCCH_2s (ch),
2192 GCT_2s (t)); 2847 GCT_2s (t));
2193 GCCH_handle_remote_destroy (ch); 2848 GCCH_handle_remote_destroy (ch,
2849 GCC_get_id (t->current_ct->cc));
2194} 2850}
2195 2851
2196 2852
@@ -2208,6 +2864,7 @@ handle_decrypted (void *cls,
2208{ 2864{
2209 struct CadetTunnel *t = cls; 2865 struct CadetTunnel *t = cls;
2210 2866
2867 GNUNET_assert (NULL != t->current_ct);
2211 GNUNET_MQ_inject_message (t->mq, 2868 GNUNET_MQ_inject_message (t->mq,
2212 msg); 2869 msg);
2213 return GNUNET_OK; 2870 return GNUNET_OK;
@@ -2259,17 +2916,19 @@ GCT_create_tunnel (struct CadetPeer *destination)
2259 t), 2916 t),
2260 GNUNET_MQ_hd_fixed_size (plaintext_channel_open_ack, 2917 GNUNET_MQ_hd_fixed_size (plaintext_channel_open_ack,
2261 GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK, 2918 GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK,
2262 struct GNUNET_CADET_ChannelManageMessage, 2919 struct GNUNET_CADET_ChannelOpenAckMessage,
2263 t), 2920 t),
2264 GNUNET_MQ_hd_fixed_size (plaintext_channel_destroy, 2921 GNUNET_MQ_hd_fixed_size (plaintext_channel_destroy,
2265 GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY, 2922 GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY,
2266 struct GNUNET_CADET_ChannelManageMessage, 2923 struct GNUNET_CADET_ChannelDestroyMessage,
2267 t), 2924 t),
2268 GNUNET_MQ_handler_end () 2925 GNUNET_MQ_handler_end ()
2269 }; 2926 };
2270 2927
2271 new_ephemeral (t); 2928 t->kx_retry_delay = INITIAL_KX_RETRY_DELAY;
2272 t->ax.kx_0 = GNUNET_CRYPTO_ecdhe_key_create (); 2929 new_ephemeral (&t->ax);
2930 GNUNET_assert (GNUNET_OK ==
2931 GNUNET_CRYPTO_ecdhe_key_create2 (&t->ax.kx_0));
2273 t->destination = destination; 2932 t->destination = destination;
2274 t->channels = GNUNET_CONTAINER_multihashmap32_create (8); 2933 t->channels = GNUNET_CONTAINER_multihashmap32_create (8);
2275 t->maintain_connections_task 2934 t->maintain_connections_task
@@ -2293,11 +2952,15 @@ GCT_create_tunnel (struct CadetPeer *destination)
2293 * 2952 *
2294 * @param t a tunnel 2953 * @param t a tunnel
2295 * @param cid connection identifer to use for the connection 2954 * @param cid connection identifer to use for the connection
2955 * @param options options for the connection
2296 * @param path path to use for the connection 2956 * @param path path to use for the connection
2957 * @return #GNUNET_OK on success,
2958 * #GNUNET_SYSERR on failure (duplicate connection)
2297 */ 2959 */
2298void 2960int
2299GCT_add_inbound_connection (struct CadetTunnel *t, 2961GCT_add_inbound_connection (struct CadetTunnel *t,
2300 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid, 2962 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
2963 enum GNUNET_CADET_ChannelOption options,
2301 struct CadetPeerPath *path) 2964 struct CadetPeerPath *path)
2302{ 2965{
2303 struct CadetTConnection *ct; 2966 struct CadetTConnection *ct;
@@ -2307,22 +2970,33 @@ GCT_add_inbound_connection (struct CadetTunnel *t,
2307 ct->t = t; 2970 ct->t = t;
2308 ct->cc = GCC_create_inbound (t->destination, 2971 ct->cc = GCC_create_inbound (t->destination,
2309 path, 2972 path,
2973 options,
2310 ct, 2974 ct,
2311 cid, 2975 cid,
2312 &connection_ready_cb, 2976 &connection_ready_cb,
2313 ct); 2977 ct);
2978 if (NULL == ct->cc)
2979 {
2980 LOG (GNUNET_ERROR_TYPE_DEBUG,
2981 "%s refused inbound %s (duplicate)\n",
2982 GCT_2s (t),
2983 GCC_2s (ct->cc));
2984 GNUNET_free (ct);
2985 return GNUNET_SYSERR;
2986 }
2314 /* FIXME: schedule job to kill connection (and path?) if it takes 2987 /* FIXME: schedule job to kill connection (and path?) if it takes
2315 too long to get ready! (And track performance data on how long 2988 too long to get ready! (And track performance data on how long
2316 other connections took with the tunnel!) 2989 other connections took with the tunnel!)
2317 => Note: to be done within 'connection'-logic! */ 2990 => Note: to be done within 'connection'-logic! */
2318 GNUNET_CONTAINER_DLL_insert (t->connection_head, 2991 GNUNET_CONTAINER_DLL_insert (t->connection_busy_head,
2319 t->connection_tail, 2992 t->connection_busy_tail,
2320 ct); 2993 ct);
2321 t->num_connections++; 2994 t->num_busy_connections++;
2322 LOG (GNUNET_ERROR_TYPE_DEBUG, 2995 LOG (GNUNET_ERROR_TYPE_DEBUG,
2323 "Tunnel %s has new connection %s\n", 2996 "%s has new %s\n",
2324 GCT_2s (t), 2997 GCT_2s (t),
2325 GCC_2s (ct->cc)); 2998 GCC_2s (ct->cc));
2999 return GNUNET_OK;
2326} 3000}
2327 3001
2328 3002
@@ -2342,7 +3016,7 @@ GCT_handle_encrypted (struct CadetTConnection *ct,
2342 ssize_t decrypted_size; 3016 ssize_t decrypted_size;
2343 3017
2344 LOG (GNUNET_ERROR_TYPE_DEBUG, 3018 LOG (GNUNET_ERROR_TYPE_DEBUG,
2345 "Tunnel %s received %u bytes of encrypted data in state %d\n", 3019 "%s received %u bytes of encrypted data in state %d\n",
2346 GCT_2s (t), 3020 GCT_2s (t),
2347 (unsigned int) size, 3021 (unsigned int) size,
2348 t->estate); 3022 t->estate);
@@ -2350,66 +3024,158 @@ GCT_handle_encrypted (struct CadetTConnection *ct,
2350 switch (t->estate) 3024 switch (t->estate)
2351 { 3025 {
2352 case CADET_TUNNEL_KEY_UNINITIALIZED: 3026 case CADET_TUNNEL_KEY_UNINITIALIZED:
3027 case CADET_TUNNEL_KEY_AX_RECV:
2353 /* We did not even SEND our KX, how can the other peer 3028 /* We did not even SEND our KX, how can the other peer
2354 send us encrypted data? */ 3029 send us encrypted data? Must have been that we went
2355 GNUNET_break_op (0); 3030 down and the other peer still things we are up.
3031 Let's send it KX back. */
3032 GNUNET_STATISTICS_update (stats,
3033 "# received encrypted without any KX",
3034 1,
3035 GNUNET_NO);
3036 if (NULL != t->kx_task)
3037 {
3038 GNUNET_SCHEDULER_cancel (t->kx_task);
3039 t->kx_task = NULL;
3040 }
3041 send_kx (t,
3042 ct,
3043 &t->ax);
2356 return; 3044 return;
2357 case CADET_TUNNEL_KEY_SENT: 3045 case CADET_TUNNEL_KEY_AX_SENT_AND_RECV:
3046 /* We send KX, and other peer send KX to us at the same time.
3047 Neither KX is AUTH'ed, so let's try KX_AUTH this time. */
3048 GNUNET_STATISTICS_update (stats,
3049 "# received encrypted without KX_AUTH",
3050 1,
3051 GNUNET_NO);
3052 if (NULL != t->kx_task)
3053 {
3054 GNUNET_SCHEDULER_cancel (t->kx_task);
3055 t->kx_task = NULL;
3056 }
3057 send_kx_auth (t,
3058 ct,
3059 &t->ax,
3060 GNUNET_YES);
3061 return;
3062 case CADET_TUNNEL_KEY_AX_SENT:
2358 /* We did not get the KX of the other peer, but that 3063 /* We did not get the KX of the other peer, but that
2359 might have been lost. Ask for KX again. */ 3064 might have been lost. Send our KX again immediately. */
2360 GNUNET_STATISTICS_update (stats, 3065 GNUNET_STATISTICS_update (stats,
2361 "# received encrypted without KX", 3066 "# received encrypted without KX",
2362 1, 3067 1,
2363 GNUNET_NO); 3068 GNUNET_NO);
2364 if (NULL != t->kx_task) 3069 if (NULL != t->kx_task)
3070 {
2365 GNUNET_SCHEDULER_cancel (t->kx_task); 3071 GNUNET_SCHEDULER_cancel (t->kx_task);
2366 t->kx_task = GNUNET_SCHEDULER_add_now (&retry_kx, 3072 t->kx_task = NULL;
2367 t); 3073 }
3074 send_kx (t,
3075 ct,
3076 &t->ax);
2368 return; 3077 return;
2369 case CADET_TUNNEL_KEY_PING: 3078 case CADET_TUNNEL_KEY_AX_AUTH_SENT:
2370 /* Great, first payload, we might graduate to OK */ 3079 /* Great, first payload, we might graduate to OK! */
2371 case CADET_TUNNEL_KEY_OK: 3080 case CADET_TUNNEL_KEY_OK:
2372 case CADET_TUNNEL_KEY_REKEY: 3081 /* We are up and running, all good. */
2373 break; 3082 break;
2374 } 3083 }
2375 3084
2376 GNUNET_STATISTICS_update (stats, 3085 decrypted_size = -1;
2377 "# received encrypted", 3086 if (CADET_TUNNEL_KEY_OK == t->estate)
2378 1, 3087 {
2379 GNUNET_NO); 3088 /* We have well-established key material available,
2380 decrypted_size = t_ax_decrypt_and_validate (t, 3089 try that. (This is the common case.) */
2381 cbuf, 3090 decrypted_size = t_ax_decrypt_and_validate (&t->ax,
2382 msg, 3091 cbuf,
2383 size); 3092 msg,
3093 size);
3094 }
3095
3096 if ( (-1 == decrypted_size) &&
3097 (NULL != t->unverified_ax) )
3098 {
3099 /* We have un-authenticated KX material available. We should try
3100 this as a back-up option, in case the sender crashed and
3101 switched keys. */
3102 decrypted_size = t_ax_decrypt_and_validate (t->unverified_ax,
3103 cbuf,
3104 msg,
3105 size);
3106 if (-1 != decrypted_size)
3107 {
3108 /* It worked! Treat this as authentication of the AX data! */
3109 cleanup_ax (&t->ax);
3110 t->ax = *t->unverified_ax;
3111 GNUNET_free (t->unverified_ax);
3112 t->unverified_ax = NULL;
3113 }
3114 if (CADET_TUNNEL_KEY_AX_AUTH_SENT == t->estate)
3115 {
3116 /* First time it worked, move tunnel into production! */
3117 GCT_change_estate (t,
3118 CADET_TUNNEL_KEY_OK);
3119 if (NULL != t->send_task)
3120 GNUNET_SCHEDULER_cancel (t->send_task);
3121 t->send_task = GNUNET_SCHEDULER_add_now (&trigger_transmissions,
3122 t);
3123 }
3124 }
3125 if (NULL != t->unverified_ax)
3126 {
3127 /* We had unverified KX material that was useless; so increment
3128 counter and eventually move to ignore it. Note that we even do
3129 this increment if we successfully decrypted with the old KX
3130 material and thus didn't even both with the new one. This is
3131 the ideal case, as a malicious injection of bogus KX data
3132 basically only causes us to increment a counter a few times. */
3133 t->unverified_attempts++;
3134 LOG (GNUNET_ERROR_TYPE_DEBUG,
3135 "Failed to decrypt message with unverified KX data %u times\n",
3136 t->unverified_attempts);
3137 if (t->unverified_attempts > MAX_UNVERIFIED_ATTEMPTS)
3138 {
3139 cleanup_ax (t->unverified_ax);
3140 GNUNET_free (t->unverified_ax);
3141 t->unverified_ax = NULL;
3142 }
3143 }
2384 3144
2385 if (-1 == decrypted_size) 3145 if (-1 == decrypted_size)
2386 { 3146 {
2387 GNUNET_break_op (0); 3147 /* Decryption failed for good, complain. */
2388 LOG (GNUNET_ERROR_TYPE_WARNING, 3148 LOG (GNUNET_ERROR_TYPE_WARNING,
2389 "Tunnel %s failed to decrypt and validate encrypted data\n", 3149 "%s failed to decrypt and validate encrypted data, retrying KX\n",
2390 GCT_2s (t)); 3150 GCT_2s (t));
2391 GNUNET_STATISTICS_update (stats, 3151 GNUNET_STATISTICS_update (stats,
2392 "# unable to decrypt", 3152 "# unable to decrypt",
2393 1, 3153 1,
2394 GNUNET_NO); 3154 GNUNET_NO);
3155 if (NULL != t->kx_task)
3156 {
3157 GNUNET_SCHEDULER_cancel (t->kx_task);
3158 t->kx_task = NULL;
3159 }
3160 send_kx (t,
3161 ct,
3162 &t->ax);
2395 return; 3163 return;
2396 } 3164 }
2397 if (CADET_TUNNEL_KEY_PING == t->estate) 3165 GNUNET_STATISTICS_update (stats,
2398 { 3166 "# decrypted bytes",
2399 GCT_change_estate (t, 3167 decrypted_size,
2400 CADET_TUNNEL_KEY_OK); 3168 GNUNET_NO);
2401 if (NULL != t->send_task) 3169
2402 GNUNET_SCHEDULER_cancel (t->send_task);
2403 t->send_task = GNUNET_SCHEDULER_add_now (&trigger_transmissions,
2404 t);
2405 }
2406 /* The MST will ultimately call #handle_decrypted() on each message. */ 3170 /* The MST will ultimately call #handle_decrypted() on each message. */
3171 t->current_ct = ct;
2407 GNUNET_break_op (GNUNET_OK == 3172 GNUNET_break_op (GNUNET_OK ==
2408 GNUNET_MST_from_buffer (t->mst, 3173 GNUNET_MST_from_buffer (t->mst,
2409 cbuf, 3174 cbuf,
2410 decrypted_size, 3175 decrypted_size,
2411 GNUNET_YES, 3176 GNUNET_YES,
2412 GNUNET_NO)); 3177 GNUNET_NO));
3178 t->current_ct = NULL;
2413} 3179}
2414 3180
2415 3181
@@ -2421,12 +3187,12 @@ GCT_handle_encrypted (struct CadetTConnection *ct,
2421 * @param t Tunnel on which this message is transmitted. 3187 * @param t Tunnel on which this message is transmitted.
2422 * @param cont Continuation to call once message is really sent. 3188 * @param cont Continuation to call once message is really sent.
2423 * @param cont_cls Closure for @c cont. 3189 * @param cont_cls Closure for @c cont.
2424 * @return Handle to cancel message. NULL if @c cont is NULL. 3190 * @return Handle to cancel message
2425 */ 3191 */
2426struct CadetTunnelQueueEntry * 3192struct CadetTunnelQueueEntry *
2427GCT_send (struct CadetTunnel *t, 3193GCT_send (struct CadetTunnel *t,
2428 const struct GNUNET_MessageHeader *message, 3194 const struct GNUNET_MessageHeader *message,
2429 GNUNET_SCHEDULER_TaskCallback cont, 3195 GCT_SendContinuation cont,
2430 void *cont_cls) 3196 void *cont_cls)
2431{ 3197{
2432 struct CadetTunnelQueueEntry *tq; 3198 struct CadetTunnelQueueEntry *tq;
@@ -2434,26 +3200,38 @@ GCT_send (struct CadetTunnel *t,
2434 struct GNUNET_MQ_Envelope *env; 3200 struct GNUNET_MQ_Envelope *env;
2435 struct GNUNET_CADET_TunnelEncryptedMessage *ax_msg; 3201 struct GNUNET_CADET_TunnelEncryptedMessage *ax_msg;
2436 3202
3203 if (CADET_TUNNEL_KEY_OK != t->estate)
3204 {
3205 GNUNET_break (0);
3206 return NULL;
3207 }
2437 payload_size = ntohs (message->size); 3208 payload_size = ntohs (message->size);
2438 LOG (GNUNET_ERROR_TYPE_DEBUG, 3209 LOG (GNUNET_ERROR_TYPE_DEBUG,
2439 "Encrypting %u bytes for tunnel %s\n", 3210 "Encrypting %u bytes for %s\n",
2440 (unsigned int) payload_size, 3211 (unsigned int) payload_size,
2441 GCT_2s (t)); 3212 GCT_2s (t));
2442 env = GNUNET_MQ_msg_extra (ax_msg, 3213 env = GNUNET_MQ_msg_extra (ax_msg,
2443 payload_size, 3214 payload_size,
2444 GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED); 3215 GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED);
2445 t_ax_encrypt (t, 3216 t_ax_encrypt (&t->ax,
2446 &ax_msg[1], 3217 &ax_msg[1],
2447 message, 3218 message,
2448 payload_size); 3219 payload_size);
2449 ax_msg->Ns = htonl (t->ax.Ns++); 3220 GNUNET_STATISTICS_update (stats,
2450 ax_msg->PNs = htonl (t->ax.PNs); 3221 "# encrypted bytes",
2451 GNUNET_CRYPTO_ecdhe_key_get_public (t->ax.DHRs, 3222 payload_size,
2452 &ax_msg->DHRs); 3223 GNUNET_NO);
2453 t_h_encrypt (t, 3224 ax_msg->ax_header.Ns = htonl (t->ax.Ns++);
3225 ax_msg->ax_header.PNs = htonl (t->ax.PNs);
3226 /* FIXME: we should do this once, not once per message;
3227 this is a point multiplication, and DHRs does not
3228 change all the time. */
3229 GNUNET_CRYPTO_ecdhe_key_get_public (&t->ax.DHRs,
3230 &ax_msg->ax_header.DHRs);
3231 t_h_encrypt (&t->ax,
2454 ax_msg); 3232 ax_msg);
2455 t_hmac (&ax_msg->Ns, 3233 t_hmac (&ax_msg->ax_header,
2456 AX_HEADER_SIZE + payload_size, 3234 sizeof (struct GNUNET_CADET_AxHeader) + payload_size,
2457 0, 3235 0,
2458 &t->ax.HKs, 3236 &t->ax.HKs,
2459 &ax_msg->hmac); 3237 &ax_msg->hmac);
@@ -2510,11 +3288,23 @@ GCT_iterate_connections (struct CadetTunnel *t,
2510 GCT_ConnectionIterator iter, 3288 GCT_ConnectionIterator iter,
2511 void *iter_cls) 3289 void *iter_cls)
2512{ 3290{
2513 for (struct CadetTConnection *ct = t->connection_head; 3291 struct CadetTConnection *n;
3292 for (struct CadetTConnection *ct = t->connection_ready_head;
2514 NULL != ct; 3293 NULL != ct;
2515 ct = ct->next) 3294 ct = n)
3295 {
3296 n = ct->next;
3297 iter (iter_cls,
3298 ct);
3299 }
3300 for (struct CadetTConnection *ct = t->connection_busy_head;
3301 NULL != ct;
3302 ct = n)
3303 {
3304 n = ct->next;
2516 iter (iter_cls, 3305 iter (iter_cls,
2517 ct->cc); 3306 ct);
3307 }
2518} 3308}
2519 3309
2520 3310
@@ -2628,10 +3418,7 @@ GCT_debug (const struct CadetTunnel *t,
2628 GCT_2s (t), 3418 GCT_2s (t),
2629 estate2s (t->estate), 3419 estate2s (t->estate),
2630 t->tq_len, 3420 t->tq_len,
2631 t->num_connections); 3421 GCT_count_any_connections (t));
2632#if DUMP_KEYS_TO_STDERR
2633 ax_debug (t->ax, level);
2634#endif
2635 LOG2 (level, 3422 LOG2 (level,
2636 "TTT channels:\n"); 3423 "TTT channels:\n");
2637 GNUNET_CONTAINER_multihashmap32_iterate (t->channels, 3424 GNUNET_CONTAINER_multihashmap32_iterate (t->channels,
@@ -2639,7 +3426,10 @@ GCT_debug (const struct CadetTunnel *t,
2639 &level); 3426 &level);
2640 LOG2 (level, 3427 LOG2 (level,
2641 "TTT connections:\n"); 3428 "TTT connections:\n");
2642 for (iter_c = t->connection_head; NULL != iter_c; iter_c = iter_c->next) 3429 for (iter_c = t->connection_ready_head; NULL != iter_c; iter_c = iter_c->next)
3430 GCC_debug (iter_c->cc,
3431 level);
3432 for (iter_c = t->connection_busy_head; NULL != iter_c; iter_c = iter_c->next)
2643 GCC_debug (iter_c->cc, 3433 GCC_debug (iter_c->cc,
2644 level); 3434 level);
2645 3435
diff --git a/src/cadet/gnunet-service-cadet-new_tunnels.h b/src/cadet/gnunet-service-cadet_tunnels.h
index c867a9e82..4a3619ab6 100644
--- a/src/cadet/gnunet-service-cadet-new_tunnels.h
+++ b/src/cadet/gnunet-service-cadet_tunnels.h
@@ -20,7 +20,7 @@
20*/ 20*/
21 21
22/** 22/**
23 * @file cadet/gnunet-service-cadet-new_tunnels.h 23 * @file cadet/gnunet-service-cadet_tunnels.h
24 * @brief Information we track per tunnel. 24 * @brief Information we track per tunnel.
25 * @author Bartlomiej Polot 25 * @author Bartlomiej Polot
26 * @author Christian Grothoff 26 * @author Christian Grothoff
@@ -28,7 +28,7 @@
28#ifndef GNUNET_SERVICE_CADET_TUNNELS_H 28#ifndef GNUNET_SERVICE_CADET_TUNNELS_H
29#define GNUNET_SERVICE_CADET_TUNNELS_H 29#define GNUNET_SERVICE_CADET_TUNNELS_H
30 30
31#include "gnunet-service-cadet-new.h" 31#include "gnunet-service-cadet.h"
32#include "cadet_protocol.h" 32#include "cadet_protocol.h"
33 33
34 34
@@ -50,29 +50,36 @@ enum CadetTunnelEState
50 CADET_TUNNEL_KEY_UNINITIALIZED, 50 CADET_TUNNEL_KEY_UNINITIALIZED,
51 51
52 /** 52 /**
53 * Ephemeral key sent, waiting for peer's key. 53 * KX message sent, waiting for other peer's KX_AUTH.
54 */ 54 */
55 CADET_TUNNEL_KEY_SENT, 55 CADET_TUNNEL_KEY_AX_SENT,
56 56
57 /** 57 /**
58 * Key received and we sent ours back, but we got no traffic yet. 58 * KX message received, trying to send back KX_AUTH.
59 */
60 CADET_TUNNEL_KEY_AX_RECV,
61
62 /**
63 * KX message sent and received, trying to send back KX_AUTH.
64 */
65 CADET_TUNNEL_KEY_AX_SENT_AND_RECV,
66
67 /**
68 * KX received and we sent KX_AUTH back, but we got no traffic yet,
69 * so we're waiting for either KX_AUTH or ENCRYPED traffic from
70 * the other peer.
71 *
59 * We will not yet send traffic, as this might have been a replay. 72 * We will not yet send traffic, as this might have been a replay.
60 * The other (initiating) peer should send a CHANNEL_OPEN next 73 * The other (initiating) peer should send a CHANNEL_OPEN next
61 * anyway. 74 * anyway, and then we are in business!
62 */ 75 */
63 CADET_TUNNEL_KEY_PING, 76 CADET_TUNNEL_KEY_AX_AUTH_SENT,
64 77
65 /** 78 /**
66 * Handshake completed: session key available. 79 * Handshake completed: session key available.
67 */ 80 */
68 CADET_TUNNEL_KEY_OK, 81 CADET_TUNNEL_KEY_OK
69 82
70 /**
71 * New ephemeral key and ping sent, waiting for pong. Unlike KEY_PING,
72 * we still have a valid session key and therefore we *can* still send
73 * traffic on the tunnel.
74 */
75 CADET_TUNNEL_KEY_REKEY
76}; 83};
77 84
78 85
@@ -112,15 +119,29 @@ GCT_destroy_tunnel_now (struct CadetTunnel *t);
112 * 119 *
113 * @param t a tunnel 120 * @param t a tunnel
114 * @param cid connection identifer to use for the connection 121 * @param cid connection identifer to use for the connection
122 * @param options options for the connection
115 * @param path path to use for the connection 123 * @param path path to use for the connection
124 * @return #GNUNET_OK on success,
125 * #GNUNET_SYSERR on failure (duplicate connection)
116 */ 126 */
117void 127int
118GCT_add_inbound_connection (struct CadetTunnel *t, 128GCT_add_inbound_connection (struct CadetTunnel *t,
119 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid, 129 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
130 enum GNUNET_CADET_ChannelOption options,
120 struct CadetPeerPath *path); 131 struct CadetPeerPath *path);
121 132
122 133
123/** 134/**
135 * We lost a connection, remove it from our list and clean up
136 * the connection object itself.
137 *
138 * @param ct binding of connection to tunnel of the connection that was lost.
139 */
140void
141GCT_connection_lost (struct CadetTConnection *ct);
142
143
144/**
124 * Return the peer to which this tunnel goes. 145 * Return the peer to which this tunnel goes.
125 * 146 *
126 * @param t a tunnel 147 * @param t a tunnel
@@ -181,6 +202,19 @@ GCT_send_channel_destroy (struct CadetTunnel *t,
181 202
182 203
183/** 204/**
205 * Function called when a transmission requested using #GCT_send is done.
206 *
207 * @param cls closure
208 * @param ctn identifier of the connection used for transmission, NULL if
209 * the transmission failed (to be used to match ACKs to the
210 * respective connection for connection performance evaluation)
211 */
212typedef void
213(*GCT_SendContinuation)(void *cls,
214 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid);
215
216
217/**
184 * Sends an already built message on a tunnel, encrypting it and 218 * Sends an already built message on a tunnel, encrypting it and
185 * choosing the best connection if not provided. 219 * choosing the best connection if not provided.
186 * 220 *
@@ -188,12 +222,12 @@ GCT_send_channel_destroy (struct CadetTunnel *t,
188 * @param t Tunnel on which this message is transmitted. 222 * @param t Tunnel on which this message is transmitted.
189 * @param cont Continuation to call once message is really sent. 223 * @param cont Continuation to call once message is really sent.
190 * @param cont_cls Closure for @c cont. 224 * @param cont_cls Closure for @c cont.
191 * @return Handle to cancel message. NULL if @c cont is NULL. 225 * @return Handle to cancel message.
192 */ 226 */
193struct CadetTunnelQueueEntry * 227struct CadetTunnelQueueEntry *
194GCT_send (struct CadetTunnel *t, 228GCT_send (struct CadetTunnel *t,
195 const struct GNUNET_MessageHeader *message, 229 const struct GNUNET_MessageHeader *message,
196 GNUNET_SCHEDULER_TaskCallback cont, 230 GCT_SendContinuation cont,
197 void *cont_cls); 231 void *cont_cls);
198 232
199 233
@@ -227,18 +261,18 @@ GCT_count_channels (struct CadetTunnel *t);
227 * @return number of connections available for the tunnel 261 * @return number of connections available for the tunnel
228 */ 262 */
229unsigned int 263unsigned int
230GCT_count_any_connections (struct CadetTunnel *t); 264GCT_count_any_connections (const struct CadetTunnel *t);
231 265
232 266
233/** 267/**
234 * Iterator over connections. 268 * Iterator over connections.
235 * 269 *
236 * @param cls closure 270 * @param cls closure
237 * @param c one of the connections 271 * @param ct one of the connections
238 */ 272 */
239typedef void 273typedef void
240(*GCT_ConnectionIterator) (void *cls, 274(*GCT_ConnectionIterator) (void *cls,
241 struct CadetConnection *c); 275 struct CadetTConnection *ct);
242 276
243 277
244/** 278/**
@@ -301,6 +335,17 @@ GCT_handle_kx (struct CadetTConnection *ct,
301 335
302 336
303/** 337/**
338 * Handle KX_AUTH message.
339 *
340 * @param ct connection/tunnel combo that received encrypted message
341 * @param msg the key exchange message
342 */
343void
344GCT_handle_kx_auth (struct CadetTConnection *ct,
345 const struct GNUNET_CADET_TunnelKeyExchangeAuthMessage *msg);
346
347
348/**
304 * Handle encrypted message. 349 * Handle encrypted message.
305 * 350 *
306 * @param ct connection/tunnel combo that received encrypted message 351 * @param ct connection/tunnel combo that received encrypted message
diff --git a/src/cadet/test_cadet.c b/src/cadet/test_cadet.c
index 3a1042eba..72df2203c 100644
--- a/src/cadet/test_cadet.c
+++ b/src/cadet/test_cadet.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2011 GNUnet e.V. 3 Copyright (C) 2011, 2017 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -19,8 +19,9 @@
19*/ 19*/
20/** 20/**
21 * @file cadet/test_cadet.c 21 * @file cadet/test_cadet.c
22 * 22 * @author Bart Polot
23 * @brief Test for the cadet service: retransmission of traffic. 23 * @author Christian Grothoff
24 * @brief Test for the cadet service using mq API.
24 */ 25 */
25#include <stdio.h> 26#include <stdio.h>
26#include "platform.h" 27#include "platform.h"
@@ -31,9 +32,20 @@
31 32
32 33
33/** 34/**
34 * How many messages to send 35 * Ugly workaround to unify data handlers on incoming and outgoing channels.
36 */
37struct CadetTestChannelWrapper
38{
39 /**
40 * Channel pointer.
41 */
42 struct GNUNET_CADET_Channel *ch;
43};
44
45/**
46 * How many messages to send by default.
35 */ 47 */
36#define TOTAL_PACKETS 500 /* Cannot exceed 64k! */ 48#define TOTAL_PACKETS 500 /* Cannot exceed 64k! */
37 49
38/** 50/**
39 * How long until we give up on connecting the peers? 51 * How long until we give up on connecting the peers?
@@ -41,7 +53,7 @@
41#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 120) 53#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 120)
42 54
43/** 55/**
44 * Time to wait for stuff that should be rather fast 56 * Time to wait by default for stuff that should be rather fast.
45 */ 57 */
46#define SHORT_TIME GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 20) 58#define SHORT_TIME GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 20)
47 59
@@ -64,7 +76,7 @@ static int test;
64/** 76/**
65 * String with test name 77 * String with test name
66 */ 78 */
67char *test_name; 79static char *test_name;
68 80
69/** 81/**
70 * Flag to send traffic leaf->root in speed tests to test BCK_ACK logic. 82 * Flag to send traffic leaf->root in speed tests to test BCK_ACK logic.
@@ -72,6 +84,16 @@ char *test_name;
72static int test_backwards = GNUNET_NO; 84static int test_backwards = GNUNET_NO;
73 85
74/** 86/**
87 * How many packets to send.
88 */
89static unsigned int total_packets;
90
91/**
92 * Time to wait for fast operations.
93 */
94static struct GNUNET_TIME_Relative short_time;
95
96/**
75 * How many events have happened 97 * How many events have happened
76 */ 98 */
77static int ok; 99static int ok;
@@ -79,32 +101,32 @@ static int ok;
79/** 101/**
80 * Number of events expected to conclude the test successfully. 102 * Number of events expected to conclude the test successfully.
81 */ 103 */
82int ok_goal; 104static int ok_goal;
83 105
84/** 106/**
85 * Size of each test packet 107 * Size of each test packet's payload
86 */ 108 */
87size_t size_payload = sizeof (struct GNUNET_MessageHeader) + sizeof (uint32_t); 109static size_t size_payload = sizeof (uint32_t);
88 110
89/** 111/**
90 * Operation to get peer ids. 112 * Operation to get peer ids.
91 */ 113 */
92struct GNUNET_TESTBED_Operation *t_op[2]; 114static struct GNUNET_TESTBED_Operation *t_op[2];
93 115
94/** 116/**
95 * Peer ids. 117 * Peer ids.
96 */ 118 */
97struct GNUNET_PeerIdentity *p_id[2]; 119static struct GNUNET_PeerIdentity *p_id[2];
98 120
99/** 121/**
100 * Port ID 122 * Port ID
101 */ 123 */
102struct GNUNET_HashCode port; 124static struct GNUNET_HashCode port;
103 125
104/** 126/**
105 * Peer ids counter. 127 * Peer ids counter.
106 */ 128 */
107unsigned int p_ids; 129static unsigned int p_ids;
108 130
109/** 131/**
110 * Is the setup initialized? 132 * Is the setup initialized?
@@ -157,9 +179,9 @@ static struct GNUNET_SCHEDULER_Task *disconnect_task;
157static struct GNUNET_SCHEDULER_Task *test_task; 179static struct GNUNET_SCHEDULER_Task *test_task;
158 180
159/** 181/**
160 * Task runnining #data_task(). 182 * Task runnining #send_next_msg().
161 */ 183 */
162static struct GNUNET_SCHEDULER_Task *data_job; 184static struct GNUNET_SCHEDULER_Task *send_next_msg_task;
163 185
164/** 186/**
165 * Cadet handle for the root peer 187 * Cadet handle for the root peer
@@ -174,7 +196,7 @@ static struct GNUNET_CADET_Handle *h2;
174/** 196/**
175 * Channel handle for the root peer 197 * Channel handle for the root peer
176 */ 198 */
177static struct GNUNET_CADET_Channel *ch; 199static struct GNUNET_CADET_Channel *outgoing_ch;
178 200
179/** 201/**
180 * Channel handle for the dest peer 202 * Channel handle for the dest peer
@@ -182,17 +204,6 @@ static struct GNUNET_CADET_Channel *ch;
182static struct GNUNET_CADET_Channel *incoming_ch; 204static struct GNUNET_CADET_Channel *incoming_ch;
183 205
184/** 206/**
185 * Transmit handle for root data calls
186 */
187static struct GNUNET_CADET_TransmitHandle *th;
188
189/**
190 * Transmit handle for root data calls
191 */
192static struct GNUNET_CADET_TransmitHandle *incoming_th;
193
194
195/**
196 * Time we started the data transmission (after channel has been established 207 * Time we started the data transmission (after channel has been established
197 * and initilized). 208 * and initilized).
198 */ 209 */
@@ -218,21 +229,32 @@ static unsigned int ka_sent;
218 */ 229 */
219static unsigned int ka_received; 230static unsigned int ka_received;
220 231
232/**
233 * How many messages were dropped by CADET because of full buffers?
234 */
235static unsigned int msg_dropped;
236
237
238/******************************************************************************/
239
240
241/******************************************************************************/
242
221 243
222/** 244/**
223 * Get the client number considered as the "target" or "receiver", depending on 245 * Get the channel considered as the "target" or "receiver", depending on
224 * the test type and size. 246 * the test type and size.
225 * 247 *
226 * @return Peer # of the target client, either 0 (for backward tests) or 248 * @return Channel handle of the target client, either 0 (for backward tests)
227 * the last peer in the line (for other tests). 249 * or the last peer in the line (for other tests).
228 */ 250 */
229static unsigned int 251static struct GNUNET_CADET_Channel *
230get_expected_target () 252get_target_channel ()
231{ 253{
232 if (SPEED == test && GNUNET_YES == test_backwards) 254 if (SPEED == test && GNUNET_YES == test_backwards)
233 return 0; 255 return outgoing_ch;
234 else 256 else
235 return peers_requested - 1; 257 return incoming_ch;
236} 258}
237 259
238 260
@@ -245,18 +267,15 @@ show_end_data (void)
245 static struct GNUNET_TIME_Absolute end_time; 267 static struct GNUNET_TIME_Absolute end_time;
246 static struct GNUNET_TIME_Relative total_time; 268 static struct GNUNET_TIME_Relative total_time;
247 269
248 end_time = GNUNET_TIME_absolute_get(); 270 end_time = GNUNET_TIME_absolute_get ();
249 total_time = GNUNET_TIME_absolute_get_difference(start_time, end_time); 271 total_time = GNUNET_TIME_absolute_get_difference (start_time, end_time);
250 FPRINTF (stderr, "\nResults of test \"%s\"\n", test_name); 272 FPRINTF (stderr, "\nResults of test \"%s\"\n", test_name);
251 FPRINTF (stderr, "Test time %s\n", 273 FPRINTF (stderr, "Test time %s\n",
252 GNUNET_STRINGS_relative_time_to_string (total_time, 274 GNUNET_STRINGS_relative_time_to_string (total_time, GNUNET_YES));
253 GNUNET_YES)); 275 FPRINTF (stderr, "Test bandwidth: %f kb/s\n", 4 * total_packets * 1.0 / (total_time.rel_value_us / 1000)); // 4bytes * ms
254 FPRINTF (stderr, "Test bandwidth: %f kb/s\n", 276 FPRINTF (stderr, "Test throughput: %f packets/s\n\n", total_packets * 1000.0 / (total_time.rel_value_us / 1000)); // packets * ms
255 4 * TOTAL_PACKETS * 1.0 / (total_time.rel_value_us / 1000)); // 4bytes * ms
256 FPRINTF (stderr, "Test throughput: %f packets/s\n\n",
257 TOTAL_PACKETS * 1000.0 / (total_time.rel_value_us / 1000)); // packets * ms
258 GAUGER ("CADET", test_name, 277 GAUGER ("CADET", test_name,
259 TOTAL_PACKETS * 1000.0 / (total_time.rel_value_us / 1000), 278 total_packets * 1000.0 / (total_time.rel_value_us / 1000),
260 "packets/s"); 279 "packets/s");
261} 280}
262 281
@@ -275,29 +294,19 @@ disconnect_cadet_peers (void *cls)
275 294
276 disconnect_task = NULL; 295 disconnect_task = NULL;
277 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 296 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
278 "disconnecting cadet service of peers, called from line %ld\n", 297 "disconnecting cadet service of peers, called from line %ld\n",
279 line); 298 line);
280 for (i = 0; i < 2; i++) 299 for (i = 0; i < 2; i++)
281 { 300 {
282 GNUNET_TESTBED_operation_done (t_op[i]); 301 GNUNET_TESTBED_operation_done (t_op[i]);
283 } 302 }
284 if (NULL != ch) 303 if (NULL != outgoing_ch)
285 { 304 {
286 if (NULL != th) 305 GNUNET_CADET_channel_destroy (outgoing_ch);
287 { 306 outgoing_ch = NULL;
288 GNUNET_CADET_notify_transmit_ready_cancel (th);
289 th = NULL;
290 }
291 GNUNET_CADET_channel_destroy (ch);
292 ch = NULL;
293 } 307 }
294 if (NULL != incoming_ch) 308 if (NULL != incoming_ch)
295 { 309 {
296 if (NULL != incoming_th)
297 {
298 GNUNET_CADET_notify_transmit_ready_cancel (incoming_th);
299 incoming_th = NULL;
300 }
301 GNUNET_CADET_channel_destroy (incoming_ch); 310 GNUNET_CADET_channel_destroy (incoming_ch);
302 incoming_ch = NULL; 311 incoming_ch = NULL;
303 } 312 }
@@ -316,10 +325,10 @@ static void
316shutdown_task (void *cls) 325shutdown_task (void *cls)
317{ 326{
318 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ending test.\n"); 327 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ending test.\n");
319 if (NULL != data_job) 328 if (NULL != send_next_msg_task)
320 { 329 {
321 GNUNET_SCHEDULER_cancel (data_job); 330 GNUNET_SCHEDULER_cancel (send_next_msg_task);
322 data_job = NULL; 331 send_next_msg_task = NULL;
323 } 332 }
324 if (NULL != test_task) 333 if (NULL != test_task)
325 { 334 {
@@ -329,8 +338,8 @@ shutdown_task (void *cls)
329 if (NULL != disconnect_task) 338 if (NULL != disconnect_task)
330 { 339 {
331 GNUNET_SCHEDULER_cancel (disconnect_task); 340 GNUNET_SCHEDULER_cancel (disconnect_task);
332 disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_cadet_peers, 341 disconnect_task =
333 (void *) __LINE__); 342 GNUNET_SCHEDULER_add_now (&disconnect_cadet_peers, (void *) __LINE__);
334 } 343 }
335} 344}
336 345
@@ -349,14 +358,16 @@ stats_cont (void *cls, struct GNUNET_TESTBED_Operation *op, const char *emsg)
349{ 358{
350 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " KA sent: %u, KA received: %u\n", 359 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " KA sent: %u, KA received: %u\n",
351 ka_sent, ka_received); 360 ka_sent, ka_received);
352 if (KEEPALIVE == test && (ka_sent < 2 || ka_sent > ka_received + 1)) 361 if ((KEEPALIVE == test) && ((ka_sent < 2) || (ka_sent > ka_received + 1)))
362 {
363 GNUNET_break (0);
353 ok--; 364 ok--;
365 }
354 GNUNET_TESTBED_operation_done (stats_op); 366 GNUNET_TESTBED_operation_done (stats_op);
355 367
356 if (NULL != disconnect_task) 368 if (NULL != disconnect_task)
357 GNUNET_SCHEDULER_cancel (disconnect_task); 369 GNUNET_SCHEDULER_cancel (disconnect_task);
358 disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_cadet_peers, 370 disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_cadet_peers, cls);
359 cls);
360} 371}
361 372
362 373
@@ -372,29 +383,27 @@ stats_cont (void *cls, struct GNUNET_TESTBED_Operation *op, const char *emsg)
372 * @return #GNUNET_OK to continue, #GNUNET_SYSERR to abort iteration 383 * @return #GNUNET_OK to continue, #GNUNET_SYSERR to abort iteration
373 */ 384 */
374static int 385static int
375stats_iterator (void *cls, 386stats_iterator (void *cls, const struct GNUNET_TESTBED_Peer *peer,
376 const struct GNUNET_TESTBED_Peer *peer, 387 const char *subsystem, const char *name, uint64_t value,
377 const char *subsystem,
378 const char *name,
379 uint64_t value,
380 int is_persistent) 388 int is_persistent)
381{ 389{
382 static const char *s_sent = "# keepalives sent"; 390 static const char *s_sent = "# keepalives sent";
383 static const char *s_recv = "# keepalives received"; 391 static const char *s_recv = "# keepalives received";
392 static const char *rdrops = "# messages dropped due to full buffer";
393 static const char *cdrops = "# messages dropped due to slow client";
384 uint32_t i; 394 uint32_t i;
385 395
386 i = GNUNET_TESTBED_get_index (peer); 396 i = GNUNET_TESTBED_get_index (peer);
387 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 397 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "STATS PEER %u - %s [%s]: %llu\n", i,
388 "STATS PEER %u - %s [%s]: %llu\n", 398 subsystem, name, (unsigned long long) value);
389 i,
390 subsystem,
391 name,
392 (unsigned long long) value);
393 if (0 == strncmp (s_sent, name, strlen (s_sent)) && 0 == i) 399 if (0 == strncmp (s_sent, name, strlen (s_sent)) && 0 == i)
394 ka_sent = value; 400 ka_sent = value;
395 401 if (0 == strncmp (s_recv, name, strlen (s_recv)) && peers_requested - 1 == i)
396 if (0 == strncmp(s_recv, name, strlen (s_recv)) && peers_requested - 1 == i)
397 ka_received = value; 402 ka_received = value;
403 if (0 == strncmp (rdrops, name, strlen (rdrops)))
404 msg_dropped += value;
405 if (0 == strncmp (cdrops, name, strlen (cdrops)))
406 msg_dropped += value;
398 407
399 return GNUNET_OK; 408 return GNUNET_OK;
400} 409}
@@ -403,7 +412,7 @@ stats_iterator (void *cls,
403/** 412/**
404 * Task to gather all statistics. 413 * Task to gather all statistics.
405 * 414 *
406 * @param cls Closure (NULL). 415 * @param cls Closure (line from which the task was scheduled).
407 */ 416 */
408static void 417static void
409gather_stats_and_exit (void *cls) 418gather_stats_and_exit (void *cls)
@@ -412,21 +421,20 @@ gather_stats_and_exit (void *cls)
412 421
413 disconnect_task = NULL; 422 disconnect_task = NULL;
414 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 423 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
415 "gathering statistics from line %d\n", 424 "gathering statistics from line %ld\n",
416 (int) l); 425 l);
417 if (NULL != ch) 426 if (NULL != outgoing_ch)
418 { 427 {
419 if (NULL != th) 428 GNUNET_CADET_channel_destroy (outgoing_ch);
420 { 429 outgoing_ch = NULL;
421 GNUNET_CADET_notify_transmit_ready_cancel (th);
422 th = NULL;
423 }
424 GNUNET_CADET_channel_destroy (ch);
425 ch = NULL;
426 } 430 }
427 stats_op = GNUNET_TESTBED_get_statistics (peers_running, testbed_peers, 431 stats_op = GNUNET_TESTBED_get_statistics (peers_running,
428 "cadet", NULL, 432 testbed_peers,
429 stats_iterator, stats_cont, cls); 433 "cadet",
434 NULL,
435 &stats_iterator,
436 stats_cont,
437 cls);
430} 438}
431 439
432 440
@@ -439,165 +447,154 @@ gather_stats_and_exit (void *cls)
439static void 447static void
440abort_test (long line) 448abort_test (long line)
441{ 449{
442 if (disconnect_task != NULL) 450 if (NULL != disconnect_task)
443 { 451 {
444 GNUNET_SCHEDULER_cancel (disconnect_task); 452 GNUNET_SCHEDULER_cancel (disconnect_task);
445 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Aborting test from %ld\n", line); 453 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Aborting test from %ld\n", line);
446 disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_cadet_peers, 454 disconnect_task =
447 (void *) line); 455 GNUNET_SCHEDULER_add_now (&disconnect_cadet_peers, (void *) line);
448 } 456 }
449} 457}
450 458
451/**
452 * Transmit ready callback.
453 *
454 * @param cls Closure (message type).
455 * @param size Size of the tranmist buffer.
456 * @param buf Pointer to the beginning of the buffer.
457 *
458 * @return Number of bytes written to buf.
459 */
460static size_t
461tmt_rdy (void *cls, size_t size, void *buf);
462
463 459
464/** 460/**
465 * Task to request a new data transmission. 461 * Send a message on the channel with the appropriate size and payload.
462 *
463 * Update the appropriate *_sent counter.
466 * 464 *
467 * @param cls Closure (peer #). 465 * @param channel Channel to send the message on.
468 */ 466 */
469static void 467static void
470data_task (void *cls) 468send_test_message (struct GNUNET_CADET_Channel *channel)
471{ 469{
472 struct GNUNET_CADET_Channel *channel; 470 struct GNUNET_MQ_Envelope *env;
473 static struct GNUNET_CADET_TransmitHandle **pth; 471 struct GNUNET_MessageHeader *msg;
474 long src; 472 uint32_t *data;
473 int payload;
474 int size;
475 475
476 data_job = NULL; 476 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
477 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Data task\n"); 477 "Sending test message on channel %p\n",
478 if (GNUNET_YES == test_backwards) 478 channel);
479 { 479 size = size_payload;
480 channel = incoming_ch; 480 if (GNUNET_NO == initialized)
481 pth = &incoming_th;
482 src = peers_requested - 1;
483 }
484 else
485 { 481 {
486 channel = ch; 482 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending INITIALIZER\n");
487 pth = &th; 483 size += 1000;
488 src = 0; 484 payload = data_sent;
485 if (SPEED_ACK == test) // FIXME unify SPEED_ACK with an initializer
486 data_sent++;
489 } 487 }
490 488 else if (SPEED == test || SPEED_ACK == test)
491 GNUNET_assert (NULL != channel);
492 GNUNET_assert (NULL == *pth);
493
494 *pth = GNUNET_CADET_notify_transmit_ready (channel, GNUNET_NO,
495 GNUNET_TIME_UNIT_FOREVER_REL,
496 size_payload + data_sent,
497 &tmt_rdy, (void *) src);
498 if (NULL == *pth)
499 { 489 {
500 unsigned long i = (unsigned long) cls; 490 if (get_target_channel() == channel)
501
502 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Retransmission\n");
503 if (0 == i)
504 { 491 {
505 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, " in 1 ms\n"); 492 payload = ack_sent;
506 data_job = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MILLISECONDS, 493 size += ack_sent;
507 &data_task, (void *) 1L); 494 ack_sent++;
495 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
496 "Sending ACK %u [%d bytes]\n",
497 payload, size);
508 } 498 }
509 else 499 else
510 { 500 {
511 i++; 501 payload = data_sent;
512 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 502 size += data_sent;
513 "in %llu ms\n", 503 data_sent++;
514 (unsigned long long) i); 504 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
515 data_job = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 505 "Sending DATA %u [%d bytes]\n",
516 i), 506 data_sent, size);
517 &data_task, (void *) i);
518 } 507 }
519 } 508 }
520} 509 else if (FORWARD == test)
510 {
511 payload = ack_sent;
512 }
513 else if (P2P_SIGNAL == test)
514 {
515 payload = data_sent;
516 }
517 else
518 {
519 GNUNET_assert (0);
520 }
521 env = GNUNET_MQ_msg_extra (msg, size, GNUNET_MESSAGE_TYPE_DUMMY);
521 522
523 data = (uint32_t *) &msg[1];
524 *data = htonl (payload);
525 GNUNET_MQ_send (GNUNET_CADET_get_mq (channel), env);
526}
522 527
523/** 528/**
524 * Transmit ready callback 529 * Task to request a new data transmission in a SPEED test, without waiting
530 * for previous messages to be sent/arrrive.
525 * 531 *
526 * @param cls Closure (peer # which is sending the data). 532 * @param cls Closure (unused).
527 * @param size Size of the buffer we have.
528 * @param buf Buffer to copy data to.
529 */ 533 */
530static size_t 534static void
531tmt_rdy (void *cls, size_t size, void *buf) 535send_next_msg (void *cls)
532{ 536{
533 struct GNUNET_MessageHeader *msg = buf; 537 struct GNUNET_CADET_Channel *channel;
534 size_t msg_size;
535 uint32_t *data;
536 long id = (long) cls;
537 unsigned int counter;
538 538
539 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 539 send_next_msg_task = NULL;
540 "tmt_rdy on %ld, filling buffer\n", 540 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending next message: %d\n", data_sent);
541 id); 541
542 if (0 == id) 542 channel = GNUNET_YES == test_backwards ? incoming_ch : outgoing_ch;
543 th = NULL; 543 GNUNET_assert (NULL != channel);
544 else if ((peers_requested - 1) == id) 544 GNUNET_assert (SPEED == test);
545 incoming_th = NULL; 545 send_test_message (channel);
546 else 546 if (data_sent < total_packets)
547 GNUNET_assert (0);
548 counter = get_expected_target () == id ? ack_sent : data_sent;
549 msg_size = size_payload + counter;
550 GNUNET_assert (msg_size > sizeof (struct GNUNET_MessageHeader));
551 if ( (size < msg_size) ||
552 (NULL == buf) )
553 {
554 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
555 "size %u, buf %p, data_sent %u, ack_received %u\n",
556 (unsigned int) size,
557 buf,
558 data_sent,
559 ack_received);
560 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ok %u, ok goal %u\n", ok, ok_goal);
561 GNUNET_break (ok >= ok_goal - 2);
562
563 return 0;
564 }
565 msg->size = htons (msg_size);
566 msg->type = htons (GNUNET_MESSAGE_TYPE_DUMMY);
567 data = (uint32_t *) &msg[1];
568 *data = htonl (counter);
569 if (GNUNET_NO == initialized)
570 { 547 {
548 /* SPEED test: Send all messages as soon as possible */
571 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 549 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
572 "sending initializer\n"); 550 "Scheduling message %d\n",
573 msg_size = size_payload + 1000; 551 data_sent + 1);
574 msg->size = htons (msg_size); 552 send_next_msg_task =
575 if (SPEED_ACK == test) 553 GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_UNIT_SECONDS,
576 data_sent++; 554 &send_next_msg,
555 NULL);
577 } 556 }
578 else if ( (SPEED == test) || 557}
579 (SPEED_ACK == test) ) 558
559
560/**
561 * Every few messages cancel the timeout task and re-schedule it again, to
562 * avoid timing out when traffic keeps coming.
563 *
564 * @param line Code line number to log if a timeout occurs.
565 */
566static void
567reschedule_timeout_task (long line)
568{
569 if ((ok % 10) == 0)
580 { 570 {
581 if (get_expected_target() == id) 571 if (NULL != disconnect_task)
582 ack_sent++;
583 else
584 data_sent++;
585 counter++;
586 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
587 " Sent message %u size %u\n",
588 counter,
589 (unsigned int) msg_size);
590 if ( (data_sent < TOTAL_PACKETS) &&
591 (SPEED == test) )
592 { 572 {
593 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 573 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
594 " Scheduling message %d\n", 574 " reschedule timeout every 10 messages\n");
595 counter + 1); 575 GNUNET_SCHEDULER_cancel (disconnect_task);
596 data_job = GNUNET_SCHEDULER_add_now (&data_task, NULL); 576 disconnect_task = GNUNET_SCHEDULER_add_delayed (short_time,
577 &gather_stats_and_exit,
578 (void *) line);
597 } 579 }
598 } 580 }
581}
599 582
600 return msg_size; 583
584/**
585 * Check if payload is sane (size contains payload).
586 *
587 * @param cls should match #ch
588 * @param message The actual message.
589 * @return #GNUNET_OK to keep the channel open,
590 * #GNUNET_SYSERR to close it (signal serious error).
591 */
592static int
593check_data (void *cls, const struct GNUNET_MessageHeader *message)
594{
595 if (sizeof (struct GNUNET_MessageHeader) >= ntohs (message->size))
596 return GNUNET_SYSERR;
597 return GNUNET_OK; /* all is well-formed */
601} 598}
602 599
603 600
@@ -605,75 +602,50 @@ tmt_rdy (void *cls, size_t size, void *buf)
605 * Function is called whenever a message is received. 602 * Function is called whenever a message is received.
606 * 603 *
607 * @param cls closure (set from GNUNET_CADET_connect(), peer number) 604 * @param cls closure (set from GNUNET_CADET_connect(), peer number)
608 * @param channel connection to the other end
609 * @param channel_ctx place to store local state associated with the channel
610 * @param message the actual message 605 * @param message the actual message
611 * @return #GNUNET_OK to keep the connection open,
612 * #GNUNET_SYSERR to close it (signal serious error)
613 */ 606 */
614static int 607static void
615data_callback (void *cls, 608handle_data (void *cls, const struct GNUNET_MessageHeader *message)
616 struct GNUNET_CADET_Channel *channel,
617 void **channel_ctx,
618 const struct GNUNET_MessageHeader *message)
619{ 609{
620 struct GNUNET_CADET_TransmitHandle **pth; 610 struct CadetTestChannelWrapper *ch = cls;
621 long client = (long) cls; 611 struct GNUNET_CADET_Channel *channel = ch->ch;
622 long expected_target_client;
623 uint32_t *data; 612 uint32_t *data;
624 uint32_t payload; 613 uint32_t payload;
625 unsigned int counter; 614 int *counter;
626 615
627 ok++; 616 ok++;
628 counter = get_expected_target () == client ? data_received : ack_received;
629
630 GNUNET_CADET_receive_done (channel); 617 GNUNET_CADET_receive_done (channel);
618 counter = get_target_channel () == channel ? &data_received : &ack_received;
631 619
632 if ((ok % 10) == 0) 620 reschedule_timeout_task ((long) __LINE__);
621
622 if (channel == outgoing_ch)
633 { 623 {
634 if (NULL != disconnect_task) 624 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Root client got a message.\n");
635 {
636 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
637 " reschedule timeout\n");
638 GNUNET_SCHEDULER_cancel (disconnect_task);
639 disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME,
640 &gather_stats_and_exit,
641 (void *) __LINE__);
642 }
643 } 625 }
644 626 else if (channel == incoming_ch)
645 switch (client) 627 {
628 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Leaf client got a message.\n");
629 }
630 else
646 { 631 {
647 case 0L: 632 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unknown channel %p.\n", channel);
648 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Root client got a message!\n");
649 GNUNET_assert (channel == ch);
650 pth = &th;
651 break;
652 case 1L:
653 case 4L:
654 GNUNET_assert (client == peers_requested - 1);
655 GNUNET_assert (channel == incoming_ch);
656 pth = &incoming_th;
657 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Leaf client %ld got a message.\n",
658 client);
659 break;
660 default:
661 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Client %ld not valid.\n", client);
662 GNUNET_assert (0); 633 GNUNET_assert (0);
663 } 634 }
635
664 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " ok: (%d/%d)\n", ok, ok_goal); 636 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " ok: (%d/%d)\n", ok, ok_goal);
665 data = (uint32_t *) &message[1]; 637 data = (uint32_t *) &message[1];
666 payload = ntohl (*data); 638 payload = ntohl (*data);
667 if (payload == counter) 639 if (payload == *counter)
668 { 640 {
669 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " payload as expected: %u\n", payload); 641 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " payload as expected: %u\n", payload);
670 } 642 }
671 else 643 else
672 { 644 {
673 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, " payload %u, expected: %u\n", 645 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
674 payload, counter); 646 " payload %u, expected: %u\n",
647 payload, *counter);
675 } 648 }
676 expected_target_client = get_expected_target ();
677 649
678 if (GNUNET_NO == initialized) 650 if (GNUNET_NO == initialized)
679 { 651 {
@@ -681,188 +653,152 @@ data_callback (void *cls,
681 start_time = GNUNET_TIME_absolute_get (); 653 start_time = GNUNET_TIME_absolute_get ();
682 if (SPEED == test) 654 if (SPEED == test)
683 { 655 {
684 GNUNET_assert (peers_requested - 1 == client); 656 GNUNET_assert (incoming_ch == channel);
685 data_job = GNUNET_SCHEDULER_add_now (&data_task, NULL); 657 send_next_msg_task = GNUNET_SCHEDULER_add_now (&send_next_msg, NULL);
686 return GNUNET_OK; 658 return;
687 } 659 }
688 } 660 }
689 661
690 counter++; 662 (*counter)++;
691 if (client == expected_target_client) /* Normally 4 */ 663 if (get_target_channel () == channel) /* Got "data" */
692 { 664 {
693 data_received++;
694 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " received data %u\n", data_received); 665 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " received data %u\n", data_received);
695 if (SPEED != test || (ok_goal - 2) == ok) 666 if (SPEED != test || (ok_goal - 2) == ok)
696 { 667 {
697 /* Send ACK */ 668 /* Send ACK */
698 GNUNET_assert (NULL == *pth); 669 send_test_message (channel);
699 *pth = GNUNET_CADET_notify_transmit_ready (channel, GNUNET_NO, 670 return;
700 GNUNET_TIME_UNIT_FOREVER_REL,
701 size_payload + ack_sent,
702 &tmt_rdy, (void *) client);
703 return GNUNET_OK;
704 } 671 }
705 else 672 else
706 { 673 {
707 if (data_received < TOTAL_PACKETS) 674 if (data_received < total_packets)
708 return GNUNET_OK; 675 return;
709 } 676 }
710 } 677 }
711 else /* Normally 0 */ 678 else /* Got "ack" */
712 { 679 {
713 if (SPEED_ACK == test || SPEED == test) 680 if (SPEED_ACK == test || SPEED == test)
714 { 681 {
715 ack_received++;
716 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " received ack %u\n", ack_received); 682 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " received ack %u\n", ack_received);
717 /* send more data */ 683 /* Send more data */
718 GNUNET_assert (NULL == *pth); 684 send_test_message (channel);
719 *pth = GNUNET_CADET_notify_transmit_ready (channel, GNUNET_NO, 685 if (ack_received < total_packets && SPEED != test)
720 GNUNET_TIME_UNIT_FOREVER_REL, 686 return;
721 size_payload + data_sent,
722 &tmt_rdy, (void *) client);
723 if (ack_received < TOTAL_PACKETS && SPEED != test)
724 return GNUNET_OK;
725 if (ok == 2 && SPEED == test) 687 if (ok == 2 && SPEED == test)
726 return GNUNET_OK; 688 return;
727 show_end_data(); 689 show_end_data ();
728 } 690 }
729 if (test == P2P_SIGNAL) 691 if (test == P2P_SIGNAL)
730 { 692 {
731 if (NULL != incoming_th)
732 {
733 GNUNET_CADET_notify_transmit_ready_cancel (incoming_th);
734 incoming_th = NULL;
735 }
736 GNUNET_CADET_channel_destroy (incoming_ch); 693 GNUNET_CADET_channel_destroy (incoming_ch);
737 incoming_ch = NULL; 694 incoming_ch = NULL;
738 } 695 }
739 else 696 else
740 { 697 {
741 if (NULL != th) 698 GNUNET_CADET_channel_destroy (outgoing_ch);
742 { 699 outgoing_ch = NULL;
743 GNUNET_CADET_notify_transmit_ready_cancel (th);
744 th = NULL;
745 }
746 GNUNET_CADET_channel_destroy (ch);
747 ch = NULL;
748 } 700 }
749 } 701 }
750
751 return GNUNET_OK;
752} 702}
753 703
754 704
755/** 705/**
756 * Data handlers for every message type of CADET's payload. 706 * Method called whenever a peer connects to a port in MQ-based CADET.
757 * {callback_function, message_type, size_expected}
758 */
759static struct GNUNET_CADET_MessageHandler handlers[] = {
760 {&data_callback,
761 GNUNET_MESSAGE_TYPE_DUMMY,
762 sizeof (struct GNUNET_MessageHeader)},
763 {NULL, 0, 0}
764};
765
766
767/**
768 * Method called whenever another peer has added us to a channel
769 * the other peer initiated.
770 * 707 *
771 * @param cls Closure. 708 * @param cls Closure from #GNUNET_CADET_open_port (peer # as long).
772 * @param channel New handle to the channel. 709 * @param channel New handle to the channel.
773 * @param initiator Peer that started the channel. 710 * @param source Peer that started this channel.
774 * @param port Port this channel is connected to. 711 * @return Closure for the incoming @a channel. It's given to:
775 * @param options channel option flags 712 * - The #GNUNET_CADET_DisconnectEventHandler (given to
776 * @return Initial channel context for the channel 713 * #GNUNET_CADET_open_port) when the channel dies.
777 * (can be NULL -- that's not an error). 714 * - Each the #GNUNET_MQ_MessageCallback handlers for each message
715 * received on the @a channel.
778 */ 716 */
779static void * 717static void *
780incoming_channel (void *cls, 718connect_handler (void *cls, struct GNUNET_CADET_Channel *channel,
781 struct GNUNET_CADET_Channel *channel, 719 const struct GNUNET_PeerIdentity *source)
782 const struct GNUNET_PeerIdentity *initiator,
783 const struct GNUNET_HashCode *port,
784 enum GNUNET_CADET_ChannelOption options)
785{ 720{
721 struct CadetTestChannelWrapper *ch;
722 long peer = (long) cls;
723
786 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 724 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
787 "Incoming channel from %s to peer %d:%s\n", 725 "Incoming channel from %s to %ld: %p\n",
788 GNUNET_i2s (initiator), 726 GNUNET_i2s (source), peer, channel);
789 (int) (long) cls, GNUNET_h2s (port));
790 ok++; 727 ok++;
791 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " ok: %d\n", ok); 728 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " ok: %d\n", ok);
792 if ((long) cls == peers_requested - 1) 729 if (peer == peers_requested - 1)
793 { 730 {
794 if (NULL != incoming_ch) 731 if (NULL != incoming_ch)
795 { 732 {
796 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 733 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
797 "Duplicate incoming channel for client %lu\n", 734 "Duplicate incoming channel for client %lu\n", (long) cls);
798 (long) cls); 735 GNUNET_assert (0);
799 GNUNET_break(0);
800 } 736 }
801 incoming_ch = channel; 737 incoming_ch = channel;
802 } 738 }
803 else 739 else
804 { 740 {
805 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 741 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
806 "Incoming channel for unknown client %lu\n", (long) cls); 742 "Incoming channel for unexpected peer #%lu\n", (long) cls);
807 GNUNET_break(0); 743 GNUNET_assert (0);
808 } 744 }
809 if (NULL != disconnect_task) 745 if (NULL != disconnect_task)
810 { 746 {
811 GNUNET_SCHEDULER_cancel (disconnect_task); 747 GNUNET_SCHEDULER_cancel (disconnect_task);
812 disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME, 748 disconnect_task = GNUNET_SCHEDULER_add_delayed (short_time,
813 &gather_stats_and_exit, 749 &gather_stats_and_exit,
814 (void *) __LINE__); 750 (void *) __LINE__);
815 } 751 }
816 752
817 return NULL; 753 /* TODO: cannot return channel as-is, in order to unify the data handlers */
754 ch = GNUNET_new (struct CadetTestChannelWrapper);
755 ch->ch = channel;
756
757 return ch;
818} 758}
819 759
820 760
821/** 761/**
822 * Function called whenever an inbound channel is destroyed. Should clean up 762 * Function called whenever an MQ-channel is destroyed, even if the destruction
823 * any associated state. 763 * was requested by #GNUNET_CADET_channel_destroy.
764 * It must NOT call #GNUNET_CADET_channel_destroy on the channel.
824 * 765 *
825 * @param cls closure (set from GNUNET_CADET_connect, peer number) 766 * It should clean up any associated state, including cancelling any pending
826 * @param channel connection to the other end (henceforth invalid) 767 * transmission on this channel.
827 * @param channel_ctx place where local state associated 768 *
828 * with the channel is stored 769 * @param cls Channel closure (channel wrapper).
770 * @param channel Connection to the other end (henceforth invalid).
829 */ 771 */
830static void 772static void
831channel_cleaner (void *cls, 773disconnect_handler (void *cls, const struct GNUNET_CADET_Channel *channel)
832 const struct GNUNET_CADET_Channel *channel,
833 void *channel_ctx)
834{ 774{
835 long i = (long) cls; 775 struct CadetTestChannelWrapper *ch_w = cls;
836 776
837 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 777 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Channel disconnected\n");
838 "Incoming channel disconnected at peer %ld\n", 778 GNUNET_assert (ch_w->ch == channel);
839 i); 779 if (channel == incoming_ch)
840 if (peers_running - 1 == i)
841 { 780 {
842 ok++; 781 ok++;
843 GNUNET_break (channel == incoming_ch);
844 incoming_ch = NULL; 782 incoming_ch = NULL;
845 } 783 }
846 else if (0L == i) 784 else if (outgoing_ch == channel
785 )
847 { 786 {
848 if (P2P_SIGNAL == test) 787 if (P2P_SIGNAL == test)
849 { 788 {
850 ok++; 789 ok++;
851 } 790 }
852 GNUNET_break (channel == ch); 791 outgoing_ch = NULL;
853 ch = NULL;
854 } 792 }
855 else 793 else
856 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 794 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Unknown channel! %p\n", channel);
857 "Unknown peer! %d\n",
858 (int) i);
859 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " ok: %d\n", ok); 795 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " ok: %d\n", ok);
860 796
861 if (NULL != disconnect_task) 797 if (NULL != disconnect_task)
862 { 798 {
863 GNUNET_SCHEDULER_cancel (disconnect_task); 799 GNUNET_SCHEDULER_cancel (disconnect_task);
864 disconnect_task = GNUNET_SCHEDULER_add_now (&gather_stats_and_exit, 800 disconnect_task =
865 (void *) __LINE__); 801 GNUNET_SCHEDULER_add_now (&gather_stats_and_exit, (void *) __LINE__);
866 } 802 }
867} 803}
868 804
@@ -876,13 +812,20 @@ channel_cleaner (void *cls,
876 * @param cls Closure (unused). 812 * @param cls Closure (unused).
877 */ 813 */
878static void 814static void
879do_test (void *cls) 815start_test (void *cls)
880{ 816{
817 struct GNUNET_MQ_MessageHandler handlers[] = {
818 GNUNET_MQ_hd_var_size (data,
819 GNUNET_MESSAGE_TYPE_DUMMY,
820 struct GNUNET_MessageHeader,
821 NULL),
822 GNUNET_MQ_handler_end ()
823 };
824 struct CadetTestChannelWrapper *ch;
881 enum GNUNET_CADET_ChannelOption flags; 825 enum GNUNET_CADET_ChannelOption flags;
882 826
883 test_task = NULL; 827 test_task = NULL;
884 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 828 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "start_test\n");
885 "do_test\n");
886 if (NULL != disconnect_task) 829 if (NULL != disconnect_task)
887 { 830 {
888 GNUNET_SCHEDULER_cancel (disconnect_task); 831 GNUNET_SCHEDULER_cancel (disconnect_task);
@@ -896,30 +839,33 @@ do_test (void *cls)
896 flags |= GNUNET_CADET_OPTION_RELIABLE; 839 flags |= GNUNET_CADET_OPTION_RELIABLE;
897 } 840 }
898 841
899 ch = GNUNET_CADET_channel_create (h1, 842 ch = GNUNET_new (struct CadetTestChannelWrapper);
900 NULL, 843 outgoing_ch = GNUNET_CADET_channel_create (h1,
901 p_id[1], 844 ch,
902 &port, 845 p_id[1],
903 flags); 846 &port,
847 flags,
848 NULL,
849 &disconnect_handler,
850 handlers);
904 851
905 disconnect_task 852 ch->ch = outgoing_ch;
906 = GNUNET_SCHEDULER_add_delayed (SHORT_TIME, 853
907 &gather_stats_and_exit, 854 disconnect_task = GNUNET_SCHEDULER_add_delayed (short_time,
908 (void *) __LINE__); 855 &gather_stats_and_exit,
856 (void *) __LINE__);
909 if (KEEPALIVE == test) 857 if (KEEPALIVE == test)
910 return; /* Don't send any data. */ 858 return; /* Don't send any data. */
859
911 860
912 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
913 "Sending data initializer...\n");
914 data_received = 0; 861 data_received = 0;
915 data_sent = 0; 862 data_sent = 0;
916 ack_received = 0; 863 ack_received = 0;
917 ack_sent = 0; 864 ack_sent = 0;
918 th = GNUNET_CADET_notify_transmit_ready (ch, 865 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
919 GNUNET_NO, 866 "Sending data initializer on channel %p...\n",
920 GNUNET_TIME_UNIT_FOREVER_REL, 867 outgoing_ch);
921 size_payload + 1000, 868 send_test_message (outgoing_ch);
922 &tmt_rdy, (void *) 0L);
923} 869}
924 870
925 871
@@ -933,35 +879,26 @@ do_test (void *cls)
933 * NULL if the operation is successfull 879 * NULL if the operation is successfull
934 */ 880 */
935static void 881static void
936pi_cb (void *cls, 882pi_cb (void *cls, struct GNUNET_TESTBED_Operation *op,
937 struct GNUNET_TESTBED_Operation *op, 883 const struct GNUNET_TESTBED_PeerInformation *pinfo, const char *emsg)
938 const struct GNUNET_TESTBED_PeerInformation *pinfo,
939 const char *emsg)
940{ 884{
941 long i = (long) cls; 885 long i = (long) cls;
942 886
943 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 887 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ID callback for %ld\n", i);
944 "id callback for %ld\n", i);
945 888
946 if ( (NULL == pinfo) || 889 if ((NULL == pinfo) || (NULL != emsg))
947 (NULL != emsg) )
948 { 890 {
949 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 891 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "pi_cb: %s\n", emsg);
950 "pi_cb: %s\n", emsg);
951 abort_test (__LINE__); 892 abort_test (__LINE__);
952 return; 893 return;
953 } 894 }
954 p_id[i] = pinfo->result.id; 895 p_id[i] = pinfo->result.id;
955 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 896 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " id: %s\n", GNUNET_i2s (p_id[i]));
956 " id: %s\n", GNUNET_i2s (p_id[i]));
957 p_ids++; 897 p_ids++;
958 if (p_ids < 2) 898 if (p_ids < 2)
959 return; 899 return;
960 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 900 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got all IDs, starting test\n");
961 "Got all IDs, starting test\n"); 901 test_task = GNUNET_SCHEDULER_add_now (&start_test, NULL);
962 test_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
963 &do_test,
964 NULL);
965} 902}
966 903
967 904
@@ -972,7 +909,7 @@ pi_cb (void *cls,
972 * @param ctx Argument to give to GNUNET_CADET_TEST_cleanup on test end. 909 * @param ctx Argument to give to GNUNET_CADET_TEST_cleanup on test end.
973 * @param num_peers Number of peers that are running. 910 * @param num_peers Number of peers that are running.
974 * @param peers Array of peers. 911 * @param peers Array of peers.
975 * @param cadetes Handle to each of the CADETs of the peers. 912 * @param cadets Handle to each of the CADETs of the peers.
976 */ 913 */
977static void 914static void
978tmain (void *cls, 915tmain (void *cls,
@@ -989,16 +926,18 @@ tmain (void *cls,
989 testbed_peers = peers; 926 testbed_peers = peers;
990 h1 = cadets[0]; 927 h1 = cadets[0];
991 h2 = cadets[num_peers - 1]; 928 h2 = cadets[num_peers - 1];
992 disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME, 929 disconnect_task = GNUNET_SCHEDULER_add_delayed (short_time,
993 &disconnect_cadet_peers, 930 &disconnect_cadet_peers,
994 (void *) __LINE__); 931 (void *) __LINE__);
995 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); 932 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL);
996 t_op[0] = GNUNET_TESTBED_peer_get_information (peers[0], 933 t_op[0] = GNUNET_TESTBED_peer_get_information (peers[0],
997 GNUNET_TESTBED_PIT_IDENTITY, 934 GNUNET_TESTBED_PIT_IDENTITY,
998 &pi_cb, (void *) 0L); 935 &pi_cb,
936 (void *) 0L);
999 t_op[1] = GNUNET_TESTBED_peer_get_information (peers[num_peers - 1], 937 t_op[1] = GNUNET_TESTBED_peer_get_information (peers[num_peers - 1],
1000 GNUNET_TESTBED_PIT_IDENTITY, 938 GNUNET_TESTBED_PIT_IDENTITY,
1001 &pi_cb, (void *) 1L); 939 &pi_cb,
940 (void *) 1L);
1002 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "requested peer ids\n"); 941 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "requested peer ids\n");
1003} 942}
1004 943
@@ -1009,16 +948,46 @@ tmain (void *cls,
1009int 948int
1010main (int argc, char *argv[]) 949main (int argc, char *argv[])
1011{ 950{
1012 initialized = GNUNET_NO;
1013 static const struct GNUNET_HashCode *ports[2]; 951 static const struct GNUNET_HashCode *ports[2];
952 struct GNUNET_MQ_MessageHandler handlers[] = {
953 GNUNET_MQ_hd_var_size (data,
954 GNUNET_MESSAGE_TYPE_DUMMY,
955 struct GNUNET_MessageHeader,
956 NULL),
957 GNUNET_MQ_handler_end ()
958 };
1014 const char *config_file; 959 const char *config_file;
1015 char port_id[] = "test port"; 960 char port_id[] = "test port";
1016 GNUNET_CRYPTO_hash (port_id, sizeof (port_id), &port); 961 struct GNUNET_GETOPT_CommandLineOption options[] = {
962 GNUNET_GETOPT_option_relative_time ('t',
963 "time",
964 "short_time",
965 gettext_noop ("set short timeout"),
966 &short_time),
967
968 GNUNET_GETOPT_option_uint ('m',
969 "messages",
970 "NUM_MESSAGES",
971 gettext_noop ("set number of messages to send"),
972 &total_packets),
1017 973
974 GNUNET_GETOPT_OPTION_END
975 };
976
977
978 initialized = GNUNET_NO;
1018 GNUNET_log_setup ("test", "DEBUG", NULL); 979 GNUNET_log_setup ("test", "DEBUG", NULL);
1019 config_file = "test_cadet.conf";
1020 980
1021 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Start\n"); 981 total_packets = TOTAL_PACKETS;
982 short_time = SHORT_TIME;
983 if (-1 == GNUNET_GETOPT_run (argv[0], options, argc, argv))
984 {
985 FPRINTF (stderr, "test failed: problem with CLI parameters\n");
986 exit (1);
987 }
988
989 config_file = "test_cadet.conf";
990 GNUNET_CRYPTO_hash (port_id, sizeof (port_id), &port);
1022 991
1023 /* Find out requested size */ 992 /* Find out requested size */
1024 if (strstr (argv[0], "_2_") != NULL) 993 if (strstr (argv[0], "_2_") != NULL)
@@ -1056,11 +1025,11 @@ main (int argc, char *argv[])
1056 { 1025 {
1057 /* Test is supposed to generate the following callbacks: 1026 /* Test is supposed to generate the following callbacks:
1058 * 1 incoming channel (@dest) 1027 * 1 incoming channel (@dest)
1059 * TOTAL_PACKETS received data packet (@dest) 1028 * total_packets received data packet (@dest)
1060 * TOTAL_PACKETS received data packet (@orig) 1029 * total_packets received data packet (@orig)
1061 * 1 received channel destroy (@dest) 1030 * 1 received channel destroy (@dest)
1062 */ 1031 */
1063 ok_goal = TOTAL_PACKETS * 2 + 2; 1032 ok_goal = total_packets * 2 + 2;
1064 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "SPEED_ACK\n"); 1033 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "SPEED_ACK\n");
1065 test = SPEED_ACK; 1034 test = SPEED_ACK;
1066 test_name = "speed ack"; 1035 test_name = "speed ack";
@@ -1070,11 +1039,11 @@ main (int argc, char *argv[])
1070 /* Test is supposed to generate the following callbacks: 1039 /* Test is supposed to generate the following callbacks:
1071 * 1 incoming channel (@dest) 1040 * 1 incoming channel (@dest)
1072 * 1 initial packet (@dest) 1041 * 1 initial packet (@dest)
1073 * TOTAL_PACKETS received data packet (@dest) 1042 * total_packets received data packet (@dest)
1074 * 1 received data packet (@orig) 1043 * 1 received data packet (@orig)
1075 * 1 received channel destroy (@dest) 1044 * 1 received channel destroy (@dest)
1076 */ 1045 */
1077 ok_goal = TOTAL_PACKETS + 4; 1046 ok_goal = total_packets + 4;
1078 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "SPEED\n"); 1047 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "SPEED\n");
1079 if (strstr (argv[0], "_reliable") != NULL) 1048 if (strstr (argv[0], "_reliable") != NULL)
1080 { 1049 {
@@ -1115,20 +1084,22 @@ main (int argc, char *argv[])
1115 p_ids = 0; 1084 p_ids = 0;
1116 ports[0] = &port; 1085 ports[0] = &port;
1117 ports[1] = NULL; 1086 ports[1] = NULL;
1118 GNUNET_CADET_TEST_run ("test_cadet_small", 1087 GNUNET_CADET_TEST_ruN ("test_cadet_small",
1119 config_file, 1088 config_file,
1120 peers_requested, 1089 peers_requested,
1121 &tmain, 1090 &tmain,
1122 NULL, /* tmain cls */ 1091 NULL, /* tmain cls */
1123 &incoming_channel, 1092 &connect_handler,
1124 &channel_cleaner, 1093 NULL,
1125 handlers, 1094 &disconnect_handler,
1126 ports); 1095 handlers,
1127 1096 ports);
1128 if (ok_goal > ok) 1097 if (NULL != strstr (argv[0], "_reliable"))
1098 msg_dropped = 0; /* dropped should be retransmitted */
1099
1100 if (ok_goal > ok - msg_dropped)
1129 { 1101 {
1130 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1102 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "FAILED! (%d/%d)\n", ok, ok_goal);
1131 "FAILED! (%d/%d)\n", ok, ok_goal);
1132 return 1; 1103 return 1;
1133 } 1104 }
1134 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "success\n"); 1105 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "success\n");
diff --git a/src/cadet/test_cadet_local.c b/src/cadet/test_cadet_local.c
deleted file mode 100644
index 2b915ab81..000000000
--- a/src/cadet/test_cadet_local.c
+++ /dev/null
@@ -1,351 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2011 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 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 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file cadet/test_cadet_local.c
23 * @brief test cadet local: test of cadet channels with just one peer
24 * @author Bartlomiej Polot
25 */
26
27#include "platform.h"
28#include "gnunet_util_lib.h"
29#include "gnunet_dht_service.h"
30#include "gnunet_testing_lib.h"
31#include "gnunet_cadet_service.h"
32
33struct GNUNET_TESTING_Peer *me;
34
35static struct GNUNET_CADET_Handle *cadet_peer_1;
36
37static struct GNUNET_CADET_Handle *cadet_peer_2;
38
39static struct GNUNET_CADET_Channel *ch;
40
41static int result = GNUNET_OK;
42
43static int got_data = GNUNET_NO;
44
45static struct GNUNET_SCHEDULER_Task *abort_task;
46
47static struct GNUNET_SCHEDULER_Task *connect_task;
48
49static struct GNUNET_CADET_TransmitHandle *mth;
50
51
52/**
53 * Connect to other client and send data
54 *
55 * @param cls Closue (unused).
56 */
57static void
58do_connect (void *cls);
59
60
61/**
62 * Shutdown nicely
63 */
64static void
65do_shutdown (void *cls)
66{
67 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
68 "shutdown\n");
69 if (NULL != abort_task)
70 {
71 GNUNET_SCHEDULER_cancel (abort_task);
72 abort_task = NULL;
73 }
74 if (NULL != ch)
75 {
76 GNUNET_CADET_channel_destroy (ch);
77 ch = NULL;
78 }
79 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
80 "Disconnect client 1\n");
81 if (NULL != cadet_peer_1)
82 {
83 GNUNET_CADET_disconnect (cadet_peer_1);
84 cadet_peer_1 = NULL;
85 }
86 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
87 "Disconnect client 2\n");
88 if (NULL != cadet_peer_2)
89 {
90 GNUNET_CADET_disconnect (cadet_peer_2);
91 cadet_peer_2 = NULL;
92 }
93 if (NULL != connect_task)
94 {
95 GNUNET_SCHEDULER_cancel (connect_task);
96 connect_task = NULL;
97 }
98}
99
100
101/**
102 * Something went wrong and timed out. Kill everything and set error flag
103 */
104static void
105do_abort (void *cls)
106{
107 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ABORT\n");
108 result = GNUNET_SYSERR;
109 abort_task = NULL;
110 GNUNET_SCHEDULER_shutdown ();
111}
112
113
114/**
115 * Function is called whenever a message is received.
116 *
117 * @param cls closure (set from GNUNET_CADET_connect)
118 * @param channel connection to the other end
119 * @param channel_ctx place to store local state associated with the channel
120 * @param message the actual message
121 * @return #GNUNET_OK to keep the connection open,
122 * #GNUNET_SYSERR to close it (signal serious error)
123 */
124static int
125data_callback (void *cls,
126 struct GNUNET_CADET_Channel *channel,
127 void **channel_ctx,
128 const struct GNUNET_MessageHeader *message)
129{
130 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
131 "Data callback! Shutting down.\n");
132 got_data = GNUNET_YES;
133 GNUNET_SCHEDULER_shutdown ();
134 GNUNET_CADET_receive_done (channel);
135 return GNUNET_OK;
136}
137
138
139/**
140 * Method called whenever another peer has added us to a channel
141 * the other peer initiated.
142 *
143 * @param cls closure
144 * @param channel new handle to the channel
145 * @param initiator peer that started the channel
146 * @param port port number
147 * @param options channel options
148 * @return initial channel context for the channel
149 * (can be NULL -- that's not an error)
150 */
151static void *
152inbound_channel (void *cls,
153 struct GNUNET_CADET_Channel *channel,
154 const struct GNUNET_PeerIdentity *initiator,
155 const struct GNUNET_HashCode *port,
156 enum GNUNET_CADET_ChannelOption options)
157{
158 long id = (long) cls;
159
160 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
161 "received incoming channel on peer %d, port %s\n",
162 (int) id,
163 GNUNET_h2s (port));
164 if (id != 2L)
165 {
166 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
167 "wrong peer\n");
168 result = GNUNET_SYSERR;
169 }
170 return NULL;
171}
172
173
174/**
175 * Function called whenever an channel is destroyed. Should clean up
176 * any associated state.
177 *
178 * @param cls closure (set from GNUNET_CADET_connect)
179 * @param channel connection to the other end (henceforth invalid)
180 * @param channel_ctx place where local state associated
181 * with the channel is stored
182 */
183static void
184channel_end (void *cls,
185 const struct GNUNET_CADET_Channel *channel,
186 void *channel_ctx)
187{
188 long id = (long) cls;
189
190 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
191 "incoming channel closed at peer %ld\n",
192 id);
193 if (NULL != mth)
194 {
195 GNUNET_CADET_notify_transmit_ready_cancel (mth);
196 mth = NULL;
197 }
198 if (channel == ch)
199 ch = NULL;
200 if (GNUNET_NO == got_data)
201 {
202 if (NULL == connect_task)
203 connect_task
204 = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
205 2),
206 &do_connect,
207 NULL);
208 }
209}
210
211
212/**
213 * Handler array for traffic received on peer1
214 */
215static struct GNUNET_CADET_MessageHandler handlers1[] = {
216 {&data_callback, 1, 0},
217 {NULL, 0, 0}
218};
219
220
221/**
222 * Handler array for traffic received on peer2 (none expected)
223 */
224static struct GNUNET_CADET_MessageHandler handlers2[] = {
225 {&data_callback, 1, 0},
226 {NULL, 0, 0}
227};
228
229
230/**
231 * Data send callback: fillbuffer with test packet.
232 *
233 * @param cls Closure (unused).
234 * @param size Buffer size.
235 * @param buf Buffer to fill.
236 *
237 * @return size of test packet.
238 */
239static size_t
240do_send (void *cls, size_t size, void *buf)
241{
242 struct GNUNET_MessageHeader *m = buf;
243
244 mth = NULL;
245 if (NULL == buf)
246 {
247 GNUNET_break (0);
248 result = GNUNET_SYSERR;
249 return 0;
250 }
251 m->size = htons (sizeof (struct GNUNET_MessageHeader));
252 m->type = htons (1);
253 GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader));
254 return sizeof (struct GNUNET_MessageHeader);
255}
256
257
258/**
259 * Connect to other client and send data
260 *
261 * @param cls Closue (unused).
262 */
263static void
264do_connect (void *cls)
265{
266 struct GNUNET_PeerIdentity id;
267
268 connect_task = NULL;
269 GNUNET_TESTING_peer_get_identity (me, &id);
270 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
271 "CONNECT BY PORT\n");
272 ch = GNUNET_CADET_channel_create (cadet_peer_1,
273 NULL,
274 &id, GC_u2h (1),
275 GNUNET_CADET_OPTION_DEFAULT);
276 mth = GNUNET_CADET_notify_transmit_ready (ch, GNUNET_NO,
277 GNUNET_TIME_UNIT_FOREVER_REL,
278 sizeof (struct GNUNET_MessageHeader),
279 &do_send, NULL);
280}
281
282
283/**
284 * Initialize framework and start test
285 *
286 * @param cls Closure (unused).
287 * @param cfg Configuration handle.
288 * @param peer Testing peer handle.
289 */
290static void
291run (void *cls,
292 const struct GNUNET_CONFIGURATION_Handle *cfg,
293 struct GNUNET_TESTING_Peer *peer)
294{
295 me = peer;
296 GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
297 NULL);
298 abort_task =
299 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
300 (GNUNET_TIME_UNIT_SECONDS, 15),
301 &do_abort,
302 NULL);
303 cadet_peer_1 = GNUNET_CADET_connect (cfg, /* configuration */
304 (void *) 1L, /* cls */
305 &channel_end, /* channel end hndlr */
306 handlers1); /* traffic handlers */
307 cadet_peer_2 = GNUNET_CADET_connect (cfg, /* configuration */
308 (void *) 2L, /* cls */
309 &channel_end, /* channel end hndlr */
310 handlers2); /* traffic handlers */
311
312 if ( (NULL == cadet_peer_1) ||
313 (NULL == cadet_peer_2) )
314 {
315 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
316 "Couldn't connect to cadet :(\n");
317 result = GNUNET_SYSERR;
318 GNUNET_SCHEDULER_shutdown ();
319 return;
320 }
321 GNUNET_CADET_open_port (cadet_peer_2,
322 GC_u2h (1),
323 &inbound_channel,
324 (void *) 2L);
325 if (NULL == connect_task)
326 connect_task
327 = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
328 2),
329 &do_connect,
330 NULL);
331}
332
333
334/**
335 * Main
336 */
337int
338main (int argc, char *argv[])
339{
340 if (0 != GNUNET_TESTING_peer_run ("test-cadet-local",
341 "test_cadet.conf",
342 &run, NULL))
343 {
344 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "run failed\n");
345 return 2;
346 }
347 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Final result: %d\n", result);
348 return (result == GNUNET_OK) ? 0 : 1;
349}
350
351/* end of test_cadet_local_1.c */
diff --git a/src/cadet/test_cadet_local_mq.c b/src/cadet/test_cadet_local_mq.c
new file mode 100644
index 000000000..3089c7fbb
--- /dev/null
+++ b/src/cadet/test_cadet_local_mq.c
@@ -0,0 +1,332 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2017 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 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 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file cadet/test_cadet_local.c
23 * @brief test cadet local: test of cadet channels with just one peer
24 * @author Bartlomiej Polot
25 */
26
27#include "platform.h"
28#include "gnunet_util_lib.h"
29#include "gnunet_dht_service.h"
30#include "gnunet_testing_lib.h"
31#include "gnunet_cadet_service.h"
32
33#define TEST_MESSAGE_TYPE 1
34#define TEST_PORT_ID 1
35
36/**
37 * Test message structure.
38 */
39struct GNUNET_CADET_TestMsg
40{
41 /**
42 * Type: #TEST_MESSAGE_TYPE
43 *
44 * Size: sizeof(struct GNUNET_CADET_TestMsg)
45 */
46 struct GNUNET_MessageHeader header;
47
48 /**
49 * Test payload.
50 */
51 uint64_t payload;
52};
53
54struct GNUNET_TESTING_Peer *me;
55
56static struct GNUNET_CADET_Handle *cadet_peer_1;
57
58static struct GNUNET_CADET_Handle *cadet_peer_2;
59
60static struct GNUNET_CADET_Channel *ch;
61
62static int result = GNUNET_OK;
63
64static int got_data = GNUNET_NO;
65
66static struct GNUNET_SCHEDULER_Task *abort_task;
67
68static struct GNUNET_SCHEDULER_Task *connect_task;
69
70
71/**
72 * Connect to other client and send data
73 *
74 * @param cls Closue (unused).
75 */
76static void
77do_connect (void *cls);
78
79
80/**
81 * Shutdown nicely
82 */
83static void
84do_shutdown (void *cls)
85{
86 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
87 "shutdown\n");
88 if (NULL != abort_task)
89 {
90 GNUNET_SCHEDULER_cancel (abort_task);
91 abort_task = NULL;
92 }
93 if (NULL != ch)
94 {
95 GNUNET_CADET_channel_destroy (ch);
96 ch = NULL;
97 }
98 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
99 "Disconnect client 1\n");
100 if (NULL != cadet_peer_1)
101 {
102 GNUNET_CADET_disconnect (cadet_peer_1);
103 cadet_peer_1 = NULL;
104 }
105 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
106 "Disconnect client 2\n");
107 if (NULL != cadet_peer_2)
108 {
109 GNUNET_CADET_disconnect (cadet_peer_2);
110 cadet_peer_2 = NULL;
111 }
112 if (NULL != connect_task)
113 {
114 GNUNET_SCHEDULER_cancel (connect_task);
115 connect_task = NULL;
116 }
117}
118
119
120/**
121 * Something went wrong and timed out. Kill everything and set error flag
122 */
123static void
124do_abort (void *cls)
125{
126 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ABORT from line %ld\n", (long) cls);
127 result = GNUNET_SYSERR;
128 abort_task = NULL;
129 GNUNET_SCHEDULER_shutdown ();
130}
131
132/**
133 * Method called whenever a peer connects to a port in MQ-based CADET.
134 *
135 * @param cls Closure from #GNUNET_CADET_open_port.
136 * @param channel New handle to the channel.
137 * @param source Peer that started this channel.
138 * @return Closure for the incoming @a channel. It's given to:
139 * - The #GNUNET_CADET_DisconnectEventHandler (given to
140 * #GNUNET_CADET_open_port) when the channel dies.
141 * - Each the #GNUNET_MQ_MessageCallback handlers for each message
142 * received on the @a channel.
143 */
144static void *
145connected (void *cls,
146 struct GNUNET_CADET_Channel *channel,
147 const struct GNUNET_PeerIdentity *source)
148{
149 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
150 "connected %s, cls: %p\n",
151 GNUNET_i2s(source), cls);
152 return channel;
153}
154
155/**
156 * Function called whenever an MQ-channel is destroyed, even if the destruction
157 * was requested by #GNUNET_CADET_channel_destroy.
158 * It must NOT call #GNUNET_CADET_channel_destroy on the channel.
159 *
160 * It should clean up any associated state, including cancelling any pending
161 * transmission on this channel.
162 *
163 * @param cls Channel closure.
164 * @param channel Connection to the other end (henceforth invalid).
165 */
166static void
167disconnected (void *cls,
168 const struct GNUNET_CADET_Channel *channel)
169{
170 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
171 "disconnected channel %p, cls: %p\n",
172 channel, cls);
173 if (channel == ch)
174 ch = NULL;
175}
176
177
178/**
179 * Handle test data
180 *
181 * @param h The cadet handle
182 * @param msg A message with the details of the new incoming channel
183 */
184static void
185handle_data_received (void *cls,
186 const struct GNUNET_CADET_TestMsg *msg)
187{
188 uint64_t payload;
189
190 payload = GNUNET_ntohll (msg->payload);
191 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
192 "Data callback payload %llu with cls: %p! Shutting down.\n",
193 (unsigned long long) payload,
194 cls);
195 GNUNET_assert (42 == payload);
196 got_data = GNUNET_YES;
197 GNUNET_SCHEDULER_shutdown ();
198}
199
200
201/**
202 * Signature of the main function of a task.
203 *
204 * @param cls Closure (unused).
205 */
206static void
207message_sent (void *cls)
208{
209 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "message sent\n");
210}
211
212
213/**
214 * Connect to other client and send data
215 *
216 * @param cls Closure (unused).
217 */
218static void
219do_connect (void *cls)
220{
221 struct GNUNET_PeerIdentity id;
222 struct GNUNET_MQ_Handle *mq;
223 struct GNUNET_MQ_Envelope *env;
224 struct GNUNET_CADET_TestMsg *msg;
225
226 struct GNUNET_MQ_MessageHandler handlers[] = {
227 GNUNET_MQ_hd_fixed_size (data_received,
228 TEST_MESSAGE_TYPE,
229 struct GNUNET_CADET_TestMsg,
230 cadet_peer_1),
231 GNUNET_MQ_handler_end ()
232 };
233
234 connect_task = NULL;
235 GNUNET_TESTING_peer_get_identity (me, &id);
236 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
237 "creating channel\n");
238 ch = GNUNET_CADET_channel_create (cadet_peer_1, /* cadet handle */
239 NULL, /* channel cls */
240 &id, /* destination */
241 GC_u2h (TEST_MESSAGE_TYPE), /* port */
242 GNUNET_CADET_OPTION_DEFAULT, /* opt */
243 NULL, /* window change */
244 &disconnected, /* disconnect handler */
245 handlers /* traffic handlers */
246 );
247 env = GNUNET_MQ_msg (msg, TEST_MESSAGE_TYPE);
248 msg->payload = GNUNET_htonll (42);
249 mq = GNUNET_CADET_get_mq (ch);
250 GNUNET_MQ_notify_sent (env, &message_sent, NULL);
251 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
252 "sending message\n");
253 GNUNET_MQ_send (mq, env);
254}
255
256
257/**
258 * Initialize framework and start test
259 *
260 * @param cls Closure (unused).
261 * @param cfg Configuration handle.
262 * @param peer Testing peer handle.
263 */
264static void
265run (void *cls,
266 const struct GNUNET_CONFIGURATION_Handle *cfg,
267 struct GNUNET_TESTING_Peer *peer)
268{
269 struct GNUNET_MQ_MessageHandler handlers[] = {
270 GNUNET_MQ_hd_fixed_size (data_received,
271 TEST_MESSAGE_TYPE,
272 struct GNUNET_CADET_TestMsg,
273 cadet_peer_2),
274 GNUNET_MQ_handler_end ()
275 };
276 struct GNUNET_TIME_Relative delay;
277
278 me = peer;
279 GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
280 NULL);
281 delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15);
282 abort_task = GNUNET_SCHEDULER_add_delayed (delay,
283 &do_abort,
284 (void *) (long) __LINE__);
285 cadet_peer_1 = GNUNET_CADET_connect (cfg);
286 cadet_peer_2 = GNUNET_CADET_connect (cfg);
287
288 if ( (NULL == cadet_peer_1) ||
289 (NULL == cadet_peer_2) )
290 {
291 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
292 "Couldn't connect to cadet\n");
293 result = GNUNET_SYSERR;
294 GNUNET_SCHEDULER_shutdown ();
295 return;
296 }
297 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CADET 1: %p\n", cadet_peer_1);
298 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CADET 2: %p\n", cadet_peer_2);
299 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "handlers 2: %p\n", handlers);
300 GNUNET_CADET_open_port (cadet_peer_2, /* cadet handle */
301 GC_u2h (TEST_PORT_ID), /* port id */
302 &connected, /* connect handler */
303 (void *) 2L, /* handle for #connected */
304 NULL, /* window size handler */
305 &disconnected, /* disconnect handler */
306 handlers); /* traffic handlers */
307 delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 2);
308 if (NULL == connect_task)
309 connect_task = GNUNET_SCHEDULER_add_delayed (delay,
310 &do_connect,
311 NULL);
312}
313
314
315/**
316 * Main
317 */
318int
319main (int argc, char *argv[])
320{
321 if (0 != GNUNET_TESTING_peer_run ("test-cadet-local",
322 "test_cadet.conf",
323 &run, NULL))
324 {
325 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "run failed\n");
326 return 2;
327 }
328 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Final result: %d\n", result);
329 return (result == GNUNET_OK) ? 0 : 1;
330}
331
332/* end of test_cadet_local_1.c */
diff --git a/src/cadet/test_cadet_single.c b/src/cadet/test_cadet_single.c
deleted file mode 100644
index b45b0af5d..000000000
--- a/src/cadet/test_cadet_single.c
+++ /dev/null
@@ -1,354 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2011 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 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 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file cadet/test_cadet_single.c
23 * @brief test cadet single: test of cadet channels with just one client
24 * @author Bartlomiej Polot
25 */
26
27#include "platform.h"
28#include "gnunet_util_lib.h"
29#include "gnunet_dht_service.h"
30#include "gnunet_testing_lib.h"
31#include "gnunet_cadet_service.h"
32
33#define REPETITIONS 5
34#define DATA_SIZE 35000
35
36struct GNUNET_TESTING_Peer *me;
37
38static struct GNUNET_CADET_Handle *cadet;
39
40static struct GNUNET_CADET_Channel *ch1;
41
42static struct GNUNET_CADET_Channel *ch2;
43
44static int result;
45
46static struct GNUNET_SCHEDULER_Task *abort_task;
47
48static struct GNUNET_SCHEDULER_Task *connect_task;
49
50static unsigned int repetition;
51
52static struct GNUNET_CADET_TransmitHandle *nth;
53
54static struct GNUNET_CADET_Port *port;
55
56
57/* forward declaration */
58static size_t
59do_send (void *cls, size_t size, void *buf);
60
61
62/**
63 * Shutdown nicely
64 */
65static void
66do_shutdown (void *cls)
67{
68 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
69 "shutdown\n");
70 if (NULL != port)
71 {
72 GNUNET_CADET_close_port (port);
73 port = NULL;
74 }
75 if (NULL != nth)
76 {
77 GNUNET_CADET_notify_transmit_ready_cancel (nth);
78 nth = NULL;
79 }
80 if (NULL != abort_task)
81 {
82 GNUNET_SCHEDULER_cancel (abort_task);
83 abort_task = NULL;
84 }
85 if (NULL != connect_task)
86 {
87 GNUNET_SCHEDULER_cancel (connect_task);
88 connect_task = NULL;
89 }
90 if (NULL != ch1)
91 {
92 GNUNET_CADET_channel_destroy (ch1);
93 ch1 = NULL;
94 }
95 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
96 "Disconnect clients\n");
97 if (NULL != cadet)
98 {
99 GNUNET_CADET_disconnect (cadet);
100 cadet = NULL;
101 }
102 else
103 {
104 GNUNET_break (0);
105 }
106}
107
108
109/**
110 * Something went wrong and timed out. Kill everything and set error flag
111 */
112static void
113do_abort (void *cls)
114{
115 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ABORT\n");
116 result = GNUNET_SYSERR;
117 abort_task = NULL;
118 GNUNET_SCHEDULER_shutdown ();
119}
120
121
122/**
123 * Function is called whenever a message is received.
124 *
125 * @param cls closure (set from GNUNET_CADET_connect)
126 * @param channel connection to the other end
127 * @param channel_ctx place to store local state associated with the channel
128 * @param message the actual message
129 * @return #GNUNET_OK to keep the connection open,
130 * #GNUNET_SYSERR to close it (signal serious error)
131 */
132static int
133data_callback (void *cls,
134 struct GNUNET_CADET_Channel *channel,
135 void **channel_ctx,
136 const struct GNUNET_MessageHeader *message)
137{
138 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
139 "Data callback! Repetition %u/%u\n",
140 repetition, REPETITIONS);
141 repetition++;
142 if (repetition < REPETITIONS)
143 {
144 struct GNUNET_CADET_Channel *my_channel;
145 if (0 == repetition % 2)
146 my_channel = ch1;
147 else
148 my_channel = ch2;
149 nth = GNUNET_CADET_notify_transmit_ready (my_channel,
150 GNUNET_NO,
151 GNUNET_TIME_UNIT_FOREVER_REL,
152 sizeof (struct GNUNET_MessageHeader)
153 + DATA_SIZE,
154 &do_send, NULL);
155 GNUNET_CADET_receive_done (channel);
156 return GNUNET_OK;
157 }
158 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
159 "All data OK. Destroying channel.\n");
160 GNUNET_assert (NULL == nth);
161 GNUNET_CADET_channel_destroy (ch1);
162 ch1 = NULL;
163 return GNUNET_OK;
164}
165
166
167/**
168 * Method called whenever another peer has added us to a channel
169 * the other peer initiated.
170 *
171 * @param cls closure
172 * @param channel new handle to the channel
173 * @param initiator peer that started the channel
174 * @param port port number
175 * @param options channel option flags
176 * @return initial channel context for the channel
177 * (can be NULL -- that's not an error)
178 */
179static void *
180inbound_channel (void *cls,
181 struct GNUNET_CADET_Channel *channel,
182 const struct GNUNET_PeerIdentity *initiator,
183 const struct GNUNET_HashCode *port,
184 enum GNUNET_CADET_ChannelOption options)
185{
186 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
187 "received incoming channel on port %s\n",
188 GNUNET_h2s (port));
189 ch2 = channel;
190 return NULL;
191}
192
193
194/**
195 * Function called whenever an inbound channel is destroyed. Should clean up
196 * any associated state.
197 *
198 * @param cls closure (set from GNUNET_CADET_connect)
199 * @param channel connection to the other end (henceforth invalid)
200 * @param channel_ctx place where local state associated
201 * with the channel is stored
202 */
203static void
204channel_end (void *cls,
205 const struct GNUNET_CADET_Channel *channel,
206 void *channel_ctx)
207{
208 long id = (long) cls;
209
210 nth = NULL;
211 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
212 "incoming channel closed at peer %ld\n",
213 id);
214 if ( (REPETITIONS == repetition) &&
215 (channel == ch2) )
216 {
217 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
218 "everything fine! finishing!\n");
219 result = GNUNET_OK;
220 GNUNET_SCHEDULER_shutdown ();
221 }
222 if (channel == ch2)
223 ch2 = NULL;
224 if (channel == ch1)
225 ch1 = NULL;
226}
227
228
229/**
230 * Handler array for traffic received on peer1
231 */
232static struct GNUNET_CADET_MessageHandler handlers1[] = {
233 {&data_callback, 1, 0},
234 {NULL, 0, 0}
235};
236
237
238/**
239 * Data send callback: fillbuffer with test packet.
240 *
241 * @param cls Closure (unused).
242 * @param size Buffer size.
243 * @param buf Buffer to fill.
244 * @return size of test packet.
245 */
246static size_t
247do_send (void *cls, size_t size, void *buf)
248{
249 struct GNUNET_MessageHeader *m = buf;
250
251 nth = NULL;
252 if (NULL == buf)
253 {
254 GNUNET_break (0);
255 result = GNUNET_SYSERR;
256 return 0;
257 }
258 m->size = htons (sizeof (struct GNUNET_MessageHeader) + DATA_SIZE);
259 m->type = htons (1);
260 memset (&m[1], 0, DATA_SIZE);
261 GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader) + DATA_SIZE);
262 return sizeof (struct GNUNET_MessageHeader) + DATA_SIZE;
263}
264
265/**
266 * Connect to other client and send data
267 *
268 * @param cls Closue (unused).
269 */
270static void
271do_connect (void *cls)
272{
273 struct GNUNET_PeerIdentity id;
274 size_t size = sizeof (struct GNUNET_MessageHeader) + DATA_SIZE;
275
276 connect_task = NULL;
277 GNUNET_TESTING_peer_get_identity (me, &id);
278 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CONNECT BY PORT\n");
279 ch1 = GNUNET_CADET_channel_create (cadet, NULL, &id, GC_u2h (1),
280 GNUNET_CADET_OPTION_DEFAULT);
281 nth = GNUNET_CADET_notify_transmit_ready (ch1,
282 GNUNET_NO,
283 GNUNET_TIME_UNIT_FOREVER_REL,
284 size,
285 &do_send,
286 NULL);
287}
288
289
290/**
291 * Initialize framework and start test
292 *
293 * @param cls Closure (unused).
294 * @param cfg Configuration handle.
295 * @param peer Testing peer handle.
296 */
297static void
298run (void *cls,
299 const struct GNUNET_CONFIGURATION_Handle *cfg,
300 struct GNUNET_TESTING_Peer *peer)
301{
302 me = peer;
303 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
304 abort_task =
305 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
306 (GNUNET_TIME_UNIT_SECONDS, 15), &do_abort,
307 NULL);
308 cadet = GNUNET_CADET_connect (cfg, /* configuration */
309 (void *) 1L, /* cls */
310 &channel_end, /* inbound end hndlr */
311 handlers1); /* traffic handlers */
312 port = GNUNET_CADET_open_port (cadet,
313 GC_u2h (1),
314 &inbound_channel,
315 (void *) 1L);
316
317
318 if (NULL == cadet)
319 {
320 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
321 "Couldn't connect to cadet :(\n");
322 result = GNUNET_SYSERR;
323 return;
324 }
325 connect_task
326 = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
327 &do_connect,
328 NULL);
329}
330
331
332/**
333 * Main
334 */
335int
336main (int argc,
337 char *argv[])
338{
339 result = GNUNET_NO;
340 if (0 != GNUNET_TESTING_peer_run ("test-cadet-local",
341 "test_cadet.conf",
342 &run, NULL))
343 {
344 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
345 "run failed\n");
346 return 2;
347 }
348 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
349 "Final result: %d\n",
350 result);
351 return (result == GNUNET_OK) ? 0 : 1;
352}
353
354/* end of test_cadet_single.c */