diff options
author | Christian Grothoff <christian@grothoff.org> | 2017-03-11 12:53:18 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2017-03-11 12:53:18 +0100 |
commit | bcf3298c5eb79dd98bfc8ccf58793703aac70f49 (patch) | |
tree | 2bc59b82d74596c65b3caab68f6102da516dfc46 | |
parent | cd3d159df3150d46a6de7d39bcefb16f03ed5d3b (diff) | |
download | gnunet-bcf3298c5eb79dd98bfc8ccf58793703aac70f49.tar.gz gnunet-bcf3298c5eb79dd98bfc8ccf58793703aac70f49.zip |
remove old CADET service code
-rw-r--r-- | src/cadet/Makefile.am | 26 | ||||
-rw-r--r-- | src/cadet/gnunet-service-cadet.c | 184 | ||||
-rw-r--r-- | src/cadet/gnunet-service-cadet_channel.c | 2562 | ||||
-rw-r--r-- | src/cadet/gnunet-service-cadet_channel.h | 363 | ||||
-rw-r--r-- | src/cadet/gnunet-service-cadet_connection.c | 3713 | ||||
-rw-r--r-- | src/cadet/gnunet-service-cadet_connection.h | 576 | ||||
-rw-r--r-- | src/cadet/gnunet-service-cadet_dht.c | 424 | ||||
-rw-r--r-- | src/cadet/gnunet-service-cadet_dht.h | 93 | ||||
-rw-r--r-- | src/cadet/gnunet-service-cadet_hello.c | 200 | ||||
-rw-r--r-- | src/cadet/gnunet-service-cadet_hello.h | 79 | ||||
-rw-r--r-- | src/cadet/gnunet-service-cadet_local.c | 1553 | ||||
-rw-r--r-- | src/cadet/gnunet-service-cadet_local.h | 234 | ||||
-rw-r--r-- | src/cadet/gnunet-service-cadet_peer.c | 2209 | ||||
-rw-r--r-- | src/cadet/gnunet-service-cadet_peer.h | 483 | ||||
-rw-r--r-- | src/cadet/gnunet-service-cadet_tunnel.c | 3501 | ||||
-rw-r--r-- | src/cadet/gnunet-service-cadet_tunnel.h | 616 |
16 files changed, 1 insertions, 16815 deletions
diff --git a/src/cadet/Makefile.am b/src/cadet/Makefile.am index b52079b2e..518646664 100644 --- a/src/cadet/Makefile.am +++ b/src/cadet/Makefile.am | |||
@@ -22,7 +22,6 @@ plugindir = $(libdir)/gnunet | |||
22 | AM_CLFAGS = -g | 22 | AM_CLFAGS = -g |
23 | 23 | ||
24 | libexec_PROGRAMS = \ | 24 | libexec_PROGRAMS = \ |
25 | gnunet-service-cadet \ | ||
26 | gnunet-service-cadet-new \ | 25 | gnunet-service-cadet-new \ |
27 | $(EXP_LIBEXEC) | 26 | $(EXP_LIBEXEC) |
28 | 27 | ||
@@ -81,31 +80,8 @@ gnunet_service_cadet_new_LDADD = \ | |||
81 | $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ | 80 | $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ |
82 | $(top_builddir)/src/hello/libgnunethello.la \ | 81 | $(top_builddir)/src/hello/libgnunethello.la \ |
83 | $(top_builddir)/src/block/libgnunetblock.la | 82 | $(top_builddir)/src/block/libgnunetblock.la |
84 | |||
85 | gnunet_service_cadet_SOURCES = \ | ||
86 | gnunet-service-cadet_tunnel.c gnunet-service-cadet_tunnel.h \ | ||
87 | gnunet-service-cadet_connection.c gnunet-service-cadet_connection.h \ | ||
88 | gnunet-service-cadet_channel.c gnunet-service-cadet_channel.h \ | ||
89 | gnunet-service-cadet_local.c gnunet-service-cadet_local.h \ | ||
90 | gnunet-service-cadet_peer.c gnunet-service-cadet_peer.h \ | ||
91 | gnunet-service-cadet_dht.c gnunet-service-cadet_dht.h \ | ||
92 | gnunet-service-cadet_hello.c gnunet-service-cadet_hello.h \ | ||
93 | cadet_path.c cadet_path.h \ | ||
94 | cadet_common.c \ | ||
95 | gnunet-service-cadet.c | ||
96 | gnunet_service_cadet_CFLAGS = $(AM_CFLAGS) | ||
97 | gnunet_service_cadet_LDADD = \ | ||
98 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
99 | $(top_builddir)/src/transport/libgnunettransport.la \ | ||
100 | $(top_builddir)/src/core/libgnunetcore.la \ | ||
101 | $(top_builddir)/src/ats/libgnunetats.la \ | ||
102 | $(top_builddir)/src/dht/libgnunetdht.la \ | ||
103 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | ||
104 | $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ | ||
105 | $(top_builddir)/src/hello/libgnunethello.la \ | ||
106 | $(top_builddir)/src/block/libgnunetblock.la | ||
107 | if LINUX | 83 | if LINUX |
108 | gnunet_service_cadet_LDFLAGS = -lrt | 84 | gnunet_service_cadet_new_LDFLAGS = -lrt |
109 | endif | 85 | endif |
110 | 86 | ||
111 | 87 | ||
diff --git a/src/cadet/gnunet-service-cadet.c b/src/cadet/gnunet-service-cadet.c deleted file mode 100644 index 3a07f0ee5..000000000 --- a/src/cadet/gnunet-service-cadet.c +++ /dev/null | |||
@@ -1,184 +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/gnunet-service-cadet.c | ||
23 | * @brief GNUnet CADET service with encryption | ||
24 | * @author Bartlomiej Polot | ||
25 | * | ||
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 | * | ||
35 | * Dictionary: | ||
36 | * - 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. | ||
41 | * - connection: path which is being used in a tunnel. | ||
42 | */ | ||
43 | |||
44 | #include "platform.h" | ||
45 | #include "gnunet_util_lib.h" | ||
46 | #include "cadet.h" | ||
47 | #include "gnunet_statistics_service.h" | ||
48 | |||
49 | #include "gnunet-service-cadet_local.h" | ||
50 | #include "gnunet-service-cadet_channel.h" | ||
51 | #include "gnunet-service-cadet_connection.h" | ||
52 | #include "gnunet-service-cadet_tunnel.h" | ||
53 | #include "gnunet-service-cadet_dht.h" | ||
54 | #include "gnunet-service-cadet_peer.h" | ||
55 | #include "gnunet-service-cadet_hello.h" | ||
56 | |||
57 | |||
58 | /******************************************************************************/ | ||
59 | /*********************** GLOBAL VARIABLES ****************************/ | ||
60 | /******************************************************************************/ | ||
61 | |||
62 | /****************************** Global variables ******************************/ | ||
63 | |||
64 | /** | ||
65 | * Handle to the statistics service. | ||
66 | */ | ||
67 | struct GNUNET_STATISTICS_Handle *stats; | ||
68 | |||
69 | /** | ||
70 | * Local peer own ID (memory efficient handle). | ||
71 | */ | ||
72 | GNUNET_PEER_Id myid; | ||
73 | |||
74 | /** | ||
75 | * Local peer own ID (full value). | ||
76 | */ | ||
77 | struct GNUNET_PeerIdentity my_full_id; | ||
78 | |||
79 | |||
80 | /** | ||
81 | * Signal that shutdown is happening: prevent recover measures. | ||
82 | */ | ||
83 | int shutting_down; | ||
84 | |||
85 | /*************************** Static global variables **************************/ | ||
86 | |||
87 | /** | ||
88 | * Own private key. | ||
89 | */ | ||
90 | static struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key; | ||
91 | |||
92 | |||
93 | /******************************************************************************/ | ||
94 | /************************ MAIN FUNCTIONS ****************************/ | ||
95 | /******************************************************************************/ | ||
96 | |||
97 | /** | ||
98 | * Task run during shutdown. | ||
99 | * | ||
100 | * @param cls unused | ||
101 | */ | ||
102 | static void | ||
103 | shutdown_task (void *cls) | ||
104 | { | ||
105 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shutting down\n"); | ||
106 | |||
107 | shutting_down = GNUNET_YES; | ||
108 | |||
109 | GML_shutdown (); | ||
110 | GCH_shutdown (); | ||
111 | GCC_shutdown (); | ||
112 | GCT_shutdown (); | ||
113 | GCD_shutdown (); | ||
114 | GCP_shutdown (); | ||
115 | |||
116 | GNUNET_STATISTICS_destroy (stats, GNUNET_NO); | ||
117 | stats = NULL; | ||
118 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shut down\n"); | ||
119 | } | ||
120 | |||
121 | |||
122 | /** | ||
123 | * Process cadet requests. | ||
124 | * | ||
125 | * @param cls closure | ||
126 | * @param server the initialized server | ||
127 | * @param c configuration to use | ||
128 | */ | ||
129 | static void | ||
130 | run (void *cls, struct GNUNET_SERVER_Handle *server, | ||
131 | const struct GNUNET_CONFIGURATION_Handle *c) | ||
132 | { | ||
133 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "starting to run\n"); | ||
134 | |||
135 | stats = GNUNET_STATISTICS_create ("cadet", c); | ||
136 | |||
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 | |||
149 | GML_init (server); /* Local clients */ | ||
150 | GCH_init (c); /* Hellos */ | ||
151 | GCC_init (c); /* Connections */ | ||
152 | GCP_init (c); /* Peers */ | ||
153 | GCD_init (c); /* DHT */ | ||
154 | GCT_init (c, my_private_key); /* Tunnels */ | ||
155 | |||
156 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cadet service running\n"); | ||
157 | } | ||
158 | |||
159 | |||
160 | /** | ||
161 | * The main function for the cadet service. | ||
162 | * | ||
163 | * @param argc number of arguments from the command line | ||
164 | * @param argv command line arguments | ||
165 | * @return 0 ok, 1 on error | ||
166 | */ | ||
167 | int | ||
168 | main (int argc, char *const *argv) | ||
169 | { | ||
170 | int r; | ||
171 | |||
172 | shutting_down = GNUNET_NO; | ||
173 | r = GNUNET_SERVICE_run (argc, argv, "cadet", GNUNET_SERVICE_OPTION_NONE, &run, | ||
174 | NULL); | ||
175 | GNUNET_free (my_private_key); | ||
176 | |||
177 | if (GNUNET_OK != r) | ||
178 | { | ||
179 | FPRINTF (stderr, "GNUNET_SERVICE_run for CADET has failed!\n"); | ||
180 | return 1; | ||
181 | } | ||
182 | |||
183 | return 0; | ||
184 | } | ||
diff --git a/src/cadet/gnunet-service-cadet_channel.c b/src/cadet/gnunet-service-cadet_channel.c deleted file mode 100644 index 7b7c6e57c..000000000 --- a/src/cadet/gnunet-service-cadet_channel.c +++ /dev/null | |||
@@ -1,2562 +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" | ||
29 | |||
30 | #include "gnunet-service-cadet_channel.h" | ||
31 | #include "gnunet-service-cadet_local.h" | ||
32 | #include "gnunet-service-cadet_tunnel.h" | ||
33 | #include "gnunet-service-cadet_peer.h" | ||
34 | |||
35 | #define LOG(level, ...) GNUNET_log_from(level,"cadet-chn",__VA_ARGS__) | ||
36 | #define LOG2(level, ...) GNUNET_log_from_nocheck(level,"cadet-chn",__VA_ARGS__) | ||
37 | |||
38 | #define CADET_RETRANSMIT_TIME GNUNET_TIME_relative_multiply(\ | ||
39 | GNUNET_TIME_UNIT_MILLISECONDS, 250) | ||
40 | #define CADET_RETRANSMIT_MARGIN 4 | ||
41 | |||
42 | |||
43 | /** | ||
44 | * All the states a connection can be in. | ||
45 | */ | ||
46 | enum CadetChannelState | ||
47 | { | ||
48 | /** | ||
49 | * Uninitialized status, should never appear in operation. | ||
50 | */ | ||
51 | CADET_CHANNEL_NEW, | ||
52 | |||
53 | /** | ||
54 | * Connection create message sent, waiting for ACK. | ||
55 | */ | ||
56 | CADET_CHANNEL_SENT, | ||
57 | |||
58 | /** | ||
59 | * Connection confirmed, ready to carry traffic. | ||
60 | */ | ||
61 | CADET_CHANNEL_READY | ||
62 | }; | ||
63 | |||
64 | |||
65 | /** | ||
66 | * Info holder for channel messages in queues. | ||
67 | */ | ||
68 | struct CadetChannelQueue | ||
69 | { | ||
70 | /** | ||
71 | * Tunnel Queue. | ||
72 | */ | ||
73 | struct CadetTunnelQueue *tq; | ||
74 | |||
75 | /** | ||
76 | * Message type (DATA/DATA_ACK) | ||
77 | */ | ||
78 | uint16_t type; | ||
79 | |||
80 | /** | ||
81 | * Message copy (for DATAs, to start retransmission timer) | ||
82 | */ | ||
83 | struct CadetReliableMessage *copy; | ||
84 | |||
85 | /** | ||
86 | * Reliability (for DATA_ACKs, to access rel->ack_q) | ||
87 | */ | ||
88 | struct CadetChannelReliability *rel; | ||
89 | }; | ||
90 | |||
91 | |||
92 | /** | ||
93 | * Info needed to retry a message in case it gets lost. | ||
94 | */ | ||
95 | struct CadetReliableMessage | ||
96 | { | ||
97 | /** | ||
98 | * Double linked list, FIFO style | ||
99 | */ | ||
100 | struct CadetReliableMessage *next; | ||
101 | struct CadetReliableMessage *prev; | ||
102 | |||
103 | /** | ||
104 | * Type of message (payload, channel management). | ||
105 | */ | ||
106 | int16_t type; | ||
107 | |||
108 | /** | ||
109 | * Tunnel Reliability queue this message is in. | ||
110 | */ | ||
111 | struct CadetChannelReliability *rel; | ||
112 | |||
113 | /** | ||
114 | * ID of the message (ACK needed to free) | ||
115 | */ | ||
116 | uint32_t mid; | ||
117 | |||
118 | /** | ||
119 | * Tunnel Queue. | ||
120 | */ | ||
121 | struct CadetChannelQueue *chq; | ||
122 | |||
123 | /** | ||
124 | * When was this message issued (to calculate ACK delay) | ||
125 | */ | ||
126 | struct GNUNET_TIME_Absolute timestamp; | ||
127 | |||
128 | /* struct GNUNET_CADET_ChannelAppDataMessage with payload */ | ||
129 | }; | ||
130 | |||
131 | |||
132 | /** | ||
133 | * Info about the traffic state for a client in a channel. | ||
134 | */ | ||
135 | struct CadetChannelReliability | ||
136 | { | ||
137 | /** | ||
138 | * Channel this is about. | ||
139 | */ | ||
140 | struct CadetChannel *ch; | ||
141 | |||
142 | /** | ||
143 | * DLL of messages sent and not yet ACK'd. | ||
144 | */ | ||
145 | struct CadetReliableMessage *head_sent; | ||
146 | struct CadetReliableMessage *tail_sent; | ||
147 | |||
148 | /** | ||
149 | * DLL of messages received out of order. | ||
150 | */ | ||
151 | struct CadetReliableMessage *head_recv; | ||
152 | struct CadetReliableMessage *tail_recv; | ||
153 | |||
154 | /** | ||
155 | * Messages received. | ||
156 | */ | ||
157 | unsigned int n_recv; | ||
158 | |||
159 | /** | ||
160 | * Next MID to use for outgoing traffic. | ||
161 | */ | ||
162 | uint32_t mid_send; | ||
163 | |||
164 | /** | ||
165 | * Next MID expected for incoming traffic. | ||
166 | */ | ||
167 | uint32_t mid_recv; | ||
168 | |||
169 | /** | ||
170 | * Handle for queued unique data CREATE, DATA_ACK. | ||
171 | */ | ||
172 | struct CadetChannelQueue *uniq; | ||
173 | |||
174 | /** | ||
175 | * Can we send data to the client? | ||
176 | */ | ||
177 | int client_ready; | ||
178 | |||
179 | /** | ||
180 | * Can the client send data to us? | ||
181 | */ | ||
182 | int client_allowed; | ||
183 | |||
184 | /** | ||
185 | * Task to resend/poll in case no ACK is received. | ||
186 | */ | ||
187 | struct GNUNET_SCHEDULER_Task * retry_task; | ||
188 | |||
189 | /** | ||
190 | * Counter for exponential backoff. | ||
191 | */ | ||
192 | struct GNUNET_TIME_Relative retry_timer; | ||
193 | |||
194 | /** | ||
195 | * How long does it usually take to get an ACK. | ||
196 | */ | ||
197 | struct GNUNET_TIME_Relative expected_delay; | ||
198 | }; | ||
199 | |||
200 | |||
201 | /** | ||
202 | * Struct containing all information regarding a channel to a remote client. | ||
203 | */ | ||
204 | struct CadetChannel | ||
205 | { | ||
206 | /** | ||
207 | * Tunnel this channel is in. | ||
208 | */ | ||
209 | struct CadetTunnel *t; | ||
210 | |||
211 | /** | ||
212 | * Destination port of the channel. | ||
213 | */ | ||
214 | struct GNUNET_HashCode port; | ||
215 | |||
216 | /** | ||
217 | * Global channel number ( < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI) | ||
218 | */ | ||
219 | struct GNUNET_CADET_ChannelTunnelNumber gid; | ||
220 | |||
221 | /** | ||
222 | * Local tunnel number for root (owner) client. | ||
223 | * ( >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI or 0 ) | ||
224 | */ | ||
225 | struct GNUNET_CADET_ClientChannelNumber lid_root; | ||
226 | |||
227 | /** | ||
228 | * Local tunnel number for local destination clients (incoming number) | ||
229 | * ( >= GNUNET_CADET_LOCAL_CHANNEL_ID_SERV or 0). | ||
230 | */ | ||
231 | struct GNUNET_CADET_ClientChannelNumber lid_dest; | ||
232 | |||
233 | /** | ||
234 | * Channel state. | ||
235 | */ | ||
236 | enum CadetChannelState state; | ||
237 | |||
238 | /** | ||
239 | * Is the tunnel bufferless (minimum latency)? | ||
240 | */ | ||
241 | int nobuffer; | ||
242 | |||
243 | /** | ||
244 | * Is the tunnel reliable? | ||
245 | */ | ||
246 | int reliable; | ||
247 | |||
248 | /** | ||
249 | * Last time the channel was used | ||
250 | */ | ||
251 | struct GNUNET_TIME_Absolute timestamp; | ||
252 | |||
253 | /** | ||
254 | * Client owner of the tunnel, if any | ||
255 | */ | ||
256 | struct CadetClient *root; | ||
257 | |||
258 | /** | ||
259 | * Client destination of the tunnel, if any. | ||
260 | */ | ||
261 | struct CadetClient *dest; | ||
262 | |||
263 | /** | ||
264 | * Flag to signal the destruction of the channel. | ||
265 | * If this is set to #GNUNET_YES the channel will be destroyed | ||
266 | * when the queue is empty. | ||
267 | */ | ||
268 | int destroy; | ||
269 | |||
270 | /** | ||
271 | * Total (reliable) messages pending ACK for this channel. | ||
272 | */ | ||
273 | unsigned int pending_messages; | ||
274 | |||
275 | /** | ||
276 | * Reliability data. | ||
277 | * Only present (non-NULL) at the owner of a tunnel. | ||
278 | */ | ||
279 | struct CadetChannelReliability *root_rel; | ||
280 | |||
281 | /** | ||
282 | * Reliability data. | ||
283 | * Only present (non-NULL) at the destination of a tunnel. | ||
284 | */ | ||
285 | struct CadetChannelReliability *dest_rel; | ||
286 | |||
287 | }; | ||
288 | |||
289 | |||
290 | /******************************************************************************/ | ||
291 | /******************************* GLOBALS ***********************************/ | ||
292 | /******************************************************************************/ | ||
293 | |||
294 | /** | ||
295 | * Global handle to the statistics service. | ||
296 | */ | ||
297 | extern struct GNUNET_STATISTICS_Handle *stats; | ||
298 | |||
299 | /** | ||
300 | * Local peer own ID (memory efficient handle). | ||
301 | */ | ||
302 | extern GNUNET_PEER_Id myid; | ||
303 | |||
304 | |||
305 | /******************************************************************************/ | ||
306 | /******************************** STATIC ***********************************/ | ||
307 | /******************************************************************************/ | ||
308 | |||
309 | |||
310 | /** | ||
311 | * Destroy a reliable message after it has been acknowledged, either by | ||
312 | * direct mid ACK or bitfield. Updates the appropriate data structures and | ||
313 | * timers and frees all memory. | ||
314 | * | ||
315 | * @param copy Message that is no longer needed: remote peer got it. | ||
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 | * | ||
321 | * @return #GNUNET_YES if channel was destroyed as a result of the call, | ||
322 | * #GNUNET_NO otherwise. | ||
323 | */ | ||
324 | static int | ||
325 | rel_message_free (struct CadetReliableMessage *copy, int update_time); | ||
326 | |||
327 | /** | ||
328 | * send a channel create message. | ||
329 | * | ||
330 | * @param ch Channel for which to send. | ||
331 | */ | ||
332 | static void | ||
333 | send_create (struct CadetChannel *ch); | ||
334 | |||
335 | /** | ||
336 | * Confirm we got a channel create, FWD ack. | ||
337 | * | ||
338 | * @param ch The channel to confirm. | ||
339 | * @param fwd Should we send a FWD ACK? (going dest->root) | ||
340 | */ | ||
341 | static void | ||
342 | send_ack (struct CadetChannel *ch, int fwd); | ||
343 | |||
344 | |||
345 | |||
346 | /** | ||
347 | * Test if the channel is loopback: both root and dest are on the local peer. | ||
348 | * | ||
349 | * @param ch Channel to test. | ||
350 | * | ||
351 | * @return #GNUNET_YES if channel is loopback, #GNUNET_NO otherwise. | ||
352 | */ | ||
353 | static int | ||
354 | is_loopback (const struct CadetChannel *ch) | ||
355 | { | ||
356 | if (NULL != ch->t) | ||
357 | return GCT_is_loopback (ch->t); | ||
358 | |||
359 | return (NULL != ch->root && NULL != ch->dest); | ||
360 | } | ||
361 | |||
362 | |||
363 | /** | ||
364 | * Save a copy of the data message for later retransmission. | ||
365 | * | ||
366 | * @param msg Message to copy. | ||
367 | * @param mid Message ID. | ||
368 | * @param rel Reliability data for retransmission. | ||
369 | */ | ||
370 | static struct CadetReliableMessage * | ||
371 | copy_message (const struct GNUNET_CADET_ChannelAppDataMessage *msg, uint32_t mid, | ||
372 | struct CadetChannelReliability *rel) | ||
373 | { | ||
374 | struct CadetReliableMessage *copy; | ||
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 (©[1], msg, size); | ||
383 | |||
384 | return copy; | ||
385 | } | ||
386 | |||
387 | /** | ||
388 | * We have received a message out of order, or the client is not ready. | ||
389 | * Buffer it until we receive an ACK from the client or the missing | ||
390 | * message from the channel. | ||
391 | * | ||
392 | * @param msg Message to buffer (MUST be of type CADET_DATA). | ||
393 | * @param rel Reliability data to the corresponding direction. | ||
394 | */ | ||
395 | static void | ||
396 | add_buffered_data (const struct GNUNET_CADET_ChannelAppDataMessage *msg, | ||
397 | struct CadetChannelReliability *rel) | ||
398 | { | ||
399 | struct CadetReliableMessage *copy; | ||
400 | struct CadetReliableMessage *prev; | ||
401 | uint32_t mid; | ||
402 | |||
403 | mid = ntohl (msg->mid); | ||
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 | { | ||
414 | LOG (GNUNET_ERROR_TYPE_DEBUG, " prev %u\n", prev->mid); | ||
415 | if (prev->mid == mid) | ||
416 | { | ||
417 | LOG (GNUNET_ERROR_TYPE_DEBUG, " already there!\n"); | ||
418 | rel->n_recv--; | ||
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 | } | ||
429 | } | ||
430 | copy = copy_message (msg, mid, rel); | ||
431 | LOG (GNUNET_ERROR_TYPE_DEBUG, " insert at tail! (now: %u)\n", rel->n_recv); | ||
432 | GNUNET_CONTAINER_DLL_insert_tail (rel->head_recv, rel->tail_recv, copy); | ||
433 | LOG (GNUNET_ERROR_TYPE_DEBUG, "add_buffered_data END\n"); | ||
434 | } | ||
435 | |||
436 | |||
437 | /** | ||
438 | * Add a destination client to a channel, initializing all data structures | ||
439 | * in the channel and the client. | ||
440 | * | ||
441 | * @param ch Channel to which add the destination. | ||
442 | * @param c Client which to add to the channel. | ||
443 | */ | ||
444 | static void | ||
445 | add_destination (struct CadetChannel *ch, struct CadetClient *c) | ||
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 | |||
468 | |||
469 | /** | ||
470 | * Set options in a channel, extracted from a bit flag field. | ||
471 | * | ||
472 | * @param ch Channel to set options to. | ||
473 | * @param options Bit array in host byte order. | ||
474 | */ | ||
475 | static void | ||
476 | channel_set_options (struct CadetChannel *ch, uint32_t options) | ||
477 | { | ||
478 | ch->nobuffer = (options & GNUNET_CADET_OPTION_NOBUFFER) != 0 ? | ||
479 | GNUNET_YES : GNUNET_NO; | ||
480 | ch->reliable = (options & GNUNET_CADET_OPTION_RELIABLE) != 0 ? | ||
481 | GNUNET_YES : GNUNET_NO; | ||
482 | } | ||
483 | |||
484 | |||
485 | /** | ||
486 | * Get a bit flag field with the options of a channel. | ||
487 | * | ||
488 | * @param ch Channel to get options from. | ||
489 | * | ||
490 | * @return Bit array in host byte order. | ||
491 | */ | ||
492 | static uint32_t | ||
493 | channel_get_options (struct CadetChannel *ch) | ||
494 | { | ||
495 | uint32_t options; | ||
496 | |||
497 | options = 0; | ||
498 | if (ch->nobuffer) | ||
499 | options |= GNUNET_CADET_OPTION_NOBUFFER; | ||
500 | if (ch->reliable) | ||
501 | options |= GNUNET_CADET_OPTION_RELIABLE; | ||
502 | |||
503 | return options; | ||
504 | } | ||
505 | |||
506 | |||
507 | /** | ||
508 | * Notify a client that the channel is no longer valid. | ||
509 | * | ||
510 | * @param ch Channel that is destroyed. | ||
511 | * @param local_only Should we avoid sending it to other peers? | ||
512 | */ | ||
513 | static void | ||
514 | send_destroy (struct CadetChannel *ch, int local_only) | ||
515 | { | ||
516 | struct GNUNET_CADET_ChannelManageMessage msg; | ||
517 | |||
518 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY); | ||
519 | msg.header.size = htons (sizeof (msg)); | ||
520 | msg.ctn = ch->gid; | ||
521 | |||
522 | /* If root is not NULL, notify. | ||
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 | } | ||
537 | |||
538 | |||
539 | /** | ||
540 | * Notify the destination client that a new incoming channel was created. | ||
541 | * | ||
542 | * @param ch Channel that was created. | ||
543 | */ | ||
544 | static void | ||
545 | send_client_create (struct CadetChannel *ch) | ||
546 | { | ||
547 | uint32_t opt; | ||
548 | |||
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 | |||
563 | |||
564 | /** | ||
565 | * Send data to a client. | ||
566 | * | ||
567 | * If the client is ready, send directly, otherwise buffer while listening | ||
568 | * for a local ACK. | ||
569 | * | ||
570 | * @param ch Channel | ||
571 | * @param msg Message. | ||
572 | * @param fwd Is this a fwd (root->dest) message? | ||
573 | */ | ||
574 | static void | ||
575 | send_client_data (struct CadetChannel *ch, | ||
576 | const struct GNUNET_CADET_ChannelAppDataMessage *msg, | ||
577 | int fwd) | ||
578 | { | ||
579 | if (fwd) | ||
580 | { | ||
581 | if (ch->dest_rel->client_ready) | ||
582 | { | ||
583 | GML_send_data (ch->dest, msg, ch->lid_dest); | ||
584 | ch->dest_rel->client_ready = GNUNET_NO; | ||
585 | ch->dest_rel->mid_recv++; | ||
586 | } | ||
587 | else | ||
588 | add_buffered_data (msg, ch->dest_rel); | ||
589 | } | ||
590 | else | ||
591 | { | ||
592 | if (ch->root_rel->client_ready) | ||
593 | { | ||
594 | GML_send_data (ch->root, msg, ch->lid_root); | ||
595 | ch->root_rel->client_ready = GNUNET_NO; | ||
596 | ch->root_rel->mid_recv++; | ||
597 | } | ||
598 | else | ||
599 | add_buffered_data (msg, ch->root_rel); | ||
600 | } | ||
601 | } | ||
602 | |||
603 | |||
604 | /** | ||
605 | * Send a buffered message to the client, for in order delivery or | ||
606 | * as result of client ACK. | ||
607 | * | ||
608 | * @param ch Channel on which to empty the message buffer. | ||
609 | * @param c Client to send to. | ||
610 | * @param fwd Is this to send FWD data?. | ||
611 | */ | ||
612 | static void | ||
613 | send_client_buffered_data (struct CadetChannel *ch, | ||
614 | struct CadetClient *c, | ||
615 | int fwd) | ||
616 | { | ||
617 | struct CadetReliableMessage *copy; | ||
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 | |||
628 | copy = rel->head_recv; | ||
629 | /* We never buffer channel management messages */ | ||
630 | if (NULL != copy) | ||
631 | { | ||
632 | if (copy->mid == rel->mid_recv || GNUNET_NO == ch->reliable) | ||
633 | { | ||
634 | struct GNUNET_CADET_ChannelAppDataMessage *msg = (struct GNUNET_CADET_ChannelAppDataMessage *) ©[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 | } | ||
664 | |||
665 | |||
666 | /** | ||
667 | * Allow a client to send more data. | ||
668 | * | ||
669 | * In case the client was already allowed to send data, do nothing. | ||
670 | * | ||
671 | * @param ch Channel. | ||
672 | * @param fwd Is this a FWD ACK? (FWD ACKs are sent to root) | ||
673 | */ | ||
674 | static void | ||
675 | send_client_ack (struct CadetChannel *ch, int fwd) | ||
676 | { | ||
677 | struct CadetChannelReliability *rel = fwd ? ch->root_rel : ch->dest_rel; | ||
678 | struct CadetClient *c = fwd ? ch->root : ch->dest; | ||
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 | |||
689 | if (NULL == rel) | ||
690 | { | ||
691 | GNUNET_break (0); | ||
692 | return; | ||
693 | } | ||
694 | |||
695 | if (GNUNET_YES == rel->client_allowed) | ||
696 | { | ||
697 | LOG (GNUNET_ERROR_TYPE_DEBUG, " already allowed\n"); | ||
698 | return; | ||
699 | } | ||
700 | rel->client_allowed = GNUNET_YES; | ||
701 | |||
702 | GML_send_ack (c, fwd ? ch->lid_root : ch->lid_dest); | ||
703 | } | ||
704 | |||
705 | |||
706 | /** | ||
707 | * Notify the root that the destination rejected the channel. | ||
708 | * | ||
709 | * @param ch Rejected channel. | ||
710 | */ | ||
711 | static void | ||
712 | send_client_nack (struct CadetChannel *ch) | ||
713 | { | ||
714 | if (NULL == ch->root) | ||
715 | { | ||
716 | GNUNET_break (0); | ||
717 | return; | ||
718 | } | ||
719 | GML_send_channel_nack (ch->root, ch->lid_root); | ||
720 | } | ||
721 | |||
722 | |||
723 | /** | ||
724 | * We haven't received an ACK after a certain time: restransmit the message. | ||
725 | * | ||
726 | * @param cls Closure (CadetChannelReliability with the message to restransmit) | ||
727 | */ | ||
728 | static void | ||
729 | channel_retransmit_message (void *cls) | ||
730 | { | ||
731 | struct CadetChannelReliability *rel = cls; | ||
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 *) ©[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 | |||
752 | GCCH_send_prebuilt_message (&payload->header, ch, fwd, copy); | ||
753 | GNUNET_STATISTICS_update (stats, "# data retransmitted", 1, GNUNET_NO); | ||
754 | } | ||
755 | |||
756 | |||
757 | /** | ||
758 | * We haven't received an Channel ACK after a certain time: resend the CREATE. | ||
759 | * | ||
760 | * @param cls Closure (CadetChannelReliability of the channel to recreate) | ||
761 | */ | ||
762 | static void | ||
763 | channel_recreate (void *cls) | ||
764 | { | ||
765 | struct CadetChannelReliability *rel = cls; | ||
766 | |||
767 | rel->retry_task = NULL; | ||
768 | LOG (GNUNET_ERROR_TYPE_DEBUG, "RE-CREATE\n"); | ||
769 | GNUNET_STATISTICS_update (stats, | ||
770 | "# data retransmitted", 1, GNUNET_NO); | ||
771 | |||
772 | if (rel == rel->ch->root_rel) | ||
773 | { | ||
774 | send_create (rel->ch); | ||
775 | } | ||
776 | else if (rel == rel->ch->dest_rel) | ||
777 | { | ||
778 | send_ack (rel->ch, GNUNET_YES); | ||
779 | } | ||
780 | else | ||
781 | { | ||
782 | GNUNET_break (0); | ||
783 | } | ||
784 | } | ||
785 | |||
786 | |||
787 | /** | ||
788 | * Message has been sent: start retransmission timer. | ||
789 | * | ||
790 | * @param cls Closure (queue structure). | ||
791 | * @param t Tunnel. | ||
792 | * @param q Queue handler (no longer valid). | ||
793 | * @param type Type of message. | ||
794 | * @param size Size of the message. | ||
795 | */ | ||
796 | static void | ||
797 | ch_message_sent (void *cls, | ||
798 | struct CadetTunnel *t, | ||
799 | struct CadetTunnelQueue *q, | ||
800 | uint16_t type, size_t size) | ||
801 | { | ||
802 | struct CadetChannelQueue *chq = cls; | ||
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 | { | ||
811 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA: | ||
812 | LOG (GNUNET_ERROR_TYPE_DEBUG, "data MID %u sent\n", copy->mid); | ||
813 | GNUNET_assert (chq == copy->chq); | ||
814 | copy->timestamp = GNUNET_TIME_absolute_get (); | ||
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 | } | ||
872 | |||
873 | GNUNET_free (chq); | ||
874 | } | ||
875 | |||
876 | |||
877 | /** | ||
878 | * send a channel create message. | ||
879 | * | ||
880 | * @param ch Channel for which to send. | ||
881 | */ | ||
882 | static void | ||
883 | send_create (struct CadetChannel *ch) | ||
884 | { | ||
885 | struct GNUNET_CADET_ChannelOpenMessage msgcc; | ||
886 | |||
887 | msgcc.header.size = htons (sizeof (msgcc)); | ||
888 | msgcc.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN); | ||
889 | msgcc.ctn = ch->gid; | ||
890 | msgcc.port = ch->port; | ||
891 | msgcc.opt = htonl (channel_get_options (ch)); | ||
892 | |||
893 | GCCH_send_prebuilt_message (&msgcc.header, ch, GNUNET_YES, NULL); | ||
894 | } | ||
895 | |||
896 | |||
897 | /** | ||
898 | * Confirm we got a channel create or FWD ack. | ||
899 | * | ||
900 | * @param ch The channel to confirm. | ||
901 | * @param fwd Should we send a FWD ACK? (going dest->root) | ||
902 | */ | ||
903 | static void | ||
904 | send_ack (struct CadetChannel *ch, int fwd) | ||
905 | { | ||
906 | struct GNUNET_CADET_ChannelManageMessage msg; | ||
907 | |||
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, | ||
911 | " sending channel %s ack for channel %s\n", | ||
912 | GC_f2s (fwd), GCCH_2s (ch)); | ||
913 | |||
914 | msg.ctn =ch->gid; | ||
915 | GCCH_send_prebuilt_message (&msg.header, ch, !fwd, NULL); | ||
916 | } | ||
917 | |||
918 | |||
919 | /** | ||
920 | * Send a message and don't keep any info about it: we won't need to cancel it | ||
921 | * or resend it. | ||
922 | * | ||
923 | * @param msg Header of the message to fire away. | ||
924 | * @param ch Channel on which the message should go. | ||
925 | * @param force Is this a forced (undroppable) message? | ||
926 | */ | ||
927 | static void | ||
928 | fire_and_forget (const struct GNUNET_MessageHeader *msg, | ||
929 | struct CadetChannel *ch, | ||
930 | int force) | ||
931 | { | ||
932 | GNUNET_break (NULL == | ||
933 | GCT_send_prebuilt_message (msg, ch->t, NULL, | ||
934 | force, NULL, NULL)); | ||
935 | } | ||
936 | |||
937 | |||
938 | /** | ||
939 | * Notify that a channel create didn't succeed. | ||
940 | * | ||
941 | * @param ch The channel to reject. | ||
942 | */ | ||
943 | static void | ||
944 | send_nack (struct CadetChannel *ch) | ||
945 | { | ||
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, | ||
951 | " sending channel NACK for channel %s\n", | ||
952 | GCCH_2s (ch)); | ||
953 | |||
954 | msg.ctn = ch->gid; | ||
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 | */ | ||
966 | static void | ||
967 | channel_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 | { | ||
977 | next = copy->next; | ||
978 | GNUNET_CONTAINER_DLL_remove (rel->head_recv, rel->tail_recv, copy); | ||
979 | LOG (GNUNET_ERROR_TYPE_DEBUG, " COPYFREE ALL RECV %p\n", copy); | ||
980 | GNUNET_break (NULL == copy->chq); | ||
981 | GNUNET_free (copy); | ||
982 | } | ||
983 | for (copy = rel->head_sent; NULL != copy; copy = next) | ||
984 | { | ||
985 | next = copy->next; | ||
986 | GNUNET_CONTAINER_DLL_remove (rel->head_sent, rel->tail_sent, copy); | ||
987 | LOG (GNUNET_ERROR_TYPE_DEBUG, " COPYFREE ALL SEND %p\n", copy); | ||
988 | if (NULL != copy->chq) | ||
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 | } | ||
1003 | if (NULL != rel->uniq && NULL != rel->uniq->tq) | ||
1004 | { | ||
1005 | GCT_cancel (rel->uniq->tq); | ||
1006 | /* ch_message_sent is called freeing uniq */ | ||
1007 | } | ||
1008 | if (NULL != rel->retry_task) | ||
1009 | { | ||
1010 | GNUNET_SCHEDULER_cancel (rel->retry_task); | ||
1011 | rel->retry_task = NULL; | ||
1012 | } | ||
1013 | GNUNET_free (rel); | ||
1014 | } | ||
1015 | |||
1016 | |||
1017 | /** | ||
1018 | * Mark future messages as ACK'd. | ||
1019 | * | ||
1020 | * @param rel Reliability data. | ||
1021 | * @param msg DataACK message with a bitfield of future ACK'd messages. | ||
1022 | * | ||
1023 | * @return How many messages have been freed. | ||
1024 | */ | ||
1025 | static unsigned int | ||
1026 | channel_rel_free_sent (struct CadetChannelReliability *rel, | ||
1027 | const struct GNUNET_CADET_ChannelDataAckMessage *msg) | ||
1028 | { | ||
1029 | struct CadetReliableMessage *copy; | ||
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 | { | ||
1046 | LOG (GNUNET_ERROR_TYPE_DEBUG, " trying bit %u (mid %u)\n", i, mid + i + 1); | ||
1047 | mask = 0x1LL << i; | ||
1048 | if (0 == (bitfield & mask)) | ||
1049 | continue; | ||
1050 | |||
1051 | LOG (GNUNET_ERROR_TYPE_DEBUG, " set!\n"); | ||
1052 | /* Bit was set, clear the bit from the bitfield */ | ||
1053 | bitfield &= ~mask; | ||
1054 | |||
1055 | /* The i-th bit was set. Do we have that copy? */ | ||
1056 | /* Skip copies with mid < target */ | ||
1057 | target = mid + i + 1; | ||
1058 | LOG (GNUNET_ERROR_TYPE_DEBUG, " target %u\n", target); | ||
1059 | while (NULL != copy && GC_is_pid_bigger (target, copy->mid)) | ||
1060 | copy = copy->next; | ||
1061 | |||
1062 | /* Did we run out of copies? (previously freed, it's ok) */ | ||
1063 | if (NULL == copy) | ||
1064 | { | ||
1065 | LOG (GNUNET_ERROR_TYPE_DEBUG, "run out of copies...\n"); | ||
1066 | return r; | ||
1067 | } | ||
1068 | |||
1069 | /* Did we overshoot the target? (previously freed, it's ok) */ | ||
1070 | if (GC_is_pid_bigger (copy->mid, target)) | ||
1071 | { | ||
1072 | LOG (GNUNET_ERROR_TYPE_DEBUG, " next copy %u\n", copy->mid); | ||
1073 | i += copy->mid - target - 1; /* MID: 90, t = 85, i += 4 (i++ later) */ | ||
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 | } | ||
1078 | |||
1079 | /* Now copy->mid == target, free it */ | ||
1080 | next = copy->next; | ||
1081 | GNUNET_break (GNUNET_YES != rel_message_free (copy, GNUNET_YES)); | ||
1082 | r++; | ||
1083 | copy = next; | ||
1084 | } | ||
1085 | LOG (GNUNET_ERROR_TYPE_DEBUG, "free_sent_reliable END\n"); | ||
1086 | return r; | ||
1087 | } | ||
1088 | |||
1089 | |||
1090 | /** | ||
1091 | * Destroy a reliable message after it has been acknowledged, either by | ||
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 | * | ||
1101 | * @return #GNUNET_YES if channel was destroyed as a result of the call, | ||
1102 | * #GNUNET_NO otherwise. | ||
1103 | */ | ||
1104 | static int | ||
1105 | rel_message_free (struct CadetReliableMessage *copy, int update_time) | ||
1106 | { | ||
1107 | struct CadetChannelReliability *rel; | ||
1108 | struct GNUNET_TIME_Relative time; | ||
1109 | |||
1110 | rel = copy->rel; | ||
1111 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Freeing %u\n", copy->mid); | ||
1112 | if (GNUNET_YES == update_time) | ||
1113 | { | ||
1114 | time = GNUNET_TIME_absolute_get_duration (copy->timestamp); | ||
1115 | if (0 == rel->expected_delay.rel_value_us) | ||
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 | } | ||
1130 | else | ||
1131 | { | ||
1132 | LOG (GNUNET_ERROR_TYPE_DEBUG, "batch free, ignoring timing\n"); | ||
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; | ||
1149 | } | ||
1150 | return GNUNET_NO; | ||
1151 | } | ||
1152 | |||
1153 | |||
1154 | /** | ||
1155 | * Channel was ACK'd by remote peer, mark as ready and cancel retransmission. | ||
1156 | * | ||
1157 | * @param ch Channel to mark as ready. | ||
1158 | * @param fwd Was the ACK message a FWD ACK? (dest->root, SYNACK) | ||
1159 | */ | ||
1160 | static void | ||
1161 | channel_confirm (struct CadetChannel *ch, int fwd) | ||
1162 | { | ||
1163 | struct CadetChannelReliability *rel; | ||
1164 | enum CadetChannelState oldstate; | ||
1165 | |||
1166 | rel = fwd ? ch->root_rel : ch->dest_rel; | ||
1167 | if (NULL == rel) | ||
1168 | { | ||
1169 | GNUNET_break (GNUNET_NO != ch->destroy); | ||
1170 | return; | ||
1171 | } | ||
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 | |||
1177 | if (CADET_CHANNEL_READY != oldstate || GNUNET_YES == is_loopback (ch)) | ||
1178 | { | ||
1179 | rel->client_ready = GNUNET_YES; | ||
1180 | rel->expected_delay = rel->retry_timer; | ||
1181 | LOG (GNUNET_ERROR_TYPE_DEBUG, " confirm retry timer %s\n", | ||
1182 | GNUNET_STRINGS_relative_time_to_string (rel->retry_timer, GNUNET_NO)); | ||
1183 | if (GCT_get_connections_buffer (ch->t) > 0 || GCT_is_loopback (ch->t)) | ||
1184 | send_client_ack (ch, fwd); | ||
1185 | |||
1186 | if (NULL != rel->retry_task) | ||
1187 | { | ||
1188 | GNUNET_SCHEDULER_cancel (rel->retry_task); | ||
1189 | rel->retry_task = NULL; | ||
1190 | } | ||
1191 | else if (NULL != rel->uniq) | ||
1192 | { | ||
1193 | GCT_cancel (rel->uniq->tq); | ||
1194 | /* ch_message_sent will free and NULL uniq */ | ||
1195 | } | ||
1196 | else if (GNUNET_NO == is_loopback (ch)) | ||
1197 | { | ||
1198 | /* We SHOULD have been trying to retransmit this! */ | ||
1199 | GNUNET_break (0); | ||
1200 | } | ||
1201 | } | ||
1202 | |||
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 | */ | ||
1218 | static struct CadetReliableMessage * | ||
1219 | channel_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 (©[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 | */ | ||
1257 | static struct CadetChannel * | ||
1258 | channel_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 | */ | ||
1289 | void | ||
1290 | handle_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 | { | ||
1303 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA: | ||
1304 | /* Don't send hop ACK, wait for client to ACK */ | ||
1305 | LOG (GNUNET_ERROR_TYPE_DEBUG, "SEND loopback %u (%u)\n", | ||
1306 | ntohl (((struct GNUNET_CADET_ChannelAppDataMessage *) msgh)->mid), ntohs (msgh->size)); | ||
1307 | GCCH_handle_data (ch, (struct GNUNET_CADET_ChannelAppDataMessage *) msgh, fwd); | ||
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 | |||
1336 | default: | ||
1337 | GNUNET_break_op (0); | ||
1338 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1339 | "end-to-end message not known (%u)\n", | ||
1340 | ntohs (msgh->type)); | ||
1341 | } | ||
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 | */ | ||
1355 | void | ||
1356 | GCCH_destroy (struct CadetChannel *ch) | ||
1357 | { | ||
1358 | struct CadetClient *c; | ||
1359 | struct CadetTunnel *t; | ||
1360 | |||
1361 | if (NULL == ch) | ||
1362 | 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 | } | ||
1376 | |||
1377 | c = ch->dest; | ||
1378 | if (NULL != c) | ||
1379 | { | ||
1380 | GML_channel_remove (c, ch->lid_dest, ch); | ||
1381 | } | ||
1382 | |||
1383 | channel_rel_free_all (ch->root_rel); | ||
1384 | channel_rel_free_all (ch->dest_rel); | ||
1385 | |||
1386 | t = ch->t; | ||
1387 | GCT_remove_channel (t, ch); | ||
1388 | GNUNET_STATISTICS_update (stats, "# channels", -1, GNUNET_NO); | ||
1389 | |||
1390 | GNUNET_free (ch); | ||
1391 | GCT_destroy_if_empty (t); | ||
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 | */ | ||
1402 | struct GNUNET_CADET_ChannelTunnelNumber | ||
1403 | GCCH_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 | */ | ||
1416 | struct CadetTunnel * | ||
1417 | GCCH_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 | */ | ||
1431 | unsigned int | ||
1432 | GCCH_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 | */ | ||
1462 | int | ||
1463 | GCCH_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 | } | ||
1478 | |||
1479 | |||
1480 | /** | ||
1481 | * Is the root client for this channel on this peer? | ||
1482 | * | ||
1483 | * @param ch Channel. | ||
1484 | * @param fwd Is this for fwd traffic? | ||
1485 | * | ||
1486 | * @return #GNUNET_YES in case it is. | ||
1487 | */ | ||
1488 | int | ||
1489 | GCCH_is_origin (struct CadetChannel *ch, int fwd) | ||
1490 | { | ||
1491 | struct CadetClient *c; | ||
1492 | |||
1493 | c = fwd ? ch->root : ch->dest; | ||
1494 | return NULL != c; | ||
1495 | } | ||
1496 | |||
1497 | |||
1498 | /** | ||
1499 | * Is the destination client for this channel on this peer? | ||
1500 | * | ||
1501 | * @param ch Channel. | ||
1502 | * @param fwd Is this for fwd traffic? | ||
1503 | * | ||
1504 | * @return #GNUNET_YES in case it is. | ||
1505 | */ | ||
1506 | int | ||
1507 | GCCH_is_terminal (struct CadetChannel *ch, int fwd) | ||
1508 | { | ||
1509 | struct CadetClient *c; | ||
1510 | |||
1511 | c = fwd ? ch->dest : ch->root; | ||
1512 | return NULL != c; | ||
1513 | } | ||
1514 | |||
1515 | |||
1516 | /** | ||
1517 | * Send an end-to-end ACK message for the most recent in-sequence payload. | ||
1518 | * | ||
1519 | * If channel is not reliable, do nothing. | ||
1520 | * | ||
1521 | * @param ch Channel this is about. | ||
1522 | * @param fwd Is for FWD traffic? (ACK dest->owner) | ||
1523 | */ | ||
1524 | void | ||
1525 | GCCH_send_data_ack (struct CadetChannel *ch, int fwd) | ||
1526 | { | ||
1527 | struct GNUNET_CADET_ChannelDataAckMessage msg; | ||
1528 | struct CadetChannelReliability *rel; | ||
1529 | struct CadetReliableMessage *copy; | ||
1530 | unsigned int delta; | ||
1531 | uint64_t mask; | ||
1532 | uint32_t ack; | ||
1533 | |||
1534 | if (GNUNET_NO == ch->reliable) | ||
1535 | return; | ||
1536 | |||
1537 | rel = fwd ? ch->dest_rel : ch->root_rel; | ||
1538 | ack = rel->mid_recv - 1; | ||
1539 | |||
1540 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK); | ||
1541 | msg.header.size = htons (sizeof (msg)); | ||
1542 | msg.ctn = ch->gid; | ||
1543 | msg.mid = htonl (ack); | ||
1544 | |||
1545 | msg.futures = 0LL; | ||
1546 | for (copy = rel->head_recv; NULL != copy; copy = copy->next) | ||
1547 | { | ||
1548 | if (copy->type != GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA) | ||
1549 | { | ||
1550 | LOG (GNUNET_ERROR_TYPE_DEBUG, " Type %s, expected DATA\n", | ||
1551 | GC_m2s (copy->type)); | ||
1552 | continue; | ||
1553 | } | ||
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 | } | ||
1564 | |||
1565 | GCCH_send_prebuilt_message (&msg.header, ch, !fwd, NULL); | ||
1566 | LOG (GNUNET_ERROR_TYPE_DEBUG, "send_data_ack END\n"); | ||
1567 | } | ||
1568 | |||
1569 | |||
1570 | /** | ||
1571 | * Allow a client to send us more data, in case it was choked. | ||
1572 | * | ||
1573 | * @param ch Channel. | ||
1574 | * @param fwd Is this about FWD traffic? (Root client). | ||
1575 | */ | ||
1576 | void | ||
1577 | GCCH_allow_client (struct CadetChannel *ch, int fwd) | ||
1578 | { | ||
1579 | struct CadetChannelReliability *rel; | ||
1580 | unsigned int buffer; | ||
1581 | |||
1582 | LOG (GNUNET_ERROR_TYPE_DEBUG, "GMCH allow\n"); | ||
1583 | |||
1584 | if (CADET_CHANNEL_READY != ch->state) | ||
1585 | { | ||
1586 | LOG (GNUNET_ERROR_TYPE_DEBUG, " channel not ready yet!\n"); | ||
1587 | return; | ||
1588 | } | ||
1589 | |||
1590 | if (GNUNET_YES == ch->reliable) | ||
1591 | { | ||
1592 | rel = fwd ? ch->root_rel : ch->dest_rel; | ||
1593 | if (NULL == rel) | ||
1594 | { | ||
1595 | GNUNET_break (GNUNET_NO != ch->destroy); | ||
1596 | return; | ||
1597 | } | ||
1598 | if (NULL != rel->head_sent) | ||
1599 | { | ||
1600 | if (64 <= rel->mid_send - rel->head_sent->mid) | ||
1601 | { | ||
1602 | LOG (GNUNET_ERROR_TYPE_DEBUG, " too big MID gap! Wait for ACK.\n"); | ||
1603 | return; | ||
1604 | } | ||
1605 | else | ||
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 | } | ||
1616 | else | ||
1617 | { | ||
1618 | LOG (GNUNET_ERROR_TYPE_DEBUG, " head sent is NULL\n"); | ||
1619 | } | ||
1620 | } | ||
1621 | |||
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 | { | ||
1629 | LOG (GNUNET_ERROR_TYPE_DEBUG, " no buffer space.\n"); | ||
1630 | return; | ||
1631 | } | ||
1632 | |||
1633 | LOG (GNUNET_ERROR_TYPE_DEBUG, " buffer space %u, allowing\n", buffer); | ||
1634 | send_client_ack (ch, fwd); | ||
1635 | } | ||
1636 | |||
1637 | |||
1638 | /** | ||
1639 | * Log channel info. | ||
1640 | * | ||
1641 | * @param ch Channel. | ||
1642 | * @param level Debug level to use. | ||
1643 | */ | ||
1644 | void | ||
1645 | GCCH_debug (struct CadetChannel *ch, enum GNUNET_ErrorType level) | ||
1646 | { | ||
1647 | int do_log; | ||
1648 | |||
1649 | do_log = GNUNET_get_log_call_status (level & (~GNUNET_ERROR_TYPE_BULK), | ||
1650 | "cadet-chn", | ||
1651 | __FILE__, __FUNCTION__, __LINE__); | ||
1652 | if (0 == do_log) | ||
1653 | return; | ||
1654 | |||
1655 | if (NULL == ch) | ||
1656 | { | ||
1657 | LOG2 (level, "CHN *** DEBUG NULL CHANNEL ***\n"); | ||
1658 | return; | ||
1659 | } | ||
1660 | LOG2 (level, "CHN Channel %s:%X (%p)\n", GCT_2s (ch->t), ch->gid, ch); | ||
1661 | LOG2 (level, "CHN root %p/%p\n", ch->root, ch->root_rel); | ||
1662 | if (NULL != ch->root) | ||
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 | { | ||
1675 | LOG2 (level, "CHN cli %s\n", GML_2s (ch->dest)); | ||
1676 | LOG2 (level, "CHN ready %s\n", ch->dest_rel->client_ready ? "YES" : "NO"); | ||
1677 | LOG2 (level, "CHN id %X\n", ch->lid_dest); | ||
1678 | LOG2 (level, "CHN recv %d\n", ch->dest_rel->n_recv); | ||
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 | |||
1685 | |||
1686 | /** | ||
1687 | * Handle an ACK given by a client. | ||
1688 | * | ||
1689 | * Mark client as ready and send him any buffered data we could have for him. | ||
1690 | * | ||
1691 | * @param ch Channel. | ||
1692 | * @param fwd Is this a "FWD ACK"? (FWD ACKs are sent by dest and go BCK) | ||
1693 | */ | ||
1694 | void | ||
1695 | GCCH_handle_local_ack (struct CadetChannel *ch, int fwd) | ||
1696 | { | ||
1697 | struct CadetChannelReliability *rel; | ||
1698 | struct CadetClient *c; | ||
1699 | |||
1700 | rel = fwd ? ch->dest_rel : ch->root_rel; | ||
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 | } | ||
1727 | |||
1728 | |||
1729 | /** | ||
1730 | * Handle data given by a client. | ||
1731 | * | ||
1732 | * Check whether the client is allowed to send in this tunnel, save if channel | ||
1733 | * is reliable and send an ACK to the client if there is still buffer space | ||
1734 | * in the tunnel. | ||
1735 | * | ||
1736 | * @param ch Channel. | ||
1737 | * @param c Client which sent the data. | ||
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 | */ | ||
1744 | int | ||
1745 | GCCH_handle_local_data (struct CadetChannel *ch, | ||
1746 | struct CadetClient *c, | ||
1747 | int fwd, | ||
1748 | const struct GNUNET_MessageHeader *message, | ||
1749 | size_t size) | ||
1750 | { | ||
1751 | struct CadetChannelReliability *rel; | ||
1752 | struct GNUNET_CADET_ChannelAppDataMessage *payload; | ||
1753 | uint16_t p2p_size = sizeof(struct GNUNET_CADET_ChannelAppDataMessage) + size; | ||
1754 | unsigned char cbuf[p2p_size]; | ||
1755 | unsigned char buffer; | ||
1756 | |||
1757 | /* Is the client in the channel? */ | ||
1758 | if ( !( (fwd && | ||
1759 | ch->root == c) | ||
1760 | || | ||
1761 | (!fwd && | ||
1762 | ch->dest == c) ) ) | ||
1763 | { | ||
1764 | GNUNET_break_op (0); | ||
1765 | return GNUNET_SYSERR; | ||
1766 | } | ||
1767 | |||
1768 | rel = fwd ? ch->root_rel : ch->dest_rel; | ||
1769 | |||
1770 | if (GNUNET_NO == rel->client_allowed) | ||
1771 | { | ||
1772 | GNUNET_break_op (0); | ||
1773 | return GNUNET_SYSERR; | ||
1774 | } | ||
1775 | |||
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 | */ | ||
1812 | void | ||
1813 | GCCH_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 | { | ||
1821 | LOG (GNUNET_ERROR_TYPE_DEBUG, " Client %s is destination.\n", GML_2s (c)); | ||
1822 | GML_client_delete_channel (c, ch, ch->lid_dest); | ||
1823 | ch->dest = NULL; | ||
1824 | } | ||
1825 | if (GNUNET_YES == is_root && c == ch->root) | ||
1826 | { | ||
1827 | LOG (GNUNET_ERROR_TYPE_DEBUG, " Client %s is owner.\n", GML_2s (c)); | ||
1828 | GML_client_delete_channel (c, ch, ch->lid_root); | ||
1829 | ch->root = NULL; | ||
1830 | } | ||
1831 | |||
1832 | send_destroy (ch, GNUNET_NO); | ||
1833 | if (0 == ch->pending_messages) | ||
1834 | GCCH_destroy (ch); | ||
1835 | } | ||
1836 | |||
1837 | |||
1838 | /** | ||
1839 | * Handle a channel create requested by a client. | ||
1840 | * | ||
1841 | * Create the channel and the tunnel in case this was the first0 channel. | ||
1842 | * | ||
1843 | * @param c Client that requested the creation (will be the root). | ||
1844 | * @param msg Create Channel message. | ||
1845 | * | ||
1846 | * @return #GNUNET_OK if everything went fine, #GNUNET_SYSERR otherwise. | ||
1847 | */ | ||
1848 | int | ||
1849 | GCCH_handle_local_create (struct CadetClient *c, | ||
1850 | struct GNUNET_CADET_LocalChannelCreateMessage *msg) | ||
1851 | { | ||
1852 | struct CadetChannel *ch; | ||
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 | |||
1861 | /* Sanity check for duplicate channel IDs */ | ||
1862 | if (NULL != GML_channel_get (c, ccn)) | ||
1863 | { | ||
1864 | GNUNET_break (0); | ||
1865 | return GNUNET_SYSERR; | ||
1866 | } | ||
1867 | |||
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 | { | ||
1878 | /* FIXME change to a tunnel API, eliminate ch <-> peer connection */ | ||
1879 | GCP_connect (peer); | ||
1880 | } | ||
1881 | |||
1882 | /* Create channel */ | ||
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 | */ | ||
1916 | void | ||
1917 | GCCH_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 | { | ||
1946 | GNUNET_break (GNUNET_NO != ch->destroy); | ||
1947 | return; | ||
1948 | } | ||
1949 | |||
1950 | if (CADET_CHANNEL_READY != ch->state) | ||
1951 | { | ||
1952 | if (GNUNET_NO == fwd) | ||
1953 | { | ||
1954 | /* If we are the root, this means the other peer has sent traffic before | ||
1955 | * receiving our ACK. Even if the SYNACK goes missing, no traffic should | ||
1956 | * be sent before the ACK. | ||
1957 | */ | ||
1958 | GNUNET_break_op (0); | ||
1959 | return; | ||
1960 | } | ||
1961 | /* If we are the dest, this means that the SYNACK got to the root but | ||
1962 | * the ACK went missing. Treat this as an ACK. | ||
1963 | */ | ||
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 | { | ||
1985 | /* Is this the exact next expected messasge? */ | ||
1986 | if (mid == rel->mid_recv) | ||
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 | } | ||
1999 | else | ||
2000 | { | ||
2001 | /* Tunnel is unreliable: send to clients directly */ | ||
2002 | /* FIXME: accept Out Of Order traffic */ | ||
2003 | rel->mid_recv = mid + 1; | ||
2004 | send_client_data (ch, msg, fwd); | ||
2005 | } | ||
2006 | } | ||
2007 | else | ||
2008 | { | ||
2009 | GNUNET_STATISTICS_update (stats, "# duplicate MID", 1, GNUNET_NO); | ||
2010 | if (GC_is_pid_bigger (rel->mid_recv, mid)) | ||
2011 | { | ||
2012 | GNUNET_break_op (0); | ||
2013 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
2014 | "MID %u on channel %s not expected (window: %u - %u). Dropping!\n", | ||
2015 | mid, GCCH_2s (ch), rel->mid_recv, rel->mid_recv + 63); | ||
2016 | } | ||
2017 | else | ||
2018 | { | ||
2019 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
2020 | "Duplicate MID %u, channel %s (expecting MID %u). Re-sending ACK!\n", | ||
2021 | mid, GCCH_2s (ch), rel->mid_recv); | ||
2022 | if (NULL != rel->uniq) | ||
2023 | { | ||
2024 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
2025 | "We are trying to send an ACK, but don't seem have the " | ||
2026 | "bandwidth. Have you set enough [ats] QUOTA in your config?\n"); | ||
2027 | } | ||
2028 | |||
2029 | } | ||
2030 | } | ||
2031 | |||
2032 | GCCH_send_data_ack (ch, fwd); | ||
2033 | } | ||
2034 | |||
2035 | |||
2036 | /** | ||
2037 | * Handler for cadet network traffic end-to-end ACKs. | ||
2038 | * | ||
2039 | * @param ch Channel on which we got this message. | ||
2040 | * @param msg Data message. | ||
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 | */ | ||
2046 | void | ||
2047 | GCCH_handle_data_ack (struct CadetChannel *ch, | ||
2048 | const struct GNUNET_CADET_ChannelDataAckMessage *msg, | ||
2049 | int fwd) | ||
2050 | { | ||
2051 | struct CadetChannelReliability *rel; | ||
2052 | struct CadetReliableMessage *copy; | ||
2053 | struct CadetReliableMessage *next; | ||
2054 | uint32_t ack; | ||
2055 | int work; | ||
2056 | |||
2057 | /* If this is a remote (non-loopback) channel, find 'fwd'. */ | ||
2058 | if (GNUNET_SYSERR == fwd) | ||
2059 | { | ||
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 | ||
2079 | rel = ch->dest_rel; | ||
2080 | |||
2081 | if (NULL == rel) | ||
2082 | { | ||
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 | { | ||
2090 | if (GC_is_pid_bigger (copy->mid, ack)) | ||
2091 | { | ||
2092 | LOG (GNUNET_ERROR_TYPE_DEBUG, " head %u, out!\n", copy->mid); | ||
2093 | if (0 < channel_rel_free_sent (rel, msg)) | ||
2094 | work = GNUNET_YES; | ||
2095 | break; | ||
2096 | } | ||
2097 | work = GNUNET_YES; | ||
2098 | LOG (GNUNET_ERROR_TYPE_DEBUG, " id %u\n", copy->mid); | ||
2099 | next = copy->next; | ||
2100 | if (GNUNET_YES == rel_message_free (copy, GNUNET_YES)) | ||
2101 | { | ||
2102 | LOG (GNUNET_ERROR_TYPE_DEBUG, " channel destoyed\n"); | ||
2103 | return; | ||
2104 | } | ||
2105 | } | ||
2106 | |||
2107 | /* ACK client if needed and possible */ | ||
2108 | GCCH_allow_client (ch, fwd); | ||
2109 | |||
2110 | /* If some message was free'd, update the retransmission delay */ | ||
2111 | if (GNUNET_YES == work) | ||
2112 | { | ||
2113 | if (NULL != rel->retry_task) | ||
2114 | { | ||
2115 | GNUNET_SCHEDULER_cancel (rel->retry_task); | ||
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 | } | ||
2133 | else | ||
2134 | { | ||
2135 | /* Work was done but no task was pending. | ||
2136 | * Task was cancelled by a retransmission that is sitting in the queue. | ||
2137 | */ | ||
2138 | // FIXME add test to make sure this is the case, probably add return | ||
2139 | // value to GCCH_send_prebuilt_message | ||
2140 | } | ||
2141 | } | ||
2142 | } | ||
2143 | |||
2144 | |||
2145 | /** | ||
2146 | * Handler for channel create messages. | ||
2147 | * | ||
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 | */ | ||
2153 | struct CadetChannel * | ||
2154 | GCCH_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 | { | ||
2168 | /* Create channel */ | ||
2169 | ccn.channel_of_client = htonl (0); | ||
2170 | ch = channel_new (t, NULL, ccn); | ||
2171 | ch->gid = gid; | ||
2172 | channel_set_options (ch, ntohl (msg->opt)); | ||
2173 | new_channel = GNUNET_YES; | ||
2174 | } | ||
2175 | else | ||
2176 | { | ||
2177 | new_channel = GNUNET_NO; | ||
2178 | } | ||
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 | |||
2219 | send_client_create (ch); | ||
2220 | ch->state = CADET_CHANNEL_SENT; | ||
2221 | } | ||
2222 | else | ||
2223 | { | ||
2224 | LOG (GNUNET_ERROR_TYPE_DEBUG, " duplicate create channel\n"); | ||
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 | |||
2240 | return ch; | ||
2241 | } | ||
2242 | |||
2243 | |||
2244 | /** | ||
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 | */ | ||
2251 | void | ||
2252 | GCCH_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 | |||
2263 | |||
2264 | /** | ||
2265 | * Handler for channel ack messages. | ||
2266 | * | ||
2267 | * @param ch Channel. | ||
2268 | * @param msg Message. | ||
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 | */ | ||
2274 | void | ||
2275 | GCCH_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 | */ | ||
2310 | void | ||
2311 | GCCH_handle_destroy (struct CadetChannel *ch, | ||
2312 | const struct GNUNET_CADET_ChannelManageMessage *msg, | ||
2313 | int fwd) | ||
2314 | { | ||
2315 | struct CadetChannelReliability *rel; | ||
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 | |||
2334 | GCCH_debug (ch, GNUNET_ERROR_TYPE_DEBUG); | ||
2335 | if ( (fwd && NULL == ch->dest) || (!fwd && NULL == ch->root) ) | ||
2336 | { | ||
2337 | /* Not for us (don't destroy twice a half-open loopback channel) */ | ||
2338 | 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 | */ | ||
2370 | void | ||
2371 | GCCH_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 | |||
2434 | if (GCT_is_loopback (ch->t)) | ||
2435 | { | ||
2436 | handle_loopback (ch, message, fwd); | ||
2437 | return; | ||
2438 | } | ||
2439 | |||
2440 | switch (type) | ||
2441 | { | ||
2442 | case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA: | ||
2443 | if (GNUNET_YES == ch->reliable) | ||
2444 | { | ||
2445 | chq = GNUNET_new (struct CadetChannelQueue); | ||
2446 | chq->type = type; | ||
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 | } | ||
2535 | } | ||
2536 | |||
2537 | |||
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 | */ | ||
2545 | const char * | ||
2546 | GCCH_2s (const struct CadetChannel *ch) | ||
2547 | { | ||
2548 | static char buf[64]; | ||
2549 | |||
2550 | if (NULL == ch) | ||
2551 | return "(NULL Channel)"; | ||
2552 | |||
2553 | SPRINTF (buf, | ||
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 deleted file mode 100644 index 9d4893269..000000000 --- a/src/cadet/gnunet-service-cadet_channel.h +++ /dev/null | |||
@@ -1,363 +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_channel.h | ||
23 | * @brief cadet service; dealing with end-to-end channels | ||
24 | * @author Bartlomiej Polot | ||
25 | * | ||
26 | * All functions in this file should use the prefix GMCH (Gnunet Cadet CHannel) | ||
27 | */ | ||
28 | |||
29 | #ifndef GNUNET_SERVICE_CADET_CHANNEL_H | ||
30 | #define GNUNET_SERVICE_CADET_CHANNEL_H | ||
31 | |||
32 | #ifdef __cplusplus | ||
33 | extern "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 | #include "cadet_protocol.h" | ||
44 | #include "cadet.h" | ||
45 | |||
46 | /** | ||
47 | * Struct containing all information regarding a channel to a remote client. | ||
48 | */ | ||
49 | struct CadetChannel; | ||
50 | |||
51 | |||
52 | #include "gnunet-service-cadet_tunnel.h" | ||
53 | #include "gnunet-service-cadet_local.h" | ||
54 | |||
55 | |||
56 | /** | ||
57 | * Destroy a channel and free all resources. | ||
58 | * | ||
59 | * @param ch Channel to destroy. | ||
60 | */ | ||
61 | void | ||
62 | GCCH_destroy (struct CadetChannel *ch); | ||
63 | |||
64 | |||
65 | /** | ||
66 | * Get the channel's public ID. | ||
67 | * | ||
68 | * @param ch Channel. | ||
69 | * | ||
70 | * @return ID used to identify the channel with the remote peer. | ||
71 | */ | ||
72 | struct GNUNET_CADET_ChannelTunnelNumber | ||
73 | GCCH_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 | */ | ||
83 | struct CadetTunnel * | ||
84 | GCCH_get_tunnel (const struct CadetChannel *ch); | ||
85 | |||
86 | |||
87 | /** | ||
88 | * Get free buffer space towards the client on a specific channel. | ||
89 | * | ||
90 | * @param ch Channel. | ||
91 | * @param fwd Is query about FWD traffic? | ||
92 | * | ||
93 | * @return Free buffer space [0 - 64] | ||
94 | */ | ||
95 | unsigned int | ||
96 | GCCH_get_buffer (struct CadetChannel *ch, int fwd); | ||
97 | |||
98 | |||
99 | /** | ||
100 | * Get flow control status of end point: is client allow to send? | ||
101 | * | ||
102 | * @param ch Channel. | ||
103 | * @param fwd Is query about FWD traffic? (Request root status). | ||
104 | * | ||
105 | * @return #GNUNET_YES if client is allowed to send us data. | ||
106 | */ | ||
107 | int | ||
108 | GCCH_get_allowed (struct CadetChannel *ch, int fwd); | ||
109 | |||
110 | |||
111 | /** | ||
112 | * Is the root client for this channel on this peer? | ||
113 | * | ||
114 | * @param ch Channel. | ||
115 | * @param fwd Is this for fwd traffic? | ||
116 | * | ||
117 | * @return #GNUNET_YES in case it is. | ||
118 | */ | ||
119 | int | ||
120 | GCCH_is_origin (struct CadetChannel *ch, int fwd); | ||
121 | |||
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 | */ | ||
130 | int | ||
131 | GCCH_is_terminal (struct CadetChannel *ch, int fwd); | ||
132 | |||
133 | /** | ||
134 | * Send an end-to-end ACK message for the most recent in-sequence payload. | ||
135 | * | ||
136 | * If channel is not reliable, do nothing. | ||
137 | * | ||
138 | * @param ch Channel this is about. | ||
139 | * @param fwd Is for FWD traffic? (ACK dest->owner) | ||
140 | */ | ||
141 | void | ||
142 | GCCH_send_data_ack (struct CadetChannel *ch, int fwd); | ||
143 | |||
144 | /** | ||
145 | * Notify the destination client that a new incoming channel was created. | ||
146 | * | ||
147 | * @param ch Channel that was created. | ||
148 | */ | ||
149 | void | ||
150 | GCCH_send_create (struct CadetChannel *ch); | ||
151 | |||
152 | /** | ||
153 | * Allow a client to send us more data, in case it was choked. | ||
154 | * | ||
155 | * @param ch Channel. | ||
156 | * @param fwd Is this about FWD traffic? (Root client). | ||
157 | */ | ||
158 | void | ||
159 | GCCH_allow_client (struct CadetChannel *ch, int fwd); | ||
160 | |||
161 | /** | ||
162 | * Log channel info. | ||
163 | * | ||
164 | * @param ch Channel. | ||
165 | * @param level Debug level to use. | ||
166 | */ | ||
167 | void | ||
168 | GCCH_debug (struct CadetChannel *ch, enum GNUNET_ErrorType level); | ||
169 | |||
170 | /** | ||
171 | * Handle an ACK given by a client. | ||
172 | * | ||
173 | * Mark client as ready and send him any buffered data we could have for him. | ||
174 | * | ||
175 | * @param ch Channel. | ||
176 | * @param fwd Is this a "FWD ACK"? (FWD ACKs are sent by root and go BCK) | ||
177 | */ | ||
178 | void | ||
179 | GCCH_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 | */ | ||
196 | int | ||
197 | GCCH_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 | */ | ||
211 | void | ||
212 | GCCH_handle_local_destroy (struct CadetChannel *ch, | ||
213 | struct CadetClient *c, | ||
214 | int is_root); | ||
215 | |||
216 | |||
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 | */ | ||
227 | int | ||
228 | GCCH_handle_local_create (struct CadetClient *c, | ||
229 | struct GNUNET_CADET_LocalChannelCreateMessage *msg); | ||
230 | |||
231 | /** | ||
232 | * Handler for cadet network payload traffic. | ||
233 | * | ||
234 | * @param ch Channel for the message. | ||
235 | * @param msg Unencryted data message. | ||
236 | * @param fwd Is this message fwd? This only is meaningful in loopback channels. | ||
237 | * #GNUNET_YES if message is FWD on the respective channel (loopback) | ||
238 | * #GNUNET_NO if message is BCK on the respective channel (loopback) | ||
239 | * #GNUNET_SYSERR if message on a one-ended channel (remote) | ||
240 | */ | ||
241 | void | ||
242 | GCCH_handle_data (struct CadetChannel *ch, | ||
243 | const struct GNUNET_CADET_ChannelAppDataMessage *msg, | ||
244 | int fwd); | ||
245 | |||
246 | |||
247 | /** | ||
248 | * Handler for cadet network traffic end-to-end ACKs. | ||
249 | * | ||
250 | * @param ch Channel on which we got this message. | ||
251 | * @param msg Data 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 | */ | ||
257 | void | ||
258 | GCCH_handle_data_ack (struct CadetChannel *ch, | ||
259 | const struct GNUNET_CADET_ChannelDataAckMessage *msg, | ||
260 | int fwd); | ||
261 | |||
262 | |||
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 | */ | ||
271 | struct CadetChannel * | ||
272 | GCCH_handle_create (struct CadetTunnel *t, | ||
273 | const struct GNUNET_CADET_ChannelOpenMessage *msg); | ||
274 | |||
275 | |||
276 | /** | ||
277 | * Handler for channel NACK messages. | ||
278 | * | ||
279 | * NACK messages always go dest -> root, no need for 'fwd' or 'msg' parameter. | ||
280 | * | ||
281 | * @param ch Channel. | ||
282 | */ | ||
283 | void | ||
284 | GCCH_handle_nack (struct CadetChannel *ch); | ||
285 | |||
286 | |||
287 | /** | ||
288 | * Handler for channel ack messages. | ||
289 | * | ||
290 | * @param ch Channel this channel is to be created in. | ||
291 | * @param msg Message. | ||
292 | * @param fwd Is this message fwd? This only is meaningful in loopback channels. | ||
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 | */ | ||
297 | void | ||
298 | GCCH_handle_ack (struct CadetChannel *ch, | ||
299 | const struct GNUNET_CADET_ChannelManageMessage *msg, | ||
300 | int fwd); | ||
301 | |||
302 | |||
303 | /** | ||
304 | * Handler for channel destroy messages. | ||
305 | * | ||
306 | * @param ch Channel this channel is to be destroyed of. | ||
307 | * @param msg Message. | ||
308 | * @param fwd Is this message fwd? This only is meaningful in loopback channels. | ||
309 | * #GNUNET_YES if message is FWD on the respective channel (loopback) | ||
310 | * #GNUNET_NO if message is BCK on the respective channel (loopback) | ||
311 | * #GNUNET_SYSERR if message on a one-ended channel (remote) | ||
312 | */ | ||
313 | void | ||
314 | GCCH_handle_destroy (struct CadetChannel *ch, | ||
315 | const struct GNUNET_CADET_ChannelManageMessage *msg, | ||
316 | int fwd); | ||
317 | |||
318 | |||
319 | /** | ||
320 | * Sends an already built message on a channel. | ||
321 | * | ||
322 | * If the channel is on a loopback tunnel, notifies the appropriate destination | ||
323 | * client locally. | ||
324 | * | ||
325 | * On a normal channel passes the message to the tunnel for encryption and | ||
326 | * sending on a connection. | ||
327 | * | ||
328 | * This function DOES NOT save the message for retransmission. | ||
329 | * | ||
330 | * @param message Message to send. Function makes a copy of it. | ||
331 | * @param ch Channel on which this message is transmitted. | ||
332 | * @param fwd Is this a fwd message? | ||
333 | * @param existing_copy This is a retransmission, don't save a copy. | ||
334 | */ | ||
335 | void | ||
336 | GCCH_send_prebuilt_message (const struct GNUNET_MessageHeader *message, | ||
337 | struct CadetChannel *ch, int fwd, | ||
338 | void *existing_copy); | ||
339 | |||
340 | |||
341 | /** | ||
342 | * Get the static string for identification of the channel. | ||
343 | * | ||
344 | * @param ch Channel.i | ||
345 | * | ||
346 | * @return Static string with the channel IDs. | ||
347 | */ | ||
348 | const char * | ||
349 | GCCH_2s (const struct CadetChannel *ch); | ||
350 | |||
351 | |||
352 | |||
353 | |||
354 | #if 0 /* keep Emacsens' auto-indent happy */ | ||
355 | { | ||
356 | #endif | ||
357 | #ifdef __cplusplus | ||
358 | } | ||
359 | #endif | ||
360 | |||
361 | /* ifndef GNUNET_SERVICE_CADET_CHANNEL_H */ | ||
362 | #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 deleted file mode 100644 index 2d5087f81..000000000 --- a/src/cadet/gnunet-service-cadet_connection.c +++ /dev/null | |||
@@ -1,3713 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2001-2015 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_connection.c | ||
22 | * @brief GNUnet CADET service connection handling | ||
23 | * @author Bartlomiej Polot | ||
24 | */ | ||
25 | #include "platform.h" | ||
26 | #include "gnunet_util_lib.h" | ||
27 | #include "gnunet_statistics_service.h" | ||
28 | #include "cadet_path.h" | ||
29 | #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 | */ | ||
59 | struct CadetConnectionQueue | ||
60 | { | ||
61 | |||
62 | struct CadetConnectionQueue *next; | ||
63 | struct CadetConnectionQueue *prev; | ||
64 | |||
65 | /** | ||
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 | |||
86 | |||
87 | /** | ||
88 | * Struct to encapsulate all the Flow Control information to a peer to which | ||
89 | * we are directly connected (on a core level). | ||
90 | */ | ||
91 | struct CadetFlowControl | ||
92 | { | ||
93 | /** | ||
94 | * Connection this controls. | ||
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 | */ | ||
138 | struct CadetEncryptedMessageIdentifier last_ack_sent; | ||
139 | |||
140 | /** | ||
141 | * Last ACK sent towards the origin (for traffic towards leaf node). | ||
142 | */ | ||
143 | struct CadetEncryptedMessageIdentifier last_ack_recv; | ||
144 | |||
145 | /** | ||
146 | * Task to poll the peer in case of a lost ACK causes stall. | ||
147 | */ | ||
148 | struct GNUNET_SCHEDULER_Task *poll_task; | ||
149 | |||
150 | /** | ||
151 | * How frequently to poll for ACKs. | ||
152 | */ | ||
153 | struct GNUNET_TIME_Relative poll_time; | ||
154 | |||
155 | /** | ||
156 | * Queued poll message, to cancel if not necessary anymore (got ACK). | ||
157 | */ | ||
158 | struct CadetConnectionQueue *poll_msg; | ||
159 | |||
160 | /** | ||
161 | * Queued poll message, to cancel if not necessary anymore (got ACK). | ||
162 | */ | ||
163 | struct CadetConnectionQueue *ack_msg; | ||
164 | }; | ||
165 | |||
166 | /** | ||
167 | * Keep a record of the last messages sent on this connection. | ||
168 | */ | ||
169 | struct CadetConnectionPerformance | ||
170 | { | ||
171 | /** | ||
172 | * Circular buffer for storing measurements. | ||
173 | */ | ||
174 | double usecsperbyte[AVG_MSGS]; | ||
175 | |||
176 | /** | ||
177 | * Running average of @c usecsperbyte. | ||
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 | */ | ||
189 | uint16_t idx; | ||
190 | }; | ||
191 | |||
192 | |||
193 | /** | ||
194 | * Struct containing all information regarding a connection to a peer. | ||
195 | */ | ||
196 | struct CadetConnection | ||
197 | { | ||
198 | /** | ||
199 | * Tunnel this connection is part of. | ||
200 | */ | ||
201 | struct CadetTunnel *t; | ||
202 | |||
203 | /** | ||
204 | * Flow control information for traffic fwd. | ||
205 | */ | ||
206 | struct CadetFlowControl fwd_fc; | ||
207 | |||
208 | /** | ||
209 | * Flow control information for traffic bck. | ||
210 | */ | ||
211 | struct CadetFlowControl bck_fc; | ||
212 | |||
213 | /** | ||
214 | * Measure connection performance on the endpoint. | ||
215 | */ | ||
216 | struct CadetConnectionPerformance *perf; | ||
217 | |||
218 | /** | ||
219 | * ID of the connection. | ||
220 | */ | ||
221 | struct GNUNET_CADET_ConnectionTunnelIdentifier id; | ||
222 | |||
223 | /** | ||
224 | * Path being used for the tunnel. At the origin of the connection | ||
225 | * it's a pointer to the destination's path pool, otherwise just a copy. | ||
226 | */ | ||
227 | struct CadetPeerPath *path; | ||
228 | |||
229 | /** | ||
230 | * Task to keep the used paths alive at the owner, | ||
231 | * time tunnel out on all the other peers. | ||
232 | */ | ||
233 | struct GNUNET_SCHEDULER_Task *fwd_maintenance_task; | ||
234 | |||
235 | /** | ||
236 | * Task to keep the used paths alive at the destination, | ||
237 | * time tunnel out on all the other peers. | ||
238 | */ | ||
239 | struct GNUNET_SCHEDULER_Task *bck_maintenance_task; | ||
240 | |||
241 | /** | ||
242 | * Queue handle for maintainance traffic. One handle for FWD and BCK since | ||
243 | * one peer never needs to maintain both directions (no loopback connections). | ||
244 | */ | ||
245 | struct CadetPeerQueue *maintenance_q; | ||
246 | |||
247 | /** | ||
248 | * Should equal #get_next_hop(), or NULL if that peer disconnected. | ||
249 | */ | ||
250 | struct CadetPeer *next_peer; | ||
251 | |||
252 | /** | ||
253 | * Should equal #get_prev_hop(), or NULL if that peer disconnected. | ||
254 | */ | ||
255 | struct CadetPeer *prev_peer; | ||
256 | |||
257 | /** | ||
258 | * State of the connection. | ||
259 | */ | ||
260 | enum CadetConnectionState state; | ||
261 | |||
262 | /** | ||
263 | * Position of the local peer in the path. | ||
264 | */ | ||
265 | unsigned int own_pos; | ||
266 | |||
267 | /** | ||
268 | * Pending message count. | ||
269 | */ | ||
270 | unsigned int pending_messages; | ||
271 | |||
272 | /** | ||
273 | * Destroy flag: | ||
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 | */ | ||
278 | int destroy; | ||
279 | |||
280 | /** | ||
281 | * In-connection-map flag. Sometimes, when @e destroy is set but | ||
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 | */ | ||
289 | int was_removed; | ||
290 | |||
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 | }; | ||
301 | |||
302 | |||
303 | /******************************************************************************/ | ||
304 | /******************************* GLOBALS ***********************************/ | ||
305 | /******************************************************************************/ | ||
306 | |||
307 | /** | ||
308 | * Global handle to the statistics service. | ||
309 | */ | ||
310 | extern struct GNUNET_STATISTICS_Handle *stats; | ||
311 | |||
312 | /** | ||
313 | * Local peer own ID (memory efficient handle). | ||
314 | */ | ||
315 | extern GNUNET_PEER_Id myid; | ||
316 | |||
317 | /** | ||
318 | * Local peer own ID (full value). | ||
319 | */ | ||
320 | extern struct GNUNET_PeerIdentity my_full_id; | ||
321 | |||
322 | /** | ||
323 | * Connections known, indexed by cid (CadetConnection). | ||
324 | */ | ||
325 | static 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 | */ | ||
332 | static 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 | */ | ||
338 | static unsigned long long max_msgs_queue; | ||
339 | |||
340 | /** | ||
341 | * How often to send path keepalives. Paths timeout after 4 missed. | ||
342 | */ | ||
343 | static struct GNUNET_TIME_Relative refresh_connection_time; | ||
344 | |||
345 | /** | ||
346 | * How often to send path create / ACKs. | ||
347 | */ | ||
348 | static 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 | ||
358 | static void | ||
359 | fc_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 | |||
370 | static void | ||
371 | connection_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 | */ | ||
397 | static void | ||
398 | schedule_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 | */ | ||
413 | static void | ||
414 | connection_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 | */ | ||
424 | static const char * | ||
425 | GCC_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 | /** | ||
450 | * Initialize a Flow Control structure to the initial state. | ||
451 | * | ||
452 | * @param fc Flow Control structure to initialize. | ||
453 | */ | ||
454 | static void | ||
455 | fc_init (struct CadetFlowControl *fc) | ||
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 | */ | ||
476 | static struct CadetConnection * | ||
477 | connection_get (const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid) | ||
478 | { | ||
479 | return GNUNET_CONTAINER_multishortmap_get (connections, | ||
480 | &cid->connection_of_tunnel); | ||
481 | } | ||
482 | |||
483 | |||
484 | /** | ||
485 | * Change the connection state. Cannot change a connection marked as destroyed. | ||
486 | * | ||
487 | * @param c Connection to change. | ||
488 | * @param state New state to set. | ||
489 | */ | ||
490 | static void | ||
491 | connection_change_state (struct CadetConnection* c, | ||
492 | enum CadetConnectionState state) | ||
493 | { | ||
494 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
495 | "Connection %s state %s -> %s\n", | ||
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 | |||
508 | /** | ||
509 | * Mark a connection as "destroyed", to send all pending traffic and freeing | ||
510 | * all associated resources, without accepting new status changes on it. | ||
511 | * | ||
512 | * @param c Connection to mark as destroyed. | ||
513 | */ | ||
514 | static void | ||
515 | mark_destroyed (struct CadetConnection *c) | ||
516 | { | ||
517 | c->destroy = GNUNET_YES; | ||
518 | connection_change_state (c, CADET_CONNECTION_DESTROYED); | ||
519 | } | ||
520 | |||
521 | |||
522 | /** | ||
523 | * Function called if a connection has been stalled for a while, | ||
524 | * possibly due to a missed ACK. Poll the neighbor about its ACK status. | ||
525 | * | ||
526 | * @param cls Closure (poll ctx). | ||
527 | */ | ||
528 | static void | ||
529 | send_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 | * | ||
540 | * @param c Connection on which to send the ACK. | ||
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 | */ | ||
545 | static void | ||
546 | send_ack (struct CadetConnection *c, | ||
547 | unsigned int buffer, | ||
548 | int fwd, | ||
549 | int force) | ||
550 | { | ||
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, | ||
583 | " ACK %u, last PID %u, last ACK %u, qmax %u, q %u\n", | ||
584 | ntohl (ack_cemi.pid), | ||
585 | ntohl (prev_fc->last_pid_recv.pid), | ||
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 | */ | ||
642 | static void | ||
643 | update_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 | */ | ||
690 | static void | ||
691 | conn_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 | { | ||
739 | GNUNET_CONTAINER_DLL_remove (fc->q_head, fc->q_tail, q); | ||
740 | forced = q->forced; | ||
741 | if (NULL != q->cont) | ||
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 | } | ||
748 | else /* CONN_CREATE or CONN_ACK */ | ||
749 | { | ||
750 | GNUNET_assert (GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED != type); | ||
751 | forced = GNUNET_YES; | ||
752 | } | ||
753 | |||
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 | { | ||
759 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
760 | "! destroying connection!\n"); | ||
761 | GCC_destroy (c); | ||
762 | GCC_check_connections (); | ||
763 | return; | ||
764 | } | ||
765 | |||
766 | /* Send ACK if needed, after accounting for sent ID in fc->queue_n */ | ||
767 | switch (type) | ||
768 | { | ||
769 | case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE: | ||
770 | case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK: | ||
771 | c->maintenance_q = NULL; | ||
772 | /* Don't trigger a keepalive for sent ACKs, only SYN and SYNACKs */ | ||
773 | if (GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE == type || !fwd) | ||
774 | schedule_next_keepalive (c, fwd); | ||
775 | break; | ||
776 | |||
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 | */ | ||
857 | static struct CadetPeer * | ||
858 | get_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 | */ | ||
886 | static struct CadetPeer * | ||
887 | get_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 | } | ||
906 | |||
907 | |||
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 | */ | ||
914 | static void | ||
915 | check_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 | |||
924 | /** | ||
925 | * Helper for #GCC_check_connections(). Calls #check_neighbours(). | ||
926 | * | ||
927 | * @param cls NULL | ||
928 | * @param key ignored | ||
929 | * @param value the `struct CadetConnection` to check | ||
930 | * @return #GNUNET_OK (continue to iterate) | ||
931 | */ | ||
932 | static int | ||
933 | check_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 | */ | ||
947 | void | ||
948 | GCC_check_connections () | ||
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 | */ | ||
968 | static struct CadetPeer * | ||
969 | get_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 | */ | ||
981 | static uint32_t | ||
982 | get_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 | */ | ||
997 | static int | ||
998 | is_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 | */ | ||
1028 | static int | ||
1029 | is_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 | */ | ||
1053 | static void | ||
1054 | send_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 | */ | ||
1101 | static void | ||
1102 | send_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 | */ | ||
1137 | static void | ||
1138 | send_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 | */ | ||
1176 | static void | ||
1177 | send_connection_keepalive (struct CadetConnection *c, int fwd) | ||
1178 | { | ||
1179 | struct GNUNET_MessageHeader msg; | ||
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 | { | ||
1194 | LOG (GNUNET_ERROR_TYPE_INFO, "not sending keepalive, traffic in queue\n"); | ||
1195 | return; | ||
1196 | } | ||
1197 | |||
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 | */ | ||
1217 | static void | ||
1218 | connection_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 | } | ||
1227 | |||
1228 | |||
1229 | /** | ||
1230 | * Generic connection timer management. | ||
1231 | * Depending on the role of the peer in the connection will send the | ||
1232 | * appropriate message (build or keepalive) | ||
1233 | * | ||
1234 | * @param c Conncetion to maintain. | ||
1235 | * @param fwd Is FWD? | ||
1236 | */ | ||
1237 | static void | ||
1238 | connection_maintain (struct CadetConnection *c, int fwd) | ||
1239 | { | ||
1240 | if (GNUNET_NO != c->destroy) | ||
1241 | { | ||
1242 | LOG (GNUNET_ERROR_TYPE_INFO, "not sending keepalive, being destroyed\n"); | ||
1243 | return; | ||
1244 | } | ||
1245 | |||
1246 | if (NULL == c->t) | ||
1247 | { | ||
1248 | GNUNET_break (0); | ||
1249 | GCC_debug (c, GNUNET_ERROR_TYPE_ERROR); | ||
1250 | return; | ||
1251 | } | ||
1252 | |||
1253 | if (CADET_TUNNEL_SEARCHING == GCT_get_cstate (c->t)) | ||
1254 | { | ||
1255 | /* If status is SEARCHING, why is there a connection? Should be WAITING */ | ||
1256 | GNUNET_break (0); | ||
1257 | GCT_debug (c->t, GNUNET_ERROR_TYPE_ERROR); | ||
1258 | LOG (GNUNET_ERROR_TYPE_INFO, "not sending keepalive, tunnel SEARCHING\n"); | ||
1259 | schedule_next_keepalive (c, fwd); | ||
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 | } | ||
1276 | } | ||
1277 | |||
1278 | |||
1279 | /** | ||
1280 | * Keep the connection alive. | ||
1281 | * | ||
1282 | * @param c Connection to keep alive. | ||
1283 | * @param fwd Direction. | ||
1284 | */ | ||
1285 | static void | ||
1286 | connection_keepalive (struct CadetConnection *c, | ||
1287 | int fwd) | ||
1288 | { | ||
1289 | GCC_check_connections (); | ||
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 | } | ||
1302 | |||
1303 | |||
1304 | /** | ||
1305 | * Keep the connection alive in the FWD direction. | ||
1306 | * | ||
1307 | * @param cls Closure (connection to keepalive). | ||
1308 | */ | ||
1309 | static void | ||
1310 | connection_fwd_keepalive (void *cls) | ||
1311 | { | ||
1312 | struct CadetConnection *c = cls; | ||
1313 | |||
1314 | GCC_check_connections (); | ||
1315 | connection_keepalive (c, | ||
1316 | GNUNET_YES); | ||
1317 | GCC_check_connections (); | ||
1318 | } | ||
1319 | |||
1320 | |||
1321 | /** | ||
1322 | * Keep the connection alive in the BCK direction. | ||
1323 | * | ||
1324 | * @param cls Closure (connection to keepalive). | ||
1325 | */ | ||
1326 | static void | ||
1327 | connection_bck_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 | |||
1337 | |||
1338 | /** | ||
1339 | * Schedule next keepalive task, taking in consideration | ||
1340 | * the connection state and number of retries. | ||
1341 | * | ||
1342 | * If the peer is not the origin, do nothing. | ||
1343 | * | ||
1344 | * @param c Connection for which to schedule the next keepalive. | ||
1345 | * @param fwd Direction for the next keepalive. | ||
1346 | */ | ||
1347 | static void | ||
1348 | schedule_next_keepalive (struct CadetConnection *c, int fwd) | ||
1349 | { | ||
1350 | struct GNUNET_TIME_Relative delay; | ||
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 | |||
1385 | /* Check that no one scheduled it before us */ | ||
1386 | if (NULL != *task_id) | ||
1387 | { | ||
1388 | /* No need for a _break. It can happen for instance when sending a SYNACK | ||
1389 | * for a duplicate SYN: the first SYNACK scheduled the task. */ | ||
1390 | GNUNET_SCHEDULER_cancel (*task_id); | ||
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 | } | ||
1402 | |||
1403 | |||
1404 | /** | ||
1405 | * Cancel all transmissions that belong to a certain connection. | ||
1406 | * | ||
1407 | * If the connection is scheduled for destruction and no more messages are left, | ||
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 | */ | ||
1413 | static void | ||
1414 | connection_cancel_queues (struct CadetConnection *c, | ||
1415 | int fwd) | ||
1416 | { | ||
1417 | struct CadetFlowControl *fc; | ||
1418 | |||
1419 | GCC_check_connections (); | ||
1420 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1421 | "Cancel %s queues for connection %s\n", | ||
1422 | GC_f2s (fwd), GCC_2s (c)); | ||
1423 | if (NULL == c) | ||
1424 | { | ||
1425 | GNUNET_break (0); | ||
1426 | return; | ||
1427 | } | ||
1428 | |||
1429 | fc = fwd ? &c->fwd_fc : &c->bck_fc; | ||
1430 | if (NULL != fc->poll_task) | ||
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 | */ | ||
1456 | static void | ||
1457 | send_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 | */ | ||
1500 | static void | ||
1501 | connection_timeout (struct CadetConnection *c, int fwd) | ||
1502 | { | ||
1503 | GCC_check_connections (); | ||
1504 | |||
1505 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
1506 | "Connection %s %s timed out. Destroying.\n", | ||
1507 | GCC_2s (c), | ||
1508 | GC_f2s (fwd)); | ||
1509 | GCC_debug (c, GNUNET_ERROR_TYPE_DEBUG); | ||
1510 | |||
1511 | if (GCC_is_origin (c, fwd)) /* Loopback? Something is wrong! */ | ||
1512 | { | ||
1513 | GNUNET_break (0); | ||
1514 | return; | ||
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 | */ | ||
1537 | static void | ||
1538 | connection_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 | */ | ||
1555 | static void | ||
1556 | connection_bck_timeout (void *cls) | ||
1557 | { | ||
1558 | struct CadetConnection *c = cls; | ||
1559 | |||
1560 | c->bck_maintenance_task = NULL; | ||
1561 | GCC_check_connections (); | ||
1562 | connection_timeout (c, GNUNET_NO); | ||
1563 | GCC_check_connections (); | ||
1564 | } | ||
1565 | |||
1566 | |||
1567 | /** | ||
1568 | * Resets the connection timeout task, some other message has done the | ||
1569 | * task's job. | ||
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 | * | ||
1579 | * TODO use heap to improve efficiency of scheduler. | ||
1580 | */ | ||
1581 | static void | ||
1582 | connection_reset_timeout (struct CadetConnection *c, int fwd) | ||
1583 | { | ||
1584 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Connection %s reset timeout\n", GC_f2s (fwd)); | ||
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 | |||
1602 | if (NULL != *ti) | ||
1603 | GNUNET_SCHEDULER_cancel (*ti); | ||
1604 | delay = GNUNET_TIME_relative_saturating_multiply (refresh_connection_time, 4); | ||
1605 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
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 | } | ||
1612 | |||
1613 | |||
1614 | /** | ||
1615 | * Iterator to compare each connection's path with the path of a new connection. | ||
1616 | * | ||
1617 | * If the connection coincides, the c member of path is set to the connection | ||
1618 | * and the destroy flag of the connection is set. | ||
1619 | * | ||
1620 | * @param cls Closure (new path). | ||
1621 | * @param c Connection in the tunnel to check. | ||
1622 | */ | ||
1623 | static void | ||
1624 | check_path (void *cls, struct CadetConnection *c) | ||
1625 | { | ||
1626 | struct CadetConnection *new_conn = cls; | ||
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 | |||
1632 | if (c != new_conn | ||
1633 | && GNUNET_NO == c->destroy | ||
1634 | && CADET_CONNECTION_BROKEN != c->state | ||
1635 | && CADET_CONNECTION_DESTROYED != c->state | ||
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 | } | ||
1643 | |||
1644 | |||
1645 | /** | ||
1646 | * Finds out if this path is already being used by an existing connection. | ||
1647 | * | ||
1648 | * Checks the tunnel towards the destination to see if it contains | ||
1649 | * any connection with the same path. | ||
1650 | * | ||
1651 | * If the existing connection is ready, it is kept. | ||
1652 | * Otherwise if the sender has a smaller ID that ours, we accept it (and | ||
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 | */ | ||
1659 | static int | ||
1660 | does_connection_exist (struct CadetConnection *conn) | ||
1661 | { | ||
1662 | struct CadetPeer *p; | ||
1663 | struct CadetTunnel *t; | ||
1664 | struct CadetConnection *c; | ||
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 | |||
1675 | GCT_iterate_connections (t, &check_path, conn); | ||
1676 | |||
1677 | if (GNUNET_YES == conn->destroy) | ||
1678 | { | ||
1679 | c = conn->path->c; | ||
1680 | conn->destroy = GNUNET_NO; | ||
1681 | conn->path->c = conn; | ||
1682 | LOG (GNUNET_ERROR_TYPE_DEBUG, " found duplicate of %s\n", GCC_2s (conn)); | ||
1683 | LOG (GNUNET_ERROR_TYPE_DEBUG, " duplicate: %s\n", GCC_2s (c)); | ||
1684 | GCC_debug (c, GNUNET_ERROR_TYPE_DEBUG); | ||
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 | ||
1696 | { | ||
1697 | LOG (GNUNET_ERROR_TYPE_DEBUG, " %s has no duplicates\n", GCC_2s (conn)); | ||
1698 | return GNUNET_NO; | ||
1699 | } | ||
1700 | } | ||
1701 | |||
1702 | |||
1703 | /** | ||
1704 | * @brief Check if the tunnel this connection belongs to has any other | ||
1705 | * connection with the same path, and destroy one if so. | ||
1706 | * | ||
1707 | * @param cls Closure (connection to check). | ||
1708 | */ | ||
1709 | static void | ||
1710 | check_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 | */ | ||
1730 | static void | ||
1731 | schedule_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 | */ | ||
1752 | static int | ||
1753 | register_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 | */ | ||
1811 | static void | ||
1812 | unregister_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 | */ | ||
1840 | static void | ||
1841 | invalidate_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 | */ | ||
1865 | static void | ||
1866 | add_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 | */ | ||
1882 | static void | ||
1883 | log_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 | */ | ||
1923 | void | ||
1924 | GCC_handle_create (struct CadetPeer *peer, | ||
1925 | const struct GNUNET_CADET_ConnectionCreateMessage *msg) | ||
1926 | { | ||
1927 | static struct CadetEncryptedMessageIdentifier zero; | ||
1928 | const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid; | ||
1929 | struct GNUNET_PeerIdentity *id; | ||
1930 | struct CadetPeerPath *path; | ||
1931 | struct CadetPeer *dest_peer; | ||
1932 | struct CadetPeer *orig_peer; | ||
1933 | struct CadetConnection *c; | ||
1934 | unsigned int own_pos; | ||
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 | { | ||
2047 | LOG (GNUNET_ERROR_TYPE_DEBUG, " not for us, retransmitting...\n"); | ||
2048 | GCP_add_path (dest_peer, path_duplicate (path), GNUNET_NO); | ||
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 | } | ||
2057 | path_destroy (path); | ||
2058 | GCC_check_connections (); | ||
2059 | } | ||
2060 | |||
2061 | |||
2062 | /** | ||
2063 | * Handler for connection confirmations. | ||
2064 | * | ||
2065 | * @param peer Message sender (neighbor). | ||
2066 | * @param msg Message itself. | ||
2067 | */ | ||
2068 | void | ||
2069 | GCC_handle_confirm (struct CadetPeer *peer, | ||
2070 | const struct GNUNET_CADET_ConnectionCreateAckMessage *msg) | ||
2071 | { | ||
2072 | static struct CadetEncryptedMessageIdentifier zero; | ||
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 | { | ||
2092 | GNUNET_assert (CADET_CONNECTION_DESTROYED == c->state); | ||
2093 | GNUNET_STATISTICS_update (stats, "# control on dying connection", | ||
2094 | 1, GNUNET_NO); | ||
2095 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2096 | "connection %s being destroyed, ignoring confirm\n", | ||
2097 | GCC_2s (c)); | ||
2098 | GCC_check_connections (); | ||
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 | } | ||
2177 | else | ||
2178 | { | ||
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 | } | ||
2188 | |||
2189 | |||
2190 | /** | ||
2191 | * Handler for notifications of broken connections. | ||
2192 | * | ||
2193 | * @param peer Message sender (neighbor). | ||
2194 | * @param msg Message itself. | ||
2195 | */ | ||
2196 | void | ||
2197 | GCC_handle_broken (struct CadetPeer *peer, | ||
2198 | const struct GNUNET_CADET_ConnectionBrokenMessage *msg) | ||
2199 | { | ||
2200 | static struct CadetEncryptedMessageIdentifier zero; | ||
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 | { | ||
2253 | (void) GCC_send_prebuilt_message (&msg->header, 0, | ||
2254 | zero, c, fwd, | ||
2255 | GNUNET_YES, NULL, NULL); | ||
2256 | connection_cancel_queues (c, !fwd); | ||
2257 | } | ||
2258 | GCC_check_connections (); | ||
2259 | return; | ||
2260 | } | ||
2261 | |||
2262 | |||
2263 | /** | ||
2264 | * Handler for notifications of destroyed connections. | ||
2265 | * | ||
2266 | * @param peer Message sender (neighbor). | ||
2267 | * @param msg Message itself. | ||
2268 | */ | ||
2269 | void | ||
2270 | GCC_handle_destroy (struct CadetPeer *peer, | ||
2271 | const struct GNUNET_CADET_ConnectionDestroyMessage *msg) | ||
2272 | { | ||
2273 | static struct CadetEncryptedMessageIdentifier zero; | ||
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 | { | ||
2282 | /* Probably already got the message from another path, | ||
2283 | * destroyed the tunnel and retransmitted to children. | ||
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, | ||
2290 | " connection unknown destroyed: previously destroyed?\n"); | ||
2291 | GCC_check_connections (); | ||
2292 | return; | ||
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 | } | ||
2309 | else if (0 == c->pending_messages) | ||
2310 | { | ||
2311 | LOG (GNUNET_ERROR_TYPE_DEBUG, " directly destroying connection!\n"); | ||
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 | } | ||
2325 | |||
2326 | |||
2327 | /** | ||
2328 | * Handler for cadet network traffic hop-by-hop acks. | ||
2329 | * | ||
2330 | * @param peer Message sender (neighbor). | ||
2331 | * @param msg Message itself. | ||
2332 | */ | ||
2333 | void | ||
2334 | GCC_handle_ack (struct CadetPeer *peer, | ||
2335 | const struct GNUNET_CADET_ConnectionEncryptedAckMessage *msg) | ||
2336 | { | ||
2337 | struct CadetConnection *c; | ||
2338 | struct CadetFlowControl *fc; | ||
2339 | struct CadetEncryptedMessageIdentifier ack; | ||
2340 | int fwd; | ||
2341 | |||
2342 | GCC_check_connections (); | ||
2343 | log_message (&msg->header, peer, &msg->cid); | ||
2344 | c = connection_get (&msg->cid); | ||
2345 | if (NULL == c) | ||
2346 | { | ||
2347 | GNUNET_STATISTICS_update (stats, | ||
2348 | "# ack on unknown connection", | ||
2349 | 1, | ||
2350 | GNUNET_NO); | ||
2351 | send_broken_unknown (&msg->cid, | ||
2352 | &my_full_id, | ||
2353 | NULL, | ||
2354 | peer); | ||
2355 | GCC_check_connections (); | ||
2356 | return; | ||
2357 | } | ||
2358 | |||
2359 | /* Is this a forward or backward ACK? */ | ||
2360 | if (get_next_hop (c) == peer) | ||
2361 | { | ||
2362 | fc = &c->fwd_fc; | ||
2363 | fwd = GNUNET_YES; | ||
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 | } | ||
2398 | |||
2399 | |||
2400 | /** | ||
2401 | * Handler for cadet network traffic hop-by-hop data counter polls. | ||
2402 | * | ||
2403 | * @param peer Message sender (neighbor). | ||
2404 | * @param msg Message itself. | ||
2405 | */ | ||
2406 | void | ||
2407 | GCC_handle_poll (struct CadetPeer *peer, | ||
2408 | const struct GNUNET_CADET_ConnectionHopByHopPollMessage *msg) | ||
2409 | { | ||
2410 | struct CadetConnection *c; | ||
2411 | struct CadetFlowControl *fc; | ||
2412 | struct CadetEncryptedMessageIdentifier pid; | ||
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 | |||
2454 | pid = msg->cemi; | ||
2455 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2456 | " PID %u, OLD %u\n", | ||
2457 | ntohl (pid.pid), | ||
2458 | ntohl (fc->last_pid_recv.pid)); | ||
2459 | fc->last_pid_recv = pid; | ||
2460 | fwd = fc == &c->bck_fc; | ||
2461 | GCC_send_ack (c, fwd, GNUNET_YES); | ||
2462 | GCC_check_connections (); | ||
2463 | } | ||
2464 | |||
2465 | |||
2466 | /** | ||
2467 | * Check the message against internal state and test if it goes FWD or BCK. | ||
2468 | * | ||
2469 | * Updates the PID, state and timeout values for the connection. | ||
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 | * | ||
2476 | * @return #GNUNET_YES if the message goes FWD. | ||
2477 | * #GNUNET_NO if it goes BCK. | ||
2478 | * #GNUNET_SYSERR if there is an error (unauthorized sender, ...). | ||
2479 | */ | ||
2480 | static int | ||
2481 | check_message (const struct GNUNET_MessageHeader *message, | ||
2482 | const struct GNUNET_CADET_ConnectionTunnelIdentifier* cid, | ||
2483 | struct CadetConnection *c, | ||
2484 | struct CadetPeer *sender, | ||
2485 | struct CadetEncryptedMessageIdentifier pid) | ||
2486 | { | ||
2487 | struct CadetFlowControl *fc; | ||
2488 | struct CadetPeer *hop; | ||
2489 | int fwd; | ||
2490 | uint16_t type; | ||
2491 | |||
2492 | /* Check connection */ | ||
2493 | if (NULL == c) | ||
2494 | { | ||
2495 | GNUNET_STATISTICS_update (stats, | ||
2496 | "# unknown connection", | ||
2497 | 1, GNUNET_NO); | ||
2498 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
2499 | "%s on unknown connection %s\n", | ||
2500 | GC_m2s (ntohs (message->type)), | ||
2501 | GNUNET_sh2s (&cid->connection_of_tunnel)); | ||
2502 | GNUNET_break_op (0); | ||
2503 | send_broken_unknown (cid, | ||
2504 | &my_full_id, | ||
2505 | NULL, | ||
2506 | sender); | ||
2507 | return GNUNET_SYSERR; | ||
2508 | } | ||
2509 | |||
2510 | /* Check if origin is as expected */ | ||
2511 | hop = get_prev_hop (c); | ||
2512 | if (sender == hop) | ||
2513 | { | ||
2514 | fwd = GNUNET_YES; | ||
2515 | } | ||
2516 | else | ||
2517 | { | ||
2518 | hop = get_next_hop (c); | ||
2519 | GNUNET_break (hop == c->next_peer); | ||
2520 | if (sender == hop) | ||
2521 | { | ||
2522 | fwd = GNUNET_NO; | ||
2523 | } | ||
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 | } | ||
2595 | connection_reset_timeout (c, fwd); | ||
2596 | |||
2597 | return fwd; | ||
2598 | } | ||
2599 | |||
2600 | |||
2601 | /** | ||
2602 | * Handler for key exchange traffic (Axolotl KX). | ||
2603 | * | ||
2604 | * @param peer Message sender (neighbor). | ||
2605 | * @param msg Message itself. | ||
2606 | */ | ||
2607 | void | ||
2608 | GCC_handle_kx (struct CadetPeer *peer, | ||
2609 | const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg) | ||
2610 | { | ||
2611 | static struct CadetEncryptedMessageIdentifier zero; | ||
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 | |||
2635 | /* Is this message for us? */ | ||
2636 | if (GCC_is_terminal (c, fwd)) | ||
2637 | { | ||
2638 | LOG (GNUNET_ERROR_TYPE_DEBUG, " message for us!\n"); | ||
2639 | GNUNET_STATISTICS_update (stats, "# received KX", 1, GNUNET_NO); | ||
2640 | if (NULL == c->t) | ||
2641 | { | ||
2642 | GNUNET_break (0); | ||
2643 | return; | ||
2644 | } | ||
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 | */ | ||
2666 | void | ||
2667 | GCC_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; | ||
2693 | } | ||
2694 | |||
2695 | /* Is this message for us? */ | ||
2696 | if (GCC_is_terminal (c, fwd)) | ||
2697 | { | ||
2698 | GNUNET_STATISTICS_update (stats, "# received encrypted", 1, GNUNET_NO); | ||
2699 | |||
2700 | if (NULL == c->t) | ||
2701 | { | ||
2702 | GNUNET_break (GNUNET_NO != c->destroy); | ||
2703 | return; | ||
2704 | } | ||
2705 | GCT_handle_encrypted (c->t, msg); | ||
2706 | GCC_send_ack (c, fwd, GNUNET_NO); | ||
2707 | GCC_check_connections (); | ||
2708 | return; | ||
2709 | } | ||
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 | } | ||
2719 | |||
2720 | |||
2721 | /** | ||
2722 | * Initialize the connections subsystem | ||
2723 | * | ||
2724 | * @param c Configuration handle. | ||
2725 | */ | ||
2726 | void | ||
2727 | GCC_init (const struct GNUNET_CONFIGURATION_Handle *c) | ||
2728 | { | ||
2729 | LOG (GNUNET_ERROR_TYPE_DEBUG, "init\n"); | ||
2730 | if (GNUNET_OK != | ||
2731 | GNUNET_CONFIGURATION_get_value_number (c, "CADET", "MAX_MSGS_QUEUE", | ||
2732 | &max_msgs_queue)) | ||
2733 | { | ||
2734 | GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, | ||
2735 | "CADET", "MAX_MSGS_QUEUE", "MISSING"); | ||
2736 | GNUNET_SCHEDULER_shutdown (); | ||
2737 | return; | ||
2738 | } | ||
2739 | |||
2740 | if (GNUNET_OK != | ||
2741 | GNUNET_CONFIGURATION_get_value_number (c, "CADET", "MAX_CONNECTIONS", | ||
2742 | &max_connections)) | ||
2743 | { | ||
2744 | GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, | ||
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 | */ | ||
2775 | static int | ||
2776 | shutdown_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 | */ | ||
2791 | void | ||
2792 | GCC_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 | */ | ||
2815 | struct CadetConnection * | ||
2816 | GCC_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 == | ||
2830 | GNUNET_CONTAINER_multishortmap_put (connections, | ||
2831 | &c->id.connection_of_tunnel, | ||
2832 | c, | ||
2833 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
2834 | fc_init (&c->fwd_fc); | ||
2835 | fc_init (&c->bck_fc); | ||
2836 | c->fwd_fc.c = c; | ||
2837 | c->bck_fc.c = c; | ||
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 | */ | ||
2880 | void | ||
2881 | GCC_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 | */ | ||
2954 | const struct GNUNET_CADET_ConnectionTunnelIdentifier * | ||
2955 | GCC_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 | */ | ||
2968 | const struct CadetPeerPath * | ||
2969 | GCC_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 | */ | ||
2984 | enum CadetConnectionState | ||
2985 | GCC_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 | */ | ||
2997 | struct CadetTunnel * | ||
2998 | GCC_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 | */ | ||
3012 | unsigned int | ||
3013 | GCC_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 | */ | ||
3035 | unsigned int | ||
3036 | GCC_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 | */ | ||
3059 | unsigned int | ||
3060 | GCC_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 | */ | ||
3077 | struct CadetEncryptedMessageIdentifier | ||
3078 | GCC_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 | */ | ||
3100 | void | ||
3101 | GCC_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 | */ | ||
3116 | void | ||
3117 | GCC_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, | ||
3127 | "shutting down %s, %s disconnected\n", | ||
3128 | GCC_2s (c), peer_name); | ||
3129 | |||
3130 | invalidate_paths (c, peer); | ||
3131 | |||
3132 | fwd = is_fwd (c, peer); | ||
3133 | if (GNUNET_SYSERR == fwd) | ||
3134 | { | ||
3135 | GNUNET_break (0); | ||
3136 | return; | ||
3137 | } | ||
3138 | if ( (GNUNET_YES == GCC_is_terminal (c, fwd)) || | ||
3139 | (GNUNET_NO != c->destroy) ) | ||
3140 | { | ||
3141 | /* Local shutdown, or other peer already down (hence 'c->destroy'); | ||
3142 | so there is no one to notify about this, just clean up. */ | ||
3143 | GCC_destroy (c); | ||
3144 | GCC_check_connections (); | ||
3145 | return; | ||
3146 | } | ||
3147 | /* Mark FlowControl towards the peer as unavaliable. */ | ||
3148 | fc = fwd ? &c->bck_fc : &c->fwd_fc; | ||
3149 | fc->queue_max = 0; | ||
3150 | |||
3151 | send_broken (c, &my_full_id, GCP_get_id (peer), fwd); | ||
3152 | |||
3153 | /* Connection will have at least one pending message | ||
3154 | * (the one we just scheduled), so delay destruction | ||
3155 | * and remove from map so we don't use accidentally. */ | ||
3156 | mark_destroyed (c); | ||
3157 | GNUNET_assert (GNUNET_NO == c->was_removed); | ||
3158 | c->was_removed = GNUNET_YES; | ||
3159 | GNUNET_break (GNUNET_YES == | ||
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 | */ | ||
3179 | int | ||
3180 | GCC_is_origin (struct CadetConnection *c, int fwd) | ||
3181 | { | ||
3182 | if (!fwd && c->path->length - 1 == c->own_pos ) | ||
3183 | return GNUNET_YES; | ||
3184 | if (fwd && 0 == c->own_pos) | ||
3185 | return GNUNET_YES; | ||
3186 | return GNUNET_NO; | ||
3187 | } | ||
3188 | |||
3189 | |||
3190 | /** | ||
3191 | * Is this peer the last one on the connection? | ||
3192 | * | ||
3193 | * @param c Connection. | ||
3194 | * @param fwd Is this about fwd traffic? | ||
3195 | * Note that the ROOT is the terminal for BCK traffic! | ||
3196 | * | ||
3197 | * @return #GNUNET_YES if terminal, #GNUNET_NO if relay/origin. | ||
3198 | */ | ||
3199 | int | ||
3200 | GCC_is_terminal (struct CadetConnection *c, int fwd) | ||
3201 | { | ||
3202 | return GCC_is_origin (c, ! fwd); | ||
3203 | } | ||
3204 | |||
3205 | |||
3206 | /** | ||
3207 | * See if we are allowed to send by the next hop in the given direction. | ||
3208 | * | ||
3209 | * @param c Connection. | ||
3210 | * @param fwd Is this about fwd traffic? | ||
3211 | * | ||
3212 | * @return #GNUNET_YES in case it's OK to send. | ||
3213 | */ | ||
3214 | int | ||
3215 | GCC_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 | */ | ||
3250 | int | ||
3251 | GCC_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 | */ | ||
3276 | struct CadetConnectionQueue * | ||
3277 | GCC_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; | ||
3337 | } | ||
3338 | |||
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 | { | ||
3348 | fc->queue_n--; | ||
3349 | } | ||
3350 | return NULL; /* Drop this message */ | ||
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 | */ | ||
3391 | void | ||
3392 | GCC_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 | */ | ||
3408 | void | ||
3409 | GCC_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->options = 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 | { | ||
3433 | GNUNET_PEER_resolve (c->path->peers[i], peers++); | ||
3434 | } | ||
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 | } | ||
3443 | |||
3444 | LOG (GNUNET_ERROR_TYPE_INFO, "==> %s %19s on conn %s (%p) FWD [%5u]\n", | ||
3445 | GC_m2s (GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE), "", | ||
3446 | GCC_2s (c), c, size); | ||
3447 | LOG (GNUNET_ERROR_TYPE_DEBUG, " C_P+ %p %u (create)\n", | ||
3448 | c, c->pending_messages); | ||
3449 | c->pending_messages++; | ||
3450 | |||
3451 | state = GCT_get_cstate (c->t); | ||
3452 | if (CADET_TUNNEL_SEARCHING == state || CADET_TUNNEL_NEW == state) | ||
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 | } | ||
3458 | |||
3459 | |||
3460 | /** | ||
3461 | * Send an ACK on the appropriate connection/channel, depending on | ||
3462 | * the direction and the position of the peer. | ||
3463 | * | ||
3464 | * @param c Which connection to send the hop-by-hop ACK. | ||
3465 | * @param fwd Is this a fwd ACK? (will go dest->root). | ||
3466 | * @param force Send the ACK even if suboptimal (e.g. requested by POLL). | ||
3467 | */ | ||
3468 | void | ||
3469 | GCC_send_ack (struct CadetConnection *c, int fwd, int force) | ||
3470 | { | ||
3471 | unsigned int buffer; | ||
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 | |||
3483 | if (GNUNET_NO != c->destroy) | ||
3484 | { | ||
3485 | LOG (GNUNET_ERROR_TYPE_DEBUG, " being destroyed, why bother...\n"); | ||
3486 | GCC_check_connections (); | ||
3487 | return; | ||
3488 | } | ||
3489 | |||
3490 | /* Get available buffer space */ | ||
3491 | if (GCC_is_terminal (c, fwd)) | ||
3492 | { | ||
3493 | LOG (GNUNET_ERROR_TYPE_DEBUG, " getting from all channels\n"); | ||
3494 | buffer = GCT_get_channels_buffer (c->t); | ||
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 | } | ||
3522 | |||
3523 | |||
3524 | /** | ||
3525 | * Send a message to all peers in this connection that the connection | ||
3526 | * is no longer valid. | ||
3527 | * | ||
3528 | * If some peer should not receive the message, it should be zero'ed out | ||
3529 | * before calling this function. | ||
3530 | * | ||
3531 | * @param c The connection whose peers to notify. | ||
3532 | */ | ||
3533 | void | ||
3534 | GCC_send_destroy (struct CadetConnection *c) | ||
3535 | { | ||
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, | ||
3547 | " sending connection destroy for connection %s\n", | ||
3548 | GCC_2s (c)); | ||
3549 | |||
3550 | if (GNUNET_NO == GCC_is_terminal (c, GNUNET_YES)) | ||
3551 | (void) GCC_send_prebuilt_message (&msg.header, | ||
3552 | UINT16_MAX, | ||
3553 | zero, | ||
3554 | c, | ||
3555 | GNUNET_YES, GNUNET_YES, NULL, NULL); | ||
3556 | if (GNUNET_NO == GCC_is_terminal (c, GNUNET_NO)) | ||
3557 | (void) GCC_send_prebuilt_message (&msg.header, | ||
3558 | UINT16_MAX, | ||
3559 | zero, | ||
3560 | c, | ||
3561 | GNUNET_NO, GNUNET_YES, NULL, NULL); | ||
3562 | mark_destroyed (c); | ||
3563 | GCC_check_connections (); | ||
3564 | } | ||
3565 | |||
3566 | |||
3567 | /** | ||
3568 | * @brief Start a polling timer for the 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 | * | ||
3574 | * @param c Connection. | ||
3575 | * @param fwd Should we poll in the FWD direction? | ||
3576 | */ | ||
3577 | void | ||
3578 | GCC_start_poll (struct CadetConnection *c, int fwd) | ||
3579 | { | ||
3580 | struct CadetFlowControl *fc; | ||
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 | } | ||
3601 | |||
3602 | |||
3603 | /** | ||
3604 | * @brief Stop polling a connection for ACKs. | ||
3605 | * | ||
3606 | * Once we have enough ACKs for future traffic, polls are no longer necessary. | ||
3607 | * | ||
3608 | * @param c Connection. | ||
3609 | * @param fwd Should we stop the poll in the FWD direction? | ||
3610 | */ | ||
3611 | void | ||
3612 | GCC_stop_poll (struct CadetConnection *c, int fwd) | ||
3613 | { | ||
3614 | struct CadetFlowControl *fc; | ||
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 | } | ||
3628 | |||
3629 | |||
3630 | /** | ||
3631 | * Get a (static) string for a connection. | ||
3632 | * | ||
3633 | * @param c Connection. | ||
3634 | */ | ||
3635 | const char * | ||
3636 | GCC_2s (const struct CadetConnection *c) | ||
3637 | { | ||
3638 | if (NULL == c) | ||
3639 | return "NULL"; | ||
3640 | |||
3641 | if (NULL != c->t) | ||
3642 | { | ||
3643 | static char buf[128]; | ||
3644 | |||
3645 | SPRINTF (buf, "%s (->%s)", | ||
3646 | GNUNET_sh2s (&GCC_get_id (c)->connection_of_tunnel), | ||
3647 | GCT_2s (c->t)); | ||
3648 | return buf; | ||
3649 | } | ||
3650 | return GNUNET_sh2s (&c->id.connection_of_tunnel); | ||
3651 | } | ||
3652 | |||
3653 | |||
3654 | /** | ||
3655 | * Log all possible info about the connection state. | ||
3656 | * | ||
3657 | * @param c Connection to debug. | ||
3658 | * @param level Debug level to use. | ||
3659 | */ | ||
3660 | void | ||
3661 | GCC_debug (const struct CadetConnection *c, enum GNUNET_ErrorType level) | ||
3662 | { | ||
3663 | int do_log; | ||
3664 | char *s; | ||
3665 | |||
3666 | do_log = GNUNET_get_log_call_status (level & (~GNUNET_ERROR_TYPE_BULK), | ||
3667 | "cadet-con", | ||
3668 | __FILE__, __FUNCTION__, __LINE__); | ||
3669 | if (0 == do_log) | ||
3670 | return; | ||
3671 | |||
3672 | if (NULL == c) | ||
3673 | { | ||
3674 | LOG2 (level, "CCC DEBUG NULL CONNECTION\n"); | ||
3675 | return; | ||
3676 | } | ||
3677 | |||
3678 | LOG2 (level, "CCC DEBUG CONNECTION %s\n", GCC_2s (c)); | ||
3679 | s = path_2s (c->path); | ||
3680 | LOG2 (level, "CCC path %s, own pos: %u\n", s, c->own_pos); | ||
3681 | GNUNET_free (s); | ||
3682 | LOG2 (level, "CCC state: %s, destroy: %u\n", | ||
3683 | GCC_state2s (c->state), c->destroy); | ||
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 | } | ||
diff --git a/src/cadet/gnunet-service-cadet_connection.h b/src/cadet/gnunet-service-cadet_connection.h deleted file mode 100644 index 307cb42c2..000000000 --- a/src/cadet/gnunet-service-cadet_connection.h +++ /dev/null | |||
@@ -1,576 +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_connection.h | ||
23 | * @brief cadet service; dealing with connections | ||
24 | * @author Bartlomiej Polot | ||
25 | * | ||
26 | * All functions in this file use the prefix GCC (GNUnet Cadet Connection) | ||
27 | */ | ||
28 | |||
29 | #ifndef GNUNET_SERVICE_CADET_CONNECTION_H | ||
30 | #define GNUNET_SERVICE_CADET_CONNECTION_H | ||
31 | |||
32 | #ifdef __cplusplus | ||
33 | extern "C" | ||
34 | { | ||
35 | #if 0 /* keep Emacsens' auto-indent happy */ | ||
36 | } | ||
37 | #endif | ||
38 | #endif | ||
39 | |||
40 | #include "gnunet_util_lib.h" | ||
41 | |||
42 | |||
43 | /** | ||
44 | * All the states a connection can be in. | ||
45 | */ | ||
46 | enum 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 | */ | ||
83 | struct CadetConnection; | ||
84 | |||
85 | /** | ||
86 | * Handle for messages queued but not yet sent. | ||
87 | */ | ||
88 | struct CadetConnectionQueue; | ||
89 | |||
90 | #include "cadet_path.h" | ||
91 | #include "gnunet-service-cadet_channel.h" | ||
92 | #include "gnunet-service-cadet_peer.h" | ||
93 | |||
94 | |||
95 | /** | ||
96 | * Check invariants for all connections using #check_neighbours(). | ||
97 | */ | ||
98 | void | ||
99 | GCC_check_connections (void); | ||
100 | |||
101 | |||
102 | /** | ||
103 | * Callback called when a queued message is sent. | ||
104 | * | ||
105 | * @param cls Closure. | ||
106 | * @param c Connection this message was on. | ||
107 | * @param type Type of message sent. | ||
108 | * @param fwd Was this a FWD going message? | ||
109 | * @param size Size of the message. | ||
110 | */ | ||
111 | typedef void | ||
112 | (*GCC_sent) (void *cls, | ||
113 | struct CadetConnection *c, | ||
114 | struct CadetConnectionQueue *q, | ||
115 | uint16_t type, | ||
116 | int fwd, | ||
117 | size_t size); | ||
118 | |||
119 | |||
120 | /** | ||
121 | * Handler for connection creation. | ||
122 | * | ||
123 | * @param peer Message sender (neighbor). | ||
124 | * @param msg Message itself. | ||
125 | */ | ||
126 | void | ||
127 | GCC_handle_create (struct CadetPeer *peer, | ||
128 | const struct GNUNET_CADET_ConnectionCreateMessage *msg); | ||
129 | |||
130 | |||
131 | /** | ||
132 | * Handler for connection confirmations. | ||
133 | * | ||
134 | * @param peer Message sender (neighbor). | ||
135 | * @param msg Message itself. | ||
136 | */ | ||
137 | void | ||
138 | GCC_handle_confirm (struct CadetPeer *peer, | ||
139 | const struct GNUNET_CADET_ConnectionCreateAckMessage *msg); | ||
140 | |||
141 | |||
142 | /** | ||
143 | * Handler for notifications of broken connections. | ||
144 | * | ||
145 | * @param peer Message sender (neighbor). | ||
146 | * @param msg Message itself. | ||
147 | */ | ||
148 | void | ||
149 | GCC_handle_broken (struct CadetPeer *peer, | ||
150 | const struct GNUNET_CADET_ConnectionBrokenMessage *msg); | ||
151 | |||
152 | /** | ||
153 | * Handler for notifications of destroyed connections. | ||
154 | * | ||
155 | * @param peer Message sender (neighbor). | ||
156 | * @param msg Message itself. | ||
157 | */ | ||
158 | void | ||
159 | GCC_handle_destroy (struct CadetPeer *peer, | ||
160 | const struct GNUNET_CADET_ConnectionDestroyMessage *msg); | ||
161 | |||
162 | /** | ||
163 | * Handler for cadet network traffic hop-by-hop acks. | ||
164 | * | ||
165 | * @param peer Message sender (neighbor). | ||
166 | * @param msg Message itself. | ||
167 | */ | ||
168 | void | ||
169 | GCC_handle_ack (struct CadetPeer *peer, | ||
170 | const struct GNUNET_CADET_ConnectionEncryptedAckMessage *msg); | ||
171 | |||
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 | */ | ||
178 | void | ||
179 | GCC_handle_poll (struct CadetPeer *peer, | ||
180 | const struct GNUNET_CADET_ConnectionHopByHopPollMessage *msg); | ||
181 | |||
182 | /** | ||
183 | * Handler for key exchange traffic (Axolotl KX). | ||
184 | * | ||
185 | * @param peer Message sender (neighbor). | ||
186 | * @param msg Message itself. | ||
187 | */ | ||
188 | void | ||
189 | GCC_handle_kx (struct CadetPeer *peer, | ||
190 | const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg); | ||
191 | |||
192 | /** | ||
193 | * Handler for encrypted cadet network traffic (channel mgmt, data). | ||
194 | * | ||
195 | * @param peer Message sender (neighbor). | ||
196 | * @param msg Message itself. | ||
197 | */ | ||
198 | void | ||
199 | GCC_handle_encrypted (struct CadetPeer *peer, | ||
200 | const struct GNUNET_CADET_TunnelEncryptedMessage *msg); | ||
201 | |||
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 | */ | ||
211 | int | ||
212 | GCC_handle_ax_kx (void *cls, const struct GNUNET_PeerIdentity *peer, | ||
213 | const struct GNUNET_MessageHeader *message); | ||
214 | |||
215 | /** | ||
216 | * Core handler for axolotl encrypted cadet network traffic. | ||
217 | * | ||
218 | * @param cls Closure (unused). | ||
219 | * @param message Message received. | ||
220 | * @param peer Neighbor who sent the message. | ||
221 | * | ||
222 | * @return GNUNET_OK, to keep the connection open. | ||
223 | */ | ||
224 | int | ||
225 | GCC_handle_ax (void *cls, const struct GNUNET_PeerIdentity *peer, | ||
226 | struct GNUNET_MessageHeader *message); | ||
227 | |||
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 | */ | ||
239 | int | ||
240 | GCC_handle_keepalive (void *cls, const struct GNUNET_PeerIdentity *peer, | ||
241 | const struct GNUNET_MessageHeader *message); | ||
242 | |||
243 | /** | ||
244 | * Send an ACK on the appropriate connection/channel, depending on | ||
245 | * the direction and the position of the peer. | ||
246 | * | ||
247 | * @param c Which connection to send the hop-by-hop ACK. | ||
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 | */ | ||
251 | void | ||
252 | GCC_send_ack (struct CadetConnection *c, int fwd, int force); | ||
253 | |||
254 | /** | ||
255 | * Initialize the connections subsystem | ||
256 | * | ||
257 | * @param c Configuration handle. | ||
258 | */ | ||
259 | void | ||
260 | GCC_init (const struct GNUNET_CONFIGURATION_Handle *c); | ||
261 | |||
262 | /** | ||
263 | * Shut down the connections subsystem. | ||
264 | */ | ||
265 | void | ||
266 | GCC_shutdown (void); | ||
267 | |||
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 | */ | ||
279 | struct CadetConnection * | ||
280 | GCC_new (const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid, | ||
281 | struct CadetTunnel *t, | ||
282 | struct CadetPeerPath *path, | ||
283 | unsigned int own_pos); | ||
284 | |||
285 | /** | ||
286 | * Connection is no longer needed: destroy it. | ||
287 | * | ||
288 | * Cancels all pending traffic (including possible DESTROY messages), all | ||
289 | * maintenance tasks and removes the connection from neighbor peers and tunnel. | ||
290 | * | ||
291 | * @param c Connection to destroy. | ||
292 | */ | ||
293 | void | ||
294 | GCC_destroy (struct CadetConnection *c); | ||
295 | |||
296 | /** | ||
297 | * Get the connection ID. | ||
298 | * | ||
299 | * @param c Connection to get the ID from. | ||
300 | * | ||
301 | * @return ID of the connection. | ||
302 | */ | ||
303 | const struct GNUNET_CADET_ConnectionTunnelIdentifier * | ||
304 | GCC_get_id (const struct CadetConnection *c); | ||
305 | |||
306 | |||
307 | /** | ||
308 | * Get the connection path. | ||
309 | * | ||
310 | * @param c Connection to get the path from. | ||
311 | * | ||
312 | * @return path used by the connection. | ||
313 | */ | ||
314 | const struct CadetPeerPath * | ||
315 | GCC_get_path (const struct CadetConnection *c); | ||
316 | |||
317 | /** | ||
318 | * Get the connection state. | ||
319 | * | ||
320 | * @param c Connection to get the state from. | ||
321 | * | ||
322 | * @return state of the connection. | ||
323 | */ | ||
324 | enum CadetConnectionState | ||
325 | GCC_get_state (const struct CadetConnection *c); | ||
326 | |||
327 | /** | ||
328 | * Get the connection tunnel. | ||
329 | * | ||
330 | * @param c Connection to get the tunnel from. | ||
331 | * | ||
332 | * @return tunnel of the connection. | ||
333 | */ | ||
334 | struct CadetTunnel * | ||
335 | GCC_get_tunnel (const struct CadetConnection *c); | ||
336 | |||
337 | /** | ||
338 | * Get free buffer space in a connection. | ||
339 | * | ||
340 | * @param c Connection. | ||
341 | * @param fwd Is query about FWD traffic? | ||
342 | * | ||
343 | * @return Free buffer space [0 - max_msgs_queue/max_connections] | ||
344 | */ | ||
345 | unsigned int | ||
346 | GCC_get_buffer (struct CadetConnection *c, int fwd); | ||
347 | |||
348 | /** | ||
349 | * Get how many messages have we allowed to send to us from a direction. | ||
350 | * | ||
351 | * @param c Connection. | ||
352 | * @param fwd Are we asking about traffic from FWD (BCK messages)? | ||
353 | * | ||
354 | * @return last_ack_sent - last_pid_recv | ||
355 | */ | ||
356 | unsigned int | ||
357 | GCC_get_allowed (struct CadetConnection *c, int fwd); | ||
358 | |||
359 | /** | ||
360 | * Get messages queued in a connection. | ||
361 | * | ||
362 | * @param c Connection. | ||
363 | * @param fwd Is query about FWD traffic? | ||
364 | * | ||
365 | * @return Number of messages queued. | ||
366 | */ | ||
367 | unsigned int | ||
368 | GCC_get_qn (struct CadetConnection *c, int fwd); | ||
369 | |||
370 | /** | ||
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 | */ | ||
377 | struct CadetEncryptedMessageIdentifier | ||
378 | GCC_get_pid (struct CadetConnection *c, int fwd); | ||
379 | |||
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 | */ | ||
390 | void | ||
391 | GCC_allow (struct CadetConnection *c, unsigned int buffer, int fwd); | ||
392 | |||
393 | /** | ||
394 | * Send FWD keepalive packets for a connection. | ||
395 | * | ||
396 | * @param cls Closure (connection for which to send the keepalive). | ||
397 | * @param tc Notification context. | ||
398 | */ | ||
399 | void | ||
400 | GCC_fwd_keepalive (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
401 | |||
402 | /** | ||
403 | * Send BCK keepalive packets for a connection. | ||
404 | * | ||
405 | * @param cls Closure (connection for which to send the keepalive). | ||
406 | * @param tc Notification context. | ||
407 | */ | ||
408 | void | ||
409 | GCC_bck_keepalive (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
410 | |||
411 | |||
412 | /** | ||
413 | * Notify other peers on a connection of a broken link. Mark connections | ||
414 | * to destroy after all traffic has been sent. | ||
415 | * | ||
416 | * @param c Connection on which there has been a disconnection. | ||
417 | * @param peer Peer that disconnected. | ||
418 | */ | ||
419 | void | ||
420 | GCC_neighbor_disconnected (struct CadetConnection *c, struct CadetPeer *peer); | ||
421 | |||
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 | */ | ||
430 | int | ||
431 | GCC_is_origin (struct CadetConnection *c, int fwd); | ||
432 | |||
433 | /** | ||
434 | * Is this peer the last one on the connection? | ||
435 | * | ||
436 | * @param c Connection. | ||
437 | * @param fwd Is this about fwd traffic? | ||
438 | * Note that the ROOT is the terminal for BCK traffic! | ||
439 | * | ||
440 | * @return #GNUNET_YES if terminal, #GNUNET_NO if relay/origin. | ||
441 | */ | ||
442 | int | ||
443 | GCC_is_terminal (struct CadetConnection *c, int fwd); | ||
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 | */ | ||
453 | int | ||
454 | GCC_is_sendable (struct CadetConnection *c, int fwd); | ||
455 | |||
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 | */ | ||
463 | int | ||
464 | GCC_is_direct (struct CadetConnection *c); | ||
465 | |||
466 | /** | ||
467 | * Cancel a previously sent message while it's in the queue. | ||
468 | * | ||
469 | * ONLY can be called before the continuation given to the send function | ||
470 | * is called. Once the continuation is called, the message is no longer in the | ||
471 | * queue. | ||
472 | * | ||
473 | * @param q Handle to the queue. | ||
474 | */ | ||
475 | void | ||
476 | GCC_cancel (struct CadetConnectionQueue *q); | ||
477 | |||
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 | */ | ||
497 | struct CadetConnectionQueue * | ||
498 | GCC_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 | |||
504 | /** | ||
505 | * Sends a CREATE CONNECTION message for a path to a peer. | ||
506 | * Changes the connection and tunnel states if necessary. | ||
507 | * | ||
508 | * @param connection Connection to create. | ||
509 | */ | ||
510 | void | ||
511 | GCC_send_create (struct CadetConnection *connection); | ||
512 | |||
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 | */ | ||
522 | void | ||
523 | GCC_send_destroy (struct CadetConnection *c); | ||
524 | |||
525 | /** | ||
526 | * @brief Start a polling timer for the connection. | ||
527 | * | ||
528 | * When a neighbor does not accept more traffic on the connection it could be | ||
529 | * caused by a simple congestion or by a lost ACK. Polling enables to check | ||
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 | */ | ||
535 | void | ||
536 | GCC_start_poll (struct CadetConnection *c, int fwd); | ||
537 | |||
538 | |||
539 | /** | ||
540 | * @brief Stop polling a connection for ACKs. | ||
541 | * | ||
542 | * Once we have enough ACKs for future traffic, polls are no longer necessary. | ||
543 | * | ||
544 | * @param c Connection. | ||
545 | * @param fwd Should we stop the poll in the FWD direction? | ||
546 | */ | ||
547 | void | ||
548 | GCC_stop_poll (struct CadetConnection *c, int fwd); | ||
549 | |||
550 | /** | ||
551 | * Get a (static) string for a connection. | ||
552 | * | ||
553 | * @param c Connection. | ||
554 | */ | ||
555 | const char * | ||
556 | GCC_2s (const struct CadetConnection *c); | ||
557 | |||
558 | /** | ||
559 | * Log all possible info about the connection state. | ||
560 | * | ||
561 | * @param c Connection to debug. | ||
562 | * @param level Debug level to use. | ||
563 | */ | ||
564 | void | ||
565 | GCC_debug (const struct CadetConnection *c, enum GNUNET_ErrorType level); | ||
566 | |||
567 | #if 0 /* keep Emacsens' auto-indent happy */ | ||
568 | { | ||
569 | #endif | ||
570 | #ifdef __cplusplus | ||
571 | } | ||
572 | #endif | ||
573 | |||
574 | /* ifndef GNUNET_SERVICE_CADET_CONNECTION_H */ | ||
575 | #endif | ||
576 | /* end of gnunet-service-cadet_connection.h */ | ||
diff --git a/src/cadet/gnunet-service-cadet_dht.c b/src/cadet/gnunet-service-cadet_dht.c deleted file mode 100644 index 22673b167..000000000 --- a/src/cadet/gnunet-service-cadet_dht.c +++ /dev/null | |||
@@ -1,424 +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_dht_service.h" | ||
26 | #include "gnunet_statistics_service.h" | ||
27 | |||
28 | #include "cadet_path.h" | ||
29 | #include "gnunet-service-cadet_dht.h" | ||
30 | #include "gnunet-service-cadet_peer.h" | ||
31 | #include "gnunet-service-cadet_hello.h" | ||
32 | |||
33 | #define LOG(level, ...) GNUNET_log_from (level,"cadet-dht",__VA_ARGS__) | ||
34 | |||
35 | |||
36 | /******************************************************************************/ | ||
37 | /******************************** STRUCTS **********************************/ | ||
38 | /******************************************************************************/ | ||
39 | |||
40 | /** | ||
41 | * Handle for DHT searches. | ||
42 | */ | ||
43 | struct GCD_search_handle | ||
44 | { | ||
45 | /** | ||
46 | * DHT_GET handle. | ||
47 | */ | ||
48 | struct GNUNET_DHT_GetHandle *dhtget; | ||
49 | |||
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 | }; | ||
65 | |||
66 | |||
67 | /******************************************************************************/ | ||
68 | /******************************* GLOBALS ***********************************/ | ||
69 | /******************************************************************************/ | ||
70 | |||
71 | /** | ||
72 | * Global handle to the statistics service. | ||
73 | */ | ||
74 | extern struct GNUNET_STATISTICS_Handle *stats; | ||
75 | |||
76 | /** | ||
77 | * Own ID (short value). | ||
78 | */ | ||
79 | extern GNUNET_PEER_Id myid; | ||
80 | |||
81 | /** | ||
82 | * Own ID (full value). | ||
83 | */ | ||
84 | extern struct GNUNET_PeerIdentity my_full_id; | ||
85 | |||
86 | /** | ||
87 | * Handle to use DHT. | ||
88 | */ | ||
89 | static struct GNUNET_DHT_Handle *dht_handle; | ||
90 | |||
91 | /** | ||
92 | * How often to PUT own ID in the DHT. | ||
93 | */ | ||
94 | static struct GNUNET_TIME_Relative id_announce_time; | ||
95 | |||
96 | /** | ||
97 | * DHT replication level, see DHT API: GNUNET_DHT_get_start, GNUNET_DHT_put. | ||
98 | */ | ||
99 | static unsigned long long dht_replication_level; | ||
100 | |||
101 | /** | ||
102 | * Task to periodically announce itself in the network. | ||
103 | */ | ||
104 | static struct GNUNET_SCHEDULER_Task * announce_id_task; | ||
105 | |||
106 | /** | ||
107 | * Delay for the next ID announce. | ||
108 | */ | ||
109 | static struct GNUNET_TIME_Relative announce_delay; | ||
110 | |||
111 | /** | ||
112 | * GET requests to stop on shutdown. | ||
113 | */ | ||
114 | static 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 | */ | ||
129 | static struct CadetPeerPath * | ||
130 | path_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 | |||
161 | /** | ||
162 | * Function to process paths received for a new peer addition. The recorded | ||
163 | * paths form the initial tunnel, which can be optimized later. | ||
164 | * Called on each result obtained for the DHT search. | ||
165 | * | ||
166 | * @param cls closure | ||
167 | * @param exp when will this value expire | ||
168 | * @param key key of the result | ||
169 | * @param get_path path of the get request | ||
170 | * @param get_path_length lenght of @a get_path | ||
171 | * @param put_path path of the put request | ||
172 | * @param put_path_length length of the @a put_path | ||
173 | * @param type type of the result | ||
174 | * @param size number of bytes in data | ||
175 | * @param data pointer to the result data | ||
176 | */ | ||
177 | static void | ||
178 | dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp, | ||
179 | const struct GNUNET_HashCode * key, | ||
180 | const struct GNUNET_PeerIdentity *get_path, | ||
181 | unsigned int get_path_length, | ||
182 | const struct GNUNET_PeerIdentity *put_path, | ||
183 | unsigned int put_path_length, enum GNUNET_BLOCK_Type type, | ||
184 | size_t size, const void *data) | ||
185 | { | ||
186 | struct GCD_search_handle *h = cls; | ||
187 | struct GNUNET_HELLO_Message *hello; | ||
188 | struct CadetPeerPath *p; | ||
189 | struct CadetPeer *peer; | ||
190 | char *s; | ||
191 | |||
192 | p = path_build_from_dht (get_path, get_path_length, | ||
193 | put_path, put_path_length); | ||
194 | if (NULL == p) | ||
195 | { | ||
196 | GNUNET_break_op (0); | ||
197 | return; | ||
198 | } | ||
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 | } | ||
216 | |||
217 | |||
218 | /** | ||
219 | * Periodically announce self id in the DHT | ||
220 | * | ||
221 | * @param cls closure | ||
222 | */ | ||
223 | static void | ||
224 | announce_id (void *cls) | ||
225 | { | ||
226 | struct GNUNET_HashCode phash; | ||
227 | const struct GNUNET_HELLO_Message *hello; | ||
228 | size_t size; | ||
229 | struct GNUNET_TIME_Absolute expiration; | ||
230 | struct GNUNET_TIME_Relative next_put; | ||
231 | |||
232 | announce_id_task = NULL; | ||
233 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Announce ID\n"); | ||
234 | hello = GCH_get_mine (); | ||
235 | size = (NULL != hello) ? GNUNET_HELLO_size (hello) : 0; | ||
236 | if ( (NULL == hello) || (0 == size) ) | ||
237 | { | ||
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 (), | ||
246 | announce_delay); | ||
247 | announce_delay = GNUNET_TIME_STD_BACKOFF (announce_delay); | ||
248 | } | ||
249 | else | ||
250 | { | ||
251 | expiration = GNUNET_HELLO_get_last_expiration (hello); | ||
252 | announce_delay = GNUNET_TIME_UNIT_SECONDS; | ||
253 | } | ||
254 | |||
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, | ||
283 | * but wait at least 1s. */ | ||
284 | next_put = GNUNET_TIME_absolute_get_remaining (expiration); | ||
285 | next_put = GNUNET_TIME_relative_min (next_put, | ||
286 | id_announce_time); | ||
287 | next_put = GNUNET_TIME_relative_max (next_put, | ||
288 | GNUNET_TIME_UNIT_SECONDS); | ||
289 | announce_id_task = GNUNET_SCHEDULER_add_delayed (next_put, | ||
290 | &announce_id, | ||
291 | cls); | ||
292 | } | ||
293 | |||
294 | /** | ||
295 | * Iterator over hash map entries and stop GET requests before disconnecting | ||
296 | * from the DHT. | ||
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 | */ | ||
304 | int | ||
305 | stop_get (void *cls, | ||
306 | uint32_t key, | ||
307 | void *value) | ||
308 | { | ||
309 | struct GCD_search_handle *h = value; | ||
310 | |||
311 | GCD_search_stop (h); | ||
312 | return GNUNET_YES; | ||
313 | } | ||
314 | |||
315 | |||
316 | /******************************************************************************/ | ||
317 | /******************************** API ***********************************/ | ||
318 | /******************************************************************************/ | ||
319 | |||
320 | /** | ||
321 | * Initialize the DHT subsystem. | ||
322 | * | ||
323 | * @param c Configuration. | ||
324 | */ | ||
325 | void | ||
326 | GCD_init (const struct GNUNET_CONFIGURATION_Handle *c) | ||
327 | { | ||
328 | LOG (GNUNET_ERROR_TYPE_DEBUG, "init\n"); | ||
329 | if (GNUNET_OK != | ||
330 | GNUNET_CONFIGURATION_get_value_number (c, "CADET", | ||
331 | "DHT_REPLICATION_LEVEL", | ||
332 | &dht_replication_level)) | ||
333 | { | ||
334 | GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING, "CADET", | ||
335 | "DHT_REPLICATION_LEVEL", "USING DEFAULT"); | ||
336 | dht_replication_level = 3; | ||
337 | } | ||
338 | |||
339 | if (GNUNET_OK != | ||
340 | GNUNET_CONFIGURATION_get_value_time (c, "CADET", "ID_ANNOUNCE_TIME", | ||
341 | &id_announce_time)) | ||
342 | { | ||
343 | GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, "CADET", | ||
344 | "ID_ANNOUNCE_TIME", "MISSING"); | ||
345 | GNUNET_SCHEDULER_shutdown (); | ||
346 | return; | ||
347 | } | ||
348 | |||
349 | dht_handle = GNUNET_DHT_connect (c, 64); | ||
350 | if (NULL == dht_handle) | ||
351 | { | ||
352 | GNUNET_break (0); | ||
353 | } | ||
354 | |||
355 | announce_delay = GNUNET_TIME_UNIT_SECONDS; | ||
356 | announce_id_task = GNUNET_SCHEDULER_add_now (&announce_id, NULL); | ||
357 | get_requests = GNUNET_CONTAINER_multihashmap32_create (32); | ||
358 | } | ||
359 | |||
360 | |||
361 | /** | ||
362 | * Shut down the DHT subsystem. | ||
363 | */ | ||
364 | void | ||
365 | GCD_shutdown (void) | ||
366 | { | ||
367 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down DHT\n"); | ||
368 | GNUNET_CONTAINER_multihashmap32_iterate (get_requests, &stop_get, NULL); | ||
369 | GNUNET_CONTAINER_multihashmap32_destroy (get_requests); | ||
370 | if (dht_handle != NULL) | ||
371 | { | ||
372 | GNUNET_DHT_disconnect (dht_handle); | ||
373 | dht_handle = NULL; | ||
374 | } | ||
375 | if (NULL != announce_id_task) | ||
376 | { | ||
377 | GNUNET_SCHEDULER_cancel (announce_id_task); | ||
378 | announce_id_task = NULL; | ||
379 | } | ||
380 | } | ||
381 | |||
382 | struct GCD_search_handle * | ||
383 | GCD_search (const struct GNUNET_PeerIdentity *peer_id, | ||
384 | GCD_search_callback callback, void *cls) | ||
385 | { | ||
386 | struct GNUNET_HashCode phash; | ||
387 | struct GCD_search_handle *h; | ||
388 | |||
389 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting DHT GET for peer %s\n", | ||
390 | GNUNET_i2s (peer_id)); | ||
391 | GNUNET_STATISTICS_update (stats, "# DHT search", 1, GNUNET_NO); | ||
392 | memset (&phash, 0, sizeof (phash)); | ||
393 | GNUNET_memcpy (&phash, peer_id, sizeof (*peer_id)); | ||
394 | 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 */ | ||
399 | GNUNET_BLOCK_TYPE_DHT_HELLO, /* type */ | ||
400 | &phash, /* key to search */ | ||
401 | dht_replication_level, /* replication level */ | ||
402 | GNUNET_DHT_RO_RECORD_ROUTE | | ||
403 | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, | ||
404 | NULL, /* xquery */ | ||
405 | 0, /* xquery bits */ | ||
406 | &dht_get_id_handler, | ||
407 | h); | ||
408 | GNUNET_CONTAINER_multihashmap32_put (get_requests, | ||
409 | h->peer_id, | ||
410 | h, | ||
411 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); | ||
412 | return h; | ||
413 | } | ||
414 | |||
415 | |||
416 | void | ||
417 | GCD_search_stop (struct GCD_search_handle *h) | ||
418 | { | ||
419 | GNUNET_break (GNUNET_OK == | ||
420 | GNUNET_CONTAINER_multihashmap32_remove (get_requests, | ||
421 | h->peer_id, h)); | ||
422 | GNUNET_DHT_get_stop (h->dhtget); | ||
423 | GNUNET_free (h); | ||
424 | } | ||
diff --git a/src/cadet/gnunet-service-cadet_dht.h b/src/cadet/gnunet-service-cadet_dht.h deleted file mode 100644 index b70dfe975..000000000 --- a/src/cadet/gnunet-service-cadet_dht.h +++ /dev/null | |||
@@ -1,93 +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_dht.h | ||
23 | * @brief cadet service; dealing with DHT requests and results | ||
24 | * @author Bartlomiej Polot | ||
25 | * | ||
26 | * All functions in this file should use the prefix GMD (Gnunet Cadet Dht) | ||
27 | */ | ||
28 | |||
29 | #ifndef GNUNET_SERVICE_CADET_DHT_H | ||
30 | #define GNUNET_SERVICE_CADET_DHT_H | ||
31 | |||
32 | #ifdef __cplusplus | ||
33 | extern "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 | struct GCD_search_handle; | ||
44 | |||
45 | |||
46 | /** | ||
47 | * Callback called on each path found over the DHT. | ||
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 | */ | ||
53 | typedef void | ||
54 | (*GCD_search_callback) (void *cls, | ||
55 | const struct CadetPeerPath *path); | ||
56 | |||
57 | /******************************************************************************/ | ||
58 | /******************************** API ***********************************/ | ||
59 | /******************************************************************************/ | ||
60 | |||
61 | /** | ||
62 | * Initialize the DHT subsystem. | ||
63 | * | ||
64 | * @param c Configuration. | ||
65 | */ | ||
66 | void | ||
67 | GCD_init (const struct GNUNET_CONFIGURATION_Handle *c); | ||
68 | |||
69 | /** | ||
70 | * Shut down the DHT subsystem. | ||
71 | */ | ||
72 | void | ||
73 | GCD_shutdown (void); | ||
74 | |||
75 | |||
76 | struct GCD_search_handle * | ||
77 | GCD_search (const struct GNUNET_PeerIdentity *peer_id, | ||
78 | GCD_search_callback callback, void *cls); | ||
79 | |||
80 | |||
81 | void | ||
82 | GCD_search_stop (struct GCD_search_handle *h); | ||
83 | |||
84 | #if 0 /* keep Emacsens' auto-indent happy */ | ||
85 | { | ||
86 | #endif | ||
87 | #ifdef __cplusplus | ||
88 | } | ||
89 | #endif | ||
90 | |||
91 | /* ifndef GNUNET_CADET_SERVICE_LOCAL_H */ | ||
92 | #endif | ||
93 | /* end of gnunet-cadet-service_LOCAL.h */ | ||
diff --git a/src/cadet/gnunet-service-cadet_hello.c b/src/cadet/gnunet-service-cadet_hello.c deleted file mode 100644 index 3c63f3551..000000000 --- a/src/cadet/gnunet-service-cadet_hello.c +++ /dev/null | |||
@@ -1,200 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2014 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 | #include "platform.h" | ||
22 | #include "gnunet_util_lib.h" | ||
23 | |||
24 | #include "gnunet_statistics_service.h" | ||
25 | #include "gnunet_peerinfo_service.h" | ||
26 | |||
27 | #include "cadet_protocol.h" | ||
28 | #include "cadet_path.h" | ||
29 | |||
30 | #include "gnunet-service-cadet_hello.h" | ||
31 | #include "gnunet-service-cadet_peer.h" | ||
32 | |||
33 | #define LOG(level, ...) GNUNET_log_from(level,"cadet-hll",__VA_ARGS__) | ||
34 | |||
35 | |||
36 | /******************************************************************************/ | ||
37 | /******************************** STRUCTS **********************************/ | ||
38 | /******************************************************************************/ | ||
39 | |||
40 | |||
41 | |||
42 | /******************************************************************************/ | ||
43 | /******************************* GLOBALS ***********************************/ | ||
44 | /******************************************************************************/ | ||
45 | |||
46 | /** | ||
47 | * Global handle to the statistics service. | ||
48 | */ | ||
49 | extern struct GNUNET_STATISTICS_Handle *stats; | ||
50 | |||
51 | /** | ||
52 | * Local peer own ID (memory efficient handle). | ||
53 | */ | ||
54 | extern GNUNET_PEER_Id myid; | ||
55 | |||
56 | /** | ||
57 | * Local peer own ID (full value). | ||
58 | */ | ||
59 | extern struct GNUNET_PeerIdentity my_full_id; | ||
60 | |||
61 | |||
62 | /** | ||
63 | * Don't try to recover tunnels if shutting down. | ||
64 | */ | ||
65 | extern int shutting_down; | ||
66 | |||
67 | |||
68 | /** | ||
69 | * Hello message of local peer. | ||
70 | */ | ||
71 | const struct GNUNET_HELLO_Message *mine; | ||
72 | |||
73 | /** | ||
74 | * Handle to peerinfo service. | ||
75 | */ | ||
76 | static struct GNUNET_PEERINFO_Handle *peerinfo; | ||
77 | |||
78 | /** | ||
79 | * Iterator context. | ||
80 | */ | ||
81 | struct GNUNET_PEERINFO_NotifyContext* nc; | ||
82 | |||
83 | |||
84 | /******************************************************************************/ | ||
85 | /******************************** STATIC ***********************************/ | ||
86 | /******************************************************************************/ | ||
87 | |||
88 | /** | ||
89 | * Process each hello message received from peerinfo. | ||
90 | * | ||
91 | * @param cls Closure (unused). | ||
92 | * @param peer Identity of the peer. | ||
93 | * @param hello Hello of the peer. | ||
94 | * @param err_msg Error message. | ||
95 | */ | ||
96 | static void | ||
97 | got_hello (void *cls, const struct GNUNET_PeerIdentity *id, | ||
98 | const struct GNUNET_HELLO_Message *hello, | ||
99 | const char *err_msg) | ||
100 | { | ||
101 | struct CadetPeer *peer; | ||
102 | |||
103 | if (NULL == id || NULL == hello) | ||
104 | { | ||
105 | LOG (GNUNET_ERROR_TYPE_DEBUG, " hello with id %p and msg %p\n", id, hello); | ||
106 | return; | ||
107 | } | ||
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 | |||
118 | |||
119 | /******************************************************************************/ | ||
120 | /******************************** API ***********************************/ | ||
121 | /******************************************************************************/ | ||
122 | |||
123 | /** | ||
124 | * Initialize the hello subsystem. | ||
125 | * | ||
126 | * @param c Configuration. | ||
127 | */ | ||
128 | void | ||
129 | GCH_init (const struct GNUNET_CONFIGURATION_Handle *c) | ||
130 | { | ||
131 | LOG (GNUNET_ERROR_TYPE_DEBUG, "init\n"); | ||
132 | GNUNET_assert (NULL == nc); | ||
133 | peerinfo = GNUNET_PEERINFO_connect (c); | ||
134 | nc = GNUNET_PEERINFO_notify (c, GNUNET_NO, &got_hello, NULL); | ||
135 | } | ||
136 | |||
137 | |||
138 | /** | ||
139 | * Shut down the hello subsystem. | ||
140 | */ | ||
141 | void | ||
142 | GCH_shutdown () | ||
143 | { | ||
144 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down channels\n"); | ||
145 | if (NULL != nc) | ||
146 | { | ||
147 | GNUNET_PEERINFO_notify_cancel (nc); | ||
148 | nc = NULL; | ||
149 | } | ||
150 | if (NULL != peerinfo) | ||
151 | { | ||
152 | GNUNET_PEERINFO_disconnect (peerinfo); | ||
153 | peerinfo = NULL; | ||
154 | } | ||
155 | } | ||
156 | |||
157 | |||
158 | /** | ||
159 | * Get own hello message. | ||
160 | * | ||
161 | * @return Own hello message. | ||
162 | */ | ||
163 | const struct GNUNET_HELLO_Message * | ||
164 | GCH_get_mine (void) | ||
165 | { | ||
166 | return mine; | ||
167 | } | ||
168 | |||
169 | |||
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 | */ | ||
177 | const struct GNUNET_HELLO_Message * | ||
178 | GCH_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 | */ | ||
194 | char * | ||
195 | GCH_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 deleted file mode 100644 index 34121e1e0..000000000 --- a/src/cadet/gnunet-service-cadet_hello.h +++ /dev/null | |||
@@ -1,79 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2014 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 | * | ||
26 | * All functions in this file should use the prefix GMH (Gnunet Cadet Hello) | ||
27 | */ | ||
28 | |||
29 | #ifndef GNUNET_SERVICE_CADET_HELLO_H | ||
30 | #define GNUNET_SERVICE_CADET_HELLO_H | ||
31 | |||
32 | #ifdef __cplusplus | ||
33 | extern "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 | #include "gnunet_hello_lib.h" | ||
43 | |||
44 | |||
45 | /** | ||
46 | * Initialize the hello subsystem. | ||
47 | * | ||
48 | * @param c Configuration. | ||
49 | */ | ||
50 | void | ||
51 | GCH_init (const struct GNUNET_CONFIGURATION_Handle *c); | ||
52 | |||
53 | |||
54 | /** | ||
55 | * Shut down the hello subsystem. | ||
56 | */ | ||
57 | void | ||
58 | GCH_shutdown (void); | ||
59 | |||
60 | |||
61 | /** | ||
62 | * Get own hello message. | ||
63 | * | ||
64 | * @return Own hello message. | ||
65 | */ | ||
66 | const struct GNUNET_HELLO_Message * | ||
67 | GCH_get_mine (void); | ||
68 | |||
69 | |||
70 | #if 0 /* keep Emacsens' auto-indent happy */ | ||
71 | { | ||
72 | #endif | ||
73 | #ifdef __cplusplus | ||
74 | } | ||
75 | #endif | ||
76 | |||
77 | /* ifndef GNUNET_CADET_SERVICE_HELLO_H */ | ||
78 | #endif | ||
79 | /* end of gnunet-cadet-service_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 | */ | ||
48 | struct 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 | */ | ||
105 | extern struct GNUNET_STATISTICS_Handle *stats; | ||
106 | |||
107 | /** | ||
108 | * Handle to server lib. | ||
109 | */ | ||
110 | static struct GNUNET_SERVER_Handle *server_handle; | ||
111 | |||
112 | /** | ||
113 | * DLL with all the clients, head. | ||
114 | */ | ||
115 | static struct CadetClient *clients_head; | ||
116 | |||
117 | /** | ||
118 | * DLL with all the clients, tail. | ||
119 | */ | ||
120 | static struct CadetClient *clients_tail; | ||
121 | |||
122 | /** | ||
123 | * Next ID to assign to a client. | ||
124 | */ | ||
125 | unsigned int next_client_id; | ||
126 | |||
127 | /** | ||
128 | * All ports clients of this peer have opened. | ||
129 | */ | ||
130 | static struct GNUNET_CONTAINER_MultiHashMap *ports; | ||
131 | |||
132 | /** | ||
133 | * Notification context, to send messages to local clients. | ||
134 | */ | ||
135 | static 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 | */ | ||
151 | static int | ||
152 | client_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 | */ | ||
179 | static int | ||
180 | channel_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 | */ | ||
203 | static void | ||
204 | client_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 | */ | ||
241 | static struct CadetClient * | ||
242 | client_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 | */ | ||
276 | static void | ||
277 | handle_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 | */ | ||
294 | static void | ||
295 | handle_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 | */ | ||
323 | static void | ||
324 | handle_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 | */ | ||
380 | static void | ||
381 | handle_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 | */ | ||
424 | static void | ||
425 | handle_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 | */ | ||
471 | static void | ||
472 | handle_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 | */ | ||
534 | static void | ||
535 | handle_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 | */ | ||
624 | static void | ||
625 | handle_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 | */ | ||
685 | static int | ||
686 | get_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 | */ | ||
718 | static int | ||
719 | show_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 | */ | ||
747 | static int | ||
748 | path_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 | */ | ||
798 | static void | ||
799 | handle_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 | */ | ||
835 | void | ||
836 | handle_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 | */ | ||
900 | static int | ||
901 | get_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 | */ | ||
933 | static void | ||
934 | handle_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 | |||
963 | static void | ||
964 | iter_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 | |||
974 | static void | ||
975 | iter_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 | */ | ||
993 | void | ||
994 | handle_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 | */ | ||
1079 | void | ||
1080 | handle_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 | */ | ||
1125 | static 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 | */ | ||
1161 | void | ||
1162 | GML_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 | */ | ||
1174 | void | ||
1175 | GML_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 | */ | ||
1193 | void | ||
1194 | GML_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 | */ | ||
1220 | struct CadetChannel * | ||
1221 | GML_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 | */ | ||
1251 | void | ||
1252 | GML_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 | */ | ||
1276 | void | ||
1277 | GML_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 | */ | ||
1299 | struct GNUNET_CADET_ClientChannelNumber | ||
1300 | GML_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 | */ | ||
1331 | struct CadetClient * | ||
1332 | GML_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 | */ | ||
1348 | struct CadetClient * | ||
1349 | GML_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 | */ | ||
1362 | void | ||
1363 | GML_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 | */ | ||
1395 | void | ||
1396 | GML_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 | */ | ||
1429 | void | ||
1430 | GML_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 | */ | ||
1455 | void | ||
1456 | GML_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 | */ | ||
1482 | void | ||
1483 | GML_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 | */ | ||
1510 | void | ||
1511 | GML_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 (©[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 | ©->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 | */ | ||
1546 | const char * | ||
1547 | GML_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 | ||
33 | extern "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 | */ | ||
46 | struct 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 | */ | ||
59 | void | ||
60 | GML_init (struct GNUNET_SERVER_Handle *handle); | ||
61 | |||
62 | /** | ||
63 | * Install server (service) handlers and start listening to clients. | ||
64 | */ | ||
65 | void | ||
66 | GML_start (void); | ||
67 | |||
68 | /** | ||
69 | * Shutdown server. | ||
70 | */ | ||
71 | void | ||
72 | GML_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 | */ | ||
82 | struct CadetChannel * | ||
83 | GML_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 | */ | ||
93 | void | ||
94 | GML_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 | */ | ||
105 | void | ||
106 | GML_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 | */ | ||
117 | struct GNUNET_CADET_ClientChannelNumber | ||
118 | GML_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 | */ | ||
127 | struct CadetClient * | ||
128 | GML_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 | */ | ||
137 | struct CadetClient * | ||
138 | GML_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 | */ | ||
147 | void | ||
148 | GML_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 | */ | ||
160 | void | ||
161 | GML_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 | */ | ||
173 | void | ||
174 | GML_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 | */ | ||
186 | void | ||
187 | GML_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 | */ | ||
197 | void | ||
198 | GML_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 | */ | ||
209 | void | ||
210 | GML_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 | */ | ||
221 | const char * | ||
222 | GML_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_peer.c b/src/cadet/gnunet-service-cadet_peer.c deleted file mode 100644 index fa3f2be80..000000000 --- a/src/cadet/gnunet-service-cadet_peer.c +++ /dev/null | |||
@@ -1,2209 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2013, 2015 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_peer.c | ||
22 | * @brief GNUnet CADET service connection handling | ||
23 | * @author Bartlomiej Polot | ||
24 | */ | ||
25 | #include "platform.h" | ||
26 | #include "gnunet_util_lib.h" | ||
27 | #include "gnunet_signatures.h" | ||
28 | #include "gnunet_transport_service.h" | ||
29 | #include "gnunet_ats_service.h" | ||
30 | #include "gnunet_core_service.h" | ||
31 | #include "gnunet_statistics_service.h" | ||
32 | #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" | ||
36 | #include "gnunet-service-cadet_tunnel.h" | ||
37 | #include "cadet_path.h" | ||
38 | |||
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 | |||
42 | |||
43 | /******************************************************************************/ | ||
44 | /******************************** STRUCTS **********************************/ | ||
45 | /******************************************************************************/ | ||
46 | |||
47 | /** | ||
48 | * Information about a queued message on the peer level. | ||
49 | */ | ||
50 | struct CadetPeerQueue { | ||
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 | |||
122 | /** | ||
123 | * Struct containing all information regarding a given peer | ||
124 | */ | ||
125 | struct CadetPeer | ||
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 | |||
196 | }; | ||
197 | |||
198 | |||
199 | /******************************************************************************/ | ||
200 | /******************************* GLOBALS ***********************************/ | ||
201 | /******************************************************************************/ | ||
202 | |||
203 | /** | ||
204 | * Global handle to the statistics service. | ||
205 | */ | ||
206 | extern struct GNUNET_STATISTICS_Handle *stats; | ||
207 | |||
208 | /** | ||
209 | * Local peer own ID (full value). | ||
210 | */ | ||
211 | extern struct GNUNET_PeerIdentity my_full_id; | ||
212 | |||
213 | /** | ||
214 | * Local peer own ID (short) | ||
215 | */ | ||
216 | extern GNUNET_PEER_Id myid; | ||
217 | |||
218 | /** | ||
219 | * Peers known, indexed by PeerIdentity, values of type `struct CadetPeer`. | ||
220 | */ | ||
221 | static struct GNUNET_CONTAINER_MultiPeerMap *peers; | ||
222 | |||
223 | /** | ||
224 | * How many peers do we want to remember? | ||
225 | */ | ||
226 | static unsigned long long max_peers; | ||
227 | |||
228 | /** | ||
229 | * Percentage of messages that will be dropped (for test purposes only). | ||
230 | */ | ||
231 | static unsigned long long drop_percent; | ||
232 | |||
233 | /** | ||
234 | * Handle to communicate with CORE. | ||
235 | */ | ||
236 | static struct GNUNET_CORE_Handle *core_handle; | ||
237 | |||
238 | /** | ||
239 | * Our configuration; | ||
240 | */ | ||
241 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
242 | |||
243 | /** | ||
244 | * Handle to communicate with ATS. | ||
245 | */ | ||
246 | static struct GNUNET_ATS_ConnectivityHandle *ats_ch; | ||
247 | |||
248 | /** | ||
249 | * Shutdown falg. | ||
250 | */ | ||
251 | static int in_shutdown; | ||
252 | |||
253 | |||
254 | /******************************************************************************/ | ||
255 | /***************************** CORE HELPERS *********************************/ | ||
256 | /******************************************************************************/ | ||
257 | |||
258 | |||
259 | /** | ||
260 | * Iterator to notify all connections of a broken link. Mark connections | ||
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 | */ | ||
269 | static int | ||
270 | notify_broken (void *cls, | ||
271 | const struct GNUNET_ShortHashCode *key, | ||
272 | void *value) | ||
273 | { | ||
274 | struct CadetPeer *peer = cls; | ||
275 | struct CadetConnection *c = value; | ||
276 | |||
277 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
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 | |||
284 | |||
285 | /** | ||
286 | * Remove the direct path to the peer. | ||
287 | * | ||
288 | * @param peer Peer to remove the direct path from. | ||
289 | */ | ||
290 | static struct CadetPeerPath * | ||
291 | pop_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 | * | ||
313 | * @param q Queue handle. | ||
314 | * @param sent #GNUNET_YES if was sent to CORE, #GNUNET_NO if dropped. | ||
315 | */ | ||
316 | static void | ||
317 | call_peer_cont (struct CadetPeerQueue *q, int sent); | ||
318 | |||
319 | |||
320 | /******************************************************************************/ | ||
321 | /***************************** CORE CALLBACKS *********************************/ | ||
322 | /******************************************************************************/ | ||
323 | |||
324 | |||
325 | /** | ||
326 | * Method called whenever a given peer connects. | ||
327 | * | ||
328 | * @param cls Core closure (unused). | ||
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 | */ | ||
334 | static void * | ||
335 | core_connect_handler (void *cls, | ||
336 | const struct GNUNET_PeerIdentity *peer, | ||
337 | struct GNUNET_MQ_Handle *mq) | ||
338 | { | ||
339 | struct CadetPeer *neighbor; | ||
340 | struct CadetPeerPath *path; | ||
341 | char own_id[16]; | ||
342 | |||
343 | GCC_check_connections (); | ||
344 | GNUNET_snprintf (own_id, | ||
345 | sizeof (own_id), | ||
346 | "%s", | ||
347 | GNUNET_i2s (&my_full_id)); | ||
348 | |||
349 | /* Save a path to the neighbor */ | ||
350 | neighbor = GCP_get (peer, GNUNET_YES); | ||
351 | if (myid == neighbor->id) | ||
352 | { | ||
353 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
354 | "CONNECTED %s (self)\n", | ||
355 | own_id); | ||
356 | path = path_new (1); | ||
357 | } | ||
358 | else | ||
359 | { | ||
360 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
361 | "CONNECTED %s <= %s\n", | ||
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 | |||
390 | return neighbor; | ||
391 | } | ||
392 | |||
393 | |||
394 | /** | ||
395 | * Method called whenever a peer disconnects. | ||
396 | * | ||
397 | * @param cls Core closure (unused). | ||
398 | * @param peer Peer identity this notification is about. | ||
399 | * @param internal_cls Internal closure (CadetPeer struct). | ||
400 | */ | ||
401 | static void | ||
402 | core_disconnect_handler (void *cls, | ||
403 | const struct GNUNET_PeerIdentity *peer, | ||
404 | void *internal_cls) | ||
405 | { | ||
406 | struct CadetPeer *p = internal_cls; | ||
407 | struct CadetPeerPath *direct_path; | ||
408 | char own_id[16]; | ||
409 | |||
410 | GCC_check_connections (); | ||
411 | strncpy (own_id, GNUNET_i2s (&my_full_id), 16); | ||
412 | own_id[15] = '\0'; | ||
413 | if (myid == p->id) | ||
414 | { | ||
415 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
416 | "DISCONNECTED %s (self)\n", | ||
417 | own_id); | ||
418 | } | ||
419 | else | ||
420 | { | ||
421 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
422 | "DISCONNECTED %s <= %s\n", | ||
423 | own_id, GNUNET_i2s (peer)); | ||
424 | p->core_mq = NULL; | ||
425 | } | ||
426 | direct_path = pop_direct_path (p); | ||
427 | if (NULL != p->connections) | ||
428 | { | ||
429 | GNUNET_CONTAINER_multishortmap_iterate (p->connections, | ||
430 | ¬ify_broken, | ||
431 | p); | ||
432 | GNUNET_CONTAINER_multishortmap_destroy (p->connections); | ||
433 | p->connections = NULL; | ||
434 | } | ||
435 | GNUNET_STATISTICS_update (stats, | ||
436 | "# peers", | ||
437 | -1, | ||
438 | GNUNET_NO); | ||
439 | path_destroy (direct_path); | ||
440 | GCC_check_connections (); | ||
441 | } | ||
442 | |||
443 | |||
444 | /******************************************************************************/ | ||
445 | /******************************************************************************/ | ||
446 | /******************************************************************************/ | ||
447 | /******************************************************************************/ | ||
448 | /******************************************************************************/ | ||
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 | */ | ||
458 | static int | ||
459 | check_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 | { | ||
466 | GNUNET_break_op (0); | ||
467 | return GNUNET_NO; | ||
468 | } | ||
469 | return GNUNET_YES; | ||
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 | */ | ||
478 | static void | ||
479 | handle_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 | */ | ||
492 | static void | ||
493 | handle_confirm (void *cls, const struct GNUNET_CADET_ConnectionCreateAckMessage *msg) | ||
494 | { | ||
495 | struct CadetPeer *peer = cls; | ||
496 | GCC_handle_confirm (peer, msg); | ||
497 | } | ||
498 | |||
499 | |||
500 | /** | ||
501 | * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN | ||
502 | * | ||
503 | * @param cls Closure (CadetPeer for neighbor that sent the message). | ||
504 | * @param msg Message itself. | ||
505 | */ | ||
506 | static void | ||
507 | handle_broken (void *cls, const struct GNUNET_CADET_ConnectionBrokenMessage *msg) | ||
508 | { | ||
509 | struct CadetPeer *peer = cls; | ||
510 | GCC_handle_broken (peer, msg); | ||
511 | } | ||
512 | |||
513 | |||
514 | /** | ||
515 | * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY | ||
516 | * | ||
517 | * @param cls Closure (CadetPeer for neighbor that sent the message). | ||
518 | * @param msg Message itself. | ||
519 | */ | ||
520 | static void | ||
521 | handle_destroy (void *cls, const struct GNUNET_CADET_ConnectionDestroyMessage *msg) | ||
522 | { | ||
523 | struct CadetPeer *peer = cls; | ||
524 | GCC_handle_destroy (peer, msg); | ||
525 | } | ||
526 | |||
527 | |||
528 | /** | ||
529 | * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_HOP_BY_HOP_ENCRYPTED_ACK | ||
530 | * | ||
531 | * @param cls Closure (CadetPeer for neighbor that sent the message). | ||
532 | * @param msg Message itself. | ||
533 | */ | ||
534 | static void | ||
535 | handle_ack (void *cls, const struct GNUNET_CADET_ConnectionEncryptedAckMessage *msg) | ||
536 | { | ||
537 | struct CadetPeer *peer = cls; | ||
538 | GCC_handle_ack (peer, msg); | ||
539 | } | ||
540 | |||
541 | |||
542 | /** | ||
543 | * Handle for #GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED_POLL | ||
544 | * | ||
545 | * @param cls Closure (CadetPeer for neighbor that sent the message). | ||
546 | * @param msg Message itself. | ||
547 | */ | ||
548 | static void | ||
549 | handle_poll (void *cls, const struct GNUNET_CADET_ConnectionHopByHopPollMessage *msg) | ||
550 | { | ||
551 | struct CadetPeer *peer = cls; | ||
552 | GCC_handle_poll (peer, msg); | ||
553 | } | ||
554 | |||
555 | |||
556 | /** | ||
557 | * Handle for #GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX | ||
558 | * | ||
559 | * @param cls Closure (CadetPeer for neighbor that sent the message). | ||
560 | * @param msg Message itself. | ||
561 | */ | ||
562 | static void | ||
563 | handle_kx (void *cls, const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg) | ||
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 | */ | ||
578 | static int | ||
579 | check_encrypted (void *cls, const struct GNUNET_CADET_TunnelEncryptedMessage *msg) | ||
580 | { | ||
581 | uint16_t size; | ||
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 | |||
596 | /** | ||
597 | * Handle for #GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED. | ||
598 | * | ||
599 | * @param cls Closure (CadetPeer for neighbor that sent the message). | ||
600 | * @param msg Message itself. | ||
601 | */ | ||
602 | static void | ||
603 | handle_encrypted (void *cls, const struct GNUNET_CADET_TunnelEncryptedMessage *msg) | ||
604 | { | ||
605 | struct CadetPeer *peer = cls; | ||
606 | GCC_handle_encrypted (peer, msg); | ||
607 | } | ||
608 | |||
609 | |||
610 | /** | ||
611 | * To be called on core init/fail. | ||
612 | * | ||
613 | * @param cls Closure (config) | ||
614 | * @param identity The public identity of this peer. | ||
615 | */ | ||
616 | static void | ||
617 | core_init_notify (void *cls, | ||
618 | const struct GNUNET_PeerIdentity *identity); | ||
619 | |||
620 | |||
621 | static void | ||
622 | connect_to_core (const struct GNUNET_CONFIGURATION_Handle *c) | ||
623 | { | ||
624 | struct GNUNET_MQ_MessageHandler core_handlers[] = { | ||
625 | GNUNET_MQ_hd_var_size (create, | ||
626 | GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE, | ||
627 | struct GNUNET_CADET_ConnectionCreateMessage, | ||
628 | NULL), | ||
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 | */ | ||
678 | static void | ||
679 | core_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 | } | ||
696 | |||
697 | |||
698 | /******************************************************************************/ | ||
699 | /******************************** STATIC ***********************************/ | ||
700 | /******************************************************************************/ | ||
701 | |||
702 | |||
703 | /** | ||
704 | * Get priority for a queued message. | ||
705 | * | ||
706 | * @param q Queued message | ||
707 | * | ||
708 | * @return CORE priority to use. | ||
709 | * | ||
710 | * FIXME make static | ||
711 | * FIXME use when sending | ||
712 | */ | ||
713 | enum GNUNET_CORE_Priority | ||
714 | get_priority (struct CadetPeerQueue *q) | ||
715 | { | ||
716 | enum GNUNET_CORE_Priority low; | ||
717 | enum GNUNET_CORE_Priority high; | ||
718 | |||
719 | if (NULL == q) | ||
720 | { | ||
721 | GNUNET_break (0); | ||
722 | return GNUNET_CORE_PRIO_BACKGROUND; | ||
723 | } | ||
724 | |||
725 | /* Relayed traffic has lower priority, our own traffic has higher */ | ||
726 | if (NULL == q->c || GNUNET_NO == GCC_is_origin (q->c, q->c_fwd)) | ||
727 | { | ||
728 | low = GNUNET_CORE_PRIO_BEST_EFFORT; | ||
729 | high = GNUNET_CORE_PRIO_URGENT; | ||
730 | } | ||
731 | else | ||
732 | { | ||
733 | low = GNUNET_CORE_PRIO_URGENT; | ||
734 | high = GNUNET_CORE_PRIO_CRITICAL_CONTROL; | ||
735 | } | ||
736 | |||
737 | /* Bulky payload has lower priority, control traffic has higher. */ | ||
738 | if (GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED == q->type) | ||
739 | return low; | ||
740 | return high; | ||
741 | } | ||
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 | */ | ||
749 | static void | ||
750 | cancel_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 | */ | ||
769 | static int | ||
770 | peer_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 | |||
820 | GNUNET_free_non_null (peer->hello); | ||
821 | GNUNET_free (peer); | ||
822 | return GNUNET_OK; | ||
823 | } | ||
824 | |||
825 | |||
826 | /** | ||
827 | * Iterator over peer hash map entries to destroy the peer during in_shutdown. | ||
828 | * | ||
829 | * @param cls closure | ||
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 | */ | ||
835 | static int | ||
836 | shutdown_peer (void *cls, | ||
837 | const struct GNUNET_PeerIdentity *key, | ||
838 | void *value) | ||
839 | { | ||
840 | struct CadetPeer *p = value; | ||
841 | struct CadetTunnel *t = p->tunnel; | ||
842 | |||
843 | LOG (GNUNET_ERROR_TYPE_DEBUG, " shutting down %s\n", GCP_2s (p)); | ||
844 | if (NULL != t) | ||
845 | GCT_destroy (t); | ||
846 | p->tunnel = NULL; | ||
847 | peer_destroy (p); | ||
848 | return GNUNET_YES; | ||
849 | } | ||
850 | |||
851 | |||
852 | /** | ||
853 | * Check if peer is searching for a path (either active or delayed search). | ||
854 | * | ||
855 | * @param peer Peer to check | ||
856 | * @return #GNUNET_YES if there is a search active. | ||
857 | * #GNUNET_NO otherwise. | ||
858 | */ | ||
859 | static int | ||
860 | is_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 | * | ||
871 | * @param cls Closure (Peer to search for). | ||
872 | */ | ||
873 | static void | ||
874 | delayed_search (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 | |||
884 | |||
885 | /** | ||
886 | * Returns if peer is used (has a tunnel or is neighbor). | ||
887 | * | ||
888 | * @param peer Peer to check. | ||
889 | * @return #GNUNET_YES if peer is in use. | ||
890 | */ | ||
891 | static int | ||
892 | peer_is_used (struct CadetPeer *peer) | ||
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 | */ | ||
915 | static int | ||
916 | peer_get_oldest (void *cls, | ||
917 | const struct GNUNET_PeerIdentity *key, | ||
918 | void *value) | ||
919 | { | ||
920 | struct CadetPeer *p = value; | ||
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 | |||
927 | if (abs->abs_value_us < p->last_contact.abs_value_us) | ||
928 | abs->abs_value_us = p->last_contact.abs_value_us; | ||
929 | |||
930 | return GNUNET_YES; | ||
931 | } | ||
932 | |||
933 | |||
934 | /** | ||
935 | * Iterator over all the peers to remove the oldest entry. | ||
936 | * | ||
937 | * @param cls Closure (unsued). | ||
938 | * @param key ID of the peer. | ||
939 | * @param value Peer_Info of the peer. | ||
940 | */ | ||
941 | static int | ||
942 | peer_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 | */ | ||
965 | static void | ||
966 | peer_delete_oldest (void) | ||
967 | { | ||
968 | struct GNUNET_TIME_Absolute abs; | ||
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 | |||
981 | /** | ||
982 | * Choose the best (yet unused) path towards a peer, | ||
983 | * considering the tunnel properties. | ||
984 | * | ||
985 | * @param peer The destination peer. | ||
986 | * @return Best current known path towards the peer, if any. | ||
987 | */ | ||
988 | static struct CadetPeerPath * | ||
989 | peer_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 | } | ||
1013 | |||
1014 | |||
1015 | /** | ||
1016 | * Function to process paths received for a new peer addition. The recorded | ||
1017 | * paths form the initial tunnel, which can be optimized later. | ||
1018 | * Called on each result obtained for the DHT search. | ||
1019 | * | ||
1020 | * @param cls Closure (peer towards a path has been found). | ||
1021 | * @param path Path created from the DHT query. Will be freed afterwards. | ||
1022 | */ | ||
1023 | static void | ||
1024 | search_handler (void *cls, const struct CadetPeerPath *path) | ||
1025 | { | ||
1026 | struct CadetPeer *peer = 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 | |||
1035 | /* If we already have our minimum (or more) connections, it's enough */ | ||
1036 | if (CONNECTIONS_PER_TUNNEL <= connection_count) | ||
1037 | { | ||
1038 | GCC_check_connections (); | ||
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 | */ | ||
1059 | static int | ||
1060 | is_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 | } | ||
1065 | |||
1066 | |||
1067 | /** | ||
1068 | * Debug function should NEVER return true in production code, useful to | ||
1069 | * simulate losses for testcases. | ||
1070 | * | ||
1071 | * @return #GNUNET_YES or #GNUNET_NO with the decision to drop. | ||
1072 | */ | ||
1073 | static int | ||
1074 | should_I_drop (void) | ||
1075 | { | ||
1076 | if (0 == drop_percent) | ||
1077 | return GNUNET_NO; | ||
1078 | |||
1079 | if (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 101) < drop_percent) | ||
1080 | return GNUNET_YES; | ||
1081 | |||
1082 | return GNUNET_NO; | ||
1083 | } | ||
1084 | |||
1085 | |||
1086 | /******************************************************************************/ | ||
1087 | /******************************** API ***********************************/ | ||
1088 | /******************************************************************************/ | ||
1089 | |||
1090 | /** | ||
1091 | * Call the continuation after a message has been sent or dropped. | ||
1092 | * | ||
1093 | * This funcion removes the message from the queue. | ||
1094 | * | ||
1095 | * @param q Queue handle. | ||
1096 | * @param sent #GNUNET_YES if was sent to CORE, #GNUNET_NO if dropped. | ||
1097 | */ | ||
1098 | static void | ||
1099 | call_peer_cont (struct CadetPeerQueue *q, int sent) | ||
1100 | { | ||
1101 | LOG (GNUNET_ERROR_TYPE_DEBUG, " core mq just sent %s\n", GC_m2s (q->type)); | ||
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 | */ | ||
1128 | static void | ||
1129 | mq_sent (void *cls) | ||
1130 | { | ||
1131 | struct CadetPeerQueue *q = cls; | ||
1132 | |||
1133 | if (GNUNET_NO == q->management_traffic) | ||
1134 | { | ||
1135 | q->peer->queue_n--; | ||
1136 | } | ||
1137 | call_peer_cont (q, GNUNET_YES); | ||
1138 | GNUNET_free (q); | ||
1139 | } | ||
1140 | |||
1141 | |||
1142 | /** | ||
1143 | * Finish the drop operation. | ||
1144 | * | ||
1145 | * @param cls queue entry to finish drop for | ||
1146 | */ | ||
1147 | static void | ||
1148 | drop_cb (void *cls) | ||
1149 | { | ||
1150 | struct CadetPeerQueue *q = cls; | ||
1151 | |||
1152 | GNUNET_MQ_discard (q->env); | ||
1153 | call_peer_cont (q, GNUNET_YES); | ||
1154 | GNUNET_free (q); | ||
1155 | } | ||
1156 | |||
1157 | |||
1158 | /** | ||
1159 | * @brief Send a message to another peer (using CORE). | ||
1160 | * | ||
1161 | * @param peer Peer towards which to queue the message. | ||
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 | */ | ||
1174 | struct CadetPeerQueue * | ||
1175 | GCP_send (struct CadetPeer *peer, | ||
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 | { | ||
1184 | struct CadetPeerQueue *q; | ||
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 | |||
1207 | q = GNUNET_new (struct CadetPeerQueue); | ||
1208 | q->env = GNUNET_MQ_msg_copy (message); | ||
1209 | q->peer = peer; | ||
1210 | q->cont = cont; | ||
1211 | q->cont_cls = cont_cls; | ||
1212 | q->queue_timestamp = GNUNET_TIME_absolute_get (); | ||
1213 | q->management_traffic = is_connection_management (type); | ||
1214 | q->type = type; | ||
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 | } | ||
1249 | |||
1250 | |||
1251 | /** | ||
1252 | * Cancel sending a message. Message must have been sent with | ||
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 | * | ||
1258 | * @param q Queue handle to cancel | ||
1259 | */ | ||
1260 | void | ||
1261 | GCP_send_cancel (struct CadetPeerQueue *q) | ||
1262 | { | ||
1263 | if (NULL != q->drop_task) | ||
1264 | { | ||
1265 | GNUNET_SCHEDULER_cancel (q->drop_task); | ||
1266 | q->drop_task = NULL; | ||
1267 | GNUNET_MQ_discard (q->env); | ||
1268 | } | ||
1269 | else | ||
1270 | { | ||
1271 | GNUNET_MQ_send_cancel (q->env); | ||
1272 | } | ||
1273 | call_peer_cont (q, GNUNET_NO); | ||
1274 | GNUNET_free (q); | ||
1275 | } | ||
1276 | |||
1277 | |||
1278 | /** | ||
1279 | * Initialize the peer subsystem. | ||
1280 | * | ||
1281 | * @param c Configuration. | ||
1282 | */ | ||
1283 | void | ||
1284 | GCP_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 | */ | ||
1327 | void | ||
1328 | GCP_shutdown (void) | ||
1329 | { | ||
1330 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1331 | "Shutting down peer subsystem\n"); | ||
1332 | in_shutdown = GNUNET_YES; | ||
1333 | if (NULL != core_handle) | ||
1334 | { | ||
1335 | GNUNET_CORE_disconnect (core_handle); | ||
1336 | core_handle = NULL; | ||
1337 | } | ||
1338 | GNUNET_PEER_change_rc (myid, -1); | ||
1339 | /* With MQ API, CORE calls the disconnect handler for every peer | ||
1340 | * after calling GNUNET_CORE_disconnect, shutdown must occur *after* that. | ||
1341 | */ | ||
1342 | GNUNET_CONTAINER_multipeermap_iterate (peers, | ||
1343 | &shutdown_peer, | ||
1344 | NULL); | ||
1345 | if (NULL != ats_ch) | ||
1346 | { | ||
1347 | GNUNET_ATS_connectivity_done (ats_ch); | ||
1348 | ats_ch = NULL; | ||
1349 | } | ||
1350 | GNUNET_CONTAINER_multipeermap_destroy (peers); | ||
1351 | peers = NULL; | ||
1352 | } | ||
1353 | |||
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 | */ | ||
1366 | struct CadetPeer * | ||
1367 | GCP_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 | */ | ||
1404 | struct CadetPeer * | ||
1405 | GCP_get_short (const GNUNET_PEER_Id peer, int create) | ||
1406 | { | ||
1407 | return GCP_get (GNUNET_PEER_resolve2 (peer), create); | ||
1408 | } | ||
1409 | |||
1410 | |||
1411 | /** | ||
1412 | * Function called once #GNUNET_TRANSPORT_offer_hello() is done. | ||
1413 | * Marks the operation as finished. | ||
1414 | * | ||
1415 | * @param cls Closure (our `struct CadetPeer`). | ||
1416 | */ | ||
1417 | static void | ||
1418 | hello_offer_done (void *cls) | ||
1419 | { | ||
1420 | struct CadetPeer *peer = cls; | ||
1421 | |||
1422 | peer->hello_offer = NULL; | ||
1423 | } | ||
1424 | |||
1425 | |||
1426 | /** | ||
1427 | * Try to establish a new connection to this peer (in its tunnel). | ||
1428 | * If the peer doesn't have any path to it yet, try to get one. | ||
1429 | * If the peer already has some path, send a CREATE CONNECTION towards it. | ||
1430 | * | ||
1431 | * @param peer Peer to connect to. | ||
1432 | */ | ||
1433 | void | ||
1434 | GCP_connect (struct CadetPeer *peer) | ||
1435 | { | ||
1436 | struct CadetTunnel *t; | ||
1437 | struct CadetPeerPath *path; | ||
1438 | struct CadetConnection *c; | ||
1439 | int rerun_search; | ||
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 | |||
1448 | t = peer->tunnel; | ||
1449 | c = NULL; | ||
1450 | rerun_search = GNUNET_NO; | ||
1451 | |||
1452 | if (NULL != peer->path_head) | ||
1453 | { | ||
1454 | LOG (GNUNET_ERROR_TYPE_DEBUG, " some path exists\n"); | ||
1455 | path = peer_get_best_path (peer); | ||
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 | } | ||
1495 | |||
1496 | if (GNUNET_YES == rerun_search) | ||
1497 | { | ||
1498 | struct GNUNET_TIME_Relative delay; | ||
1499 | |||
1500 | GCP_stop_search (peer); | ||
1501 | delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 100); | ||
1502 | peer->search_delayed = GNUNET_SCHEDULER_add_delayed (delay, | ||
1503 | &delayed_search, | ||
1504 | peer); | ||
1505 | GCC_check_connections (); | ||
1506 | return; | ||
1507 | } | ||
1508 | |||
1509 | if (GNUNET_NO == is_searching (peer)) | ||
1510 | GCP_start_search (peer); | ||
1511 | GCC_check_connections (); | ||
1512 | } | ||
1513 | |||
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 | */ | ||
1522 | int | ||
1523 | GCP_is_neighbor (const struct CadetPeer *peer) | ||
1524 | { | ||
1525 | struct CadetPeerPath *path; | ||
1526 | |||
1527 | if (NULL == peer->connections) | ||
1528 | return GNUNET_NO; | ||
1529 | |||
1530 | for (path = peer->path_head; NULL != path; path = path->next) | ||
1531 | { | ||
1532 | if (3 > path->length) | ||
1533 | return GNUNET_YES; | ||
1534 | } | ||
1535 | |||
1536 | /* Is not a neighbor but connections is not NULL, probably disconnecting */ | ||
1537 | return GNUNET_NO; | ||
1538 | } | ||
1539 | |||
1540 | |||
1541 | /** | ||
1542 | * Create and initialize a new tunnel towards a peer, in case it has none. | ||
1543 | * In case the peer already has a tunnel, nothing is done. | ||
1544 | * | ||
1545 | * Does not generate any traffic, just creates the local data structures. | ||
1546 | * | ||
1547 | * @param peer Peer towards which to create the tunnel. | ||
1548 | */ | ||
1549 | void | ||
1550 | GCP_add_tunnel (struct CadetPeer *peer) | ||
1551 | { | ||
1552 | GCC_check_connections (); | ||
1553 | if (NULL != peer->tunnel) | ||
1554 | return; | ||
1555 | peer->tunnel = GCT_new (peer); | ||
1556 | GCC_check_connections (); | ||
1557 | } | ||
1558 | |||
1559 | |||
1560 | /** | ||
1561 | * Add a connection to a neighboring peer. | ||
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 | * | ||
1567 | * @param peer Peer to add connection to. | ||
1568 | * @param c Connection to add. | ||
1569 | * @param pred #GNUNET_YES if we are predecessor, #GNUNET_NO if we are successor | ||
1570 | */ | ||
1571 | void | ||
1572 | GCP_add_connection (struct CadetPeer *peer, | ||
1573 | struct CadetConnection *c, | ||
1574 | int pred) | ||
1575 | { | ||
1576 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1577 | "adding connection %s\n", | ||
1578 | GCC_2s (c)); | ||
1579 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
1580 | "to peer %s\n", | ||
1581 | GCP_2s (peer)); | ||
1582 | GNUNET_assert (NULL != peer->connections); | ||
1583 | GNUNET_assert (GNUNET_OK == | ||
1584 | GNUNET_CONTAINER_multishortmap_put (peer->connections, | ||
1585 | &GCC_get_id (c)->connection_of_tunnel, | ||
1586 | c, | ||
1587 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
1588 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
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 | */ | ||
1607 | struct CadetPeerPath * | ||
1608 | GCP_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 | |||
1687 | finish: | ||
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 | } | ||
1697 | |||
1698 | |||
1699 | /** | ||
1700 | * Add the path to the origin peer and update the path used to reach it in case | ||
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 | * | ||
1710 | * @return path if path was taken, pointer to existing duplicate if exists | ||
1711 | * NULL on error. | ||
1712 | */ | ||
1713 | struct CadetPeerPath * | ||
1714 | GCP_add_path_to_origin (struct CadetPeer *peer, | ||
1715 | struct CadetPeerPath *path, | ||
1716 | int trusted) | ||
1717 | { | ||
1718 | if (NULL == path) | ||
1719 | return NULL; | ||
1720 | path_invert (path); | ||
1721 | return GCP_add_path (peer, path, trusted); | ||
1722 | } | ||
1723 | |||
1724 | |||
1725 | /** | ||
1726 | * Adds a path to the info of all the peers in the path | ||
1727 | * | ||
1728 | * @param p Path to process. | ||
1729 | * @param confirmed Whether we know if the path works or not. | ||
1730 | */ | ||
1731 | void | ||
1732 | GCP_add_path_to_all (const struct CadetPeerPath *p, int confirmed) | ||
1733 | { | ||
1734 | unsigned int i; | ||
1735 | |||
1736 | /* TODO: invert and add to origin */ | ||
1737 | /* TODO: replace all "GCP_add_path" with this, make the other one static */ | ||
1738 | GCC_check_connections (); | ||
1739 | for (i = 0; i < p->length && p->peers[i] != myid; i++) /* skip'em */ ; | ||
1740 | for (i++; i < p->length; i++) | ||
1741 | { | ||
1742 | struct CadetPeer *peer; | ||
1743 | struct CadetPeerPath *copy; | ||
1744 | |||
1745 | peer = GCP_get_short (p->peers[i], GNUNET_YES); | ||
1746 | copy = path_duplicate (p); | ||
1747 | copy->length = i + 1; | ||
1748 | GCP_add_path (peer, copy, 3 > p->length ? GNUNET_NO : confirmed); | ||
1749 | } | ||
1750 | GCC_check_connections (); | ||
1751 | } | ||
1752 | |||
1753 | |||
1754 | /** | ||
1755 | * Remove any path to the peer that has the exact same peers as the one given. | ||
1756 | * | ||
1757 | * @param peer Peer to remove the path from. | ||
1758 | * @param path Path to remove. Is always destroyed . | ||
1759 | */ | ||
1760 | void | ||
1761 | GCP_remove_path (struct CadetPeer *peer, | ||
1762 | struct CadetPeerPath *path) | ||
1763 | { | ||
1764 | struct CadetPeerPath *iter; | ||
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 | } | ||
1790 | |||
1791 | |||
1792 | /** | ||
1793 | * Check that we are aware of a connection from a neighboring peer. | ||
1794 | * | ||
1795 | * @param peer Peer to the connection is with | ||
1796 | * @param c Connection that should be in the map with this peer. | ||
1797 | */ | ||
1798 | void | ||
1799 | GCP_check_connection (const struct CadetPeer *peer, | ||
1800 | const struct CadetConnection *c) | ||
1801 | { | ||
1802 | GNUNET_assert (NULL != peer); | ||
1803 | GNUNET_assert (NULL != peer->connections); | ||
1804 | return; // ???? | ||
1805 | GNUNET_assert (GNUNET_YES == | ||
1806 | GNUNET_CONTAINER_multishortmap_contains_value (peer->connections, | ||
1807 | &GCC_get_id (c)->connection_of_tunnel, | ||
1808 | c)); | ||
1809 | } | ||
1810 | |||
1811 | |||
1812 | /** | ||
1813 | * Remove a connection from a neighboring peer. | ||
1814 | * | ||
1815 | * @param peer Peer to remove connection from. | ||
1816 | * @param c Connection to remove. | ||
1817 | */ | ||
1818 | void | ||
1819 | GCP_remove_connection (struct CadetPeer *peer, | ||
1820 | const struct CadetConnection *c) | ||
1821 | { | ||
1822 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
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 | } | ||
1840 | |||
1841 | |||
1842 | /** | ||
1843 | * Start the DHT search for new paths towards the peer: we don't have | ||
1844 | * enough good connections. | ||
1845 | * | ||
1846 | * @param peer Destination peer. | ||
1847 | */ | ||
1848 | void | ||
1849 | GCP_start_search (struct CadetPeer *peer) | ||
1850 | { | ||
1851 | const struct GNUNET_PeerIdentity *id; | ||
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 | |||
1882 | |||
1883 | /** | ||
1884 | * Stop the DHT search for new paths towards the peer: we already have | ||
1885 | * enough good connections. | ||
1886 | * | ||
1887 | * @param peer Destination peer. | ||
1888 | */ | ||
1889 | void | ||
1890 | GCP_stop_search (struct CadetPeer *peer) | ||
1891 | { | ||
1892 | GCC_check_connections (); | ||
1893 | if (NULL != peer->search_h) | ||
1894 | { | ||
1895 | GCD_search_stop (peer->search_h); | ||
1896 | peer->search_h = NULL; | ||
1897 | } | ||
1898 | if (NULL != peer->search_delayed) | ||
1899 | { | ||
1900 | GNUNET_SCHEDULER_cancel (peer->search_delayed); | ||
1901 | peer->search_delayed = NULL; | ||
1902 | } | ||
1903 | GCC_check_connections (); | ||
1904 | } | ||
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 | */ | ||
1914 | const struct GNUNET_PeerIdentity * | ||
1915 | GCP_get_id (const struct CadetPeer *peer) | ||
1916 | { | ||
1917 | return GNUNET_PEER_resolve2 (peer->id); | ||
1918 | } | ||
1919 | |||
1920 | |||
1921 | /** | ||
1922 | * Get the Short ID of a peer. | ||
1923 | * | ||
1924 | * @param peer Peer to get from. | ||
1925 | * | ||
1926 | * @return Short ID of peer. | ||
1927 | */ | ||
1928 | GNUNET_PEER_Id | ||
1929 | GCP_get_short_id (const struct CadetPeer *peer) | ||
1930 | { | ||
1931 | return peer->id; | ||
1932 | } | ||
1933 | |||
1934 | |||
1935 | /** | ||
1936 | * Set tunnel. | ||
1937 | * | ||
1938 | * If tunnel is NULL and there was a search active, stop it, as it's useless. | ||
1939 | * | ||
1940 | * @param peer Peer. | ||
1941 | * @param t Tunnel. | ||
1942 | */ | ||
1943 | void | ||
1944 | GCP_set_tunnel (struct CadetPeer *peer, struct CadetTunnel *t) | ||
1945 | { | ||
1946 | peer->tunnel = t; | ||
1947 | if (NULL == t && GNUNET_YES == is_searching (peer)) | ||
1948 | { | ||
1949 | GCP_stop_search (peer); | ||
1950 | } | ||
1951 | } | ||
1952 | |||
1953 | |||
1954 | /** | ||
1955 | * Get the tunnel towards a peer. | ||
1956 | * | ||
1957 | * @param peer Peer to get from. | ||
1958 | * | ||
1959 | * @return Tunnel towards peer. | ||
1960 | */ | ||
1961 | struct CadetTunnel * | ||
1962 | GCP_get_tunnel (const struct CadetPeer *peer) | ||
1963 | { | ||
1964 | if (NULL == peer) | ||
1965 | return NULL; | ||
1966 | return peer->tunnel; | ||
1967 | } | ||
1968 | |||
1969 | |||
1970 | /** | ||
1971 | * Set the hello message. | ||
1972 | * | ||
1973 | * @param peer Peer whose message to set. | ||
1974 | * @param hello Hello message. | ||
1975 | */ | ||
1976 | void | ||
1977 | GCP_set_hello (struct CadetPeer *peer, | ||
1978 | const struct GNUNET_HELLO_Message *hello) | ||
1979 | { | ||
1980 | struct GNUNET_HELLO_Message *old; | ||
1981 | size_t size; | ||
1982 | |||
1983 | GCC_check_connections (); | ||
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 | } | ||
2002 | |||
2003 | |||
2004 | /** | ||
2005 | * Get the hello message. | ||
2006 | * | ||
2007 | * @param peer Peer whose message to get. | ||
2008 | * | ||
2009 | * @return Hello message. | ||
2010 | */ | ||
2011 | struct GNUNET_HELLO_Message * | ||
2012 | GCP_get_hello (struct CadetPeer *peer) | ||
2013 | { | ||
2014 | struct GNUNET_TIME_Absolute expiration; | ||
2015 | struct GNUNET_TIME_Relative remaining; | ||
2016 | |||
2017 | if (NULL == peer->hello) | ||
2018 | return NULL; | ||
2019 | |||
2020 | expiration = GNUNET_HELLO_get_last_expiration (peer->hello); | ||
2021 | remaining = GNUNET_TIME_absolute_get_remaining (expiration); | ||
2022 | if (0 == remaining.rel_value_us) | ||
2023 | { | ||
2024 | LOG (GNUNET_ERROR_TYPE_DEBUG, " get - hello expired on %s\n", | ||
2025 | GNUNET_STRINGS_absolute_time_to_string (expiration)); | ||
2026 | GNUNET_free (peer->hello); | ||
2027 | peer->hello = NULL; | ||
2028 | } | ||
2029 | return peer->hello; | ||
2030 | } | ||
2031 | |||
2032 | |||
2033 | /** | ||
2034 | * Try to connect to a peer on TRANSPORT level. | ||
2035 | * | ||
2036 | * @param peer Peer to whom to connect. | ||
2037 | */ | ||
2038 | void | ||
2039 | GCP_try_connect (struct CadetPeer *peer) | ||
2040 | { | ||
2041 | struct GNUNET_HELLO_Message *hello; | ||
2042 | struct GNUNET_MessageHeader *mh; | ||
2043 | |||
2044 | if (GNUNET_YES != | ||
2045 | GNUNET_CONFIGURATION_get_value_yesno (cfg, | ||
2046 | "CADET", | ||
2047 | "DISABLE_TRY_CONNECT")) | ||
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 | } | ||
2073 | |||
2074 | |||
2075 | /** | ||
2076 | * Notify a peer that a link between two other peers is broken. If any path | ||
2077 | * used that link, eliminate it. | ||
2078 | * | ||
2079 | * @param peer Peer affected by the change. | ||
2080 | * @param peer1 Peer whose link is broken. | ||
2081 | * @param peer2 Peer whose link is broken. | ||
2082 | */ | ||
2083 | void | ||
2084 | GCP_notify_broken_link (struct CadetPeer *peer, | ||
2085 | const struct GNUNET_PeerIdentity *peer1, | ||
2086 | const struct GNUNET_PeerIdentity *peer2) | ||
2087 | { | ||
2088 | struct CadetPeerPath *iter; | ||
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 | } | ||
2125 | |||
2126 | |||
2127 | /** | ||
2128 | * Count the number of known paths toward the peer. | ||
2129 | * | ||
2130 | * @param peer Peer to get path info. | ||
2131 | * | ||
2132 | * @return Number of known paths. | ||
2133 | */ | ||
2134 | unsigned int | ||
2135 | GCP_count_paths (const struct CadetPeer *peer) | ||
2136 | { | ||
2137 | struct CadetPeerPath *iter; | ||
2138 | unsigned int i; | ||
2139 | |||
2140 | for (iter = peer->path_head, i = 0; NULL != iter; iter = iter->next) | ||
2141 | i++; | ||
2142 | |||
2143 | return i; | ||
2144 | } | ||
2145 | |||
2146 | |||
2147 | /** | ||
2148 | * Iterate over the paths to a peer. | ||
2149 | * | ||
2150 | * @param peer Peer to get path info. | ||
2151 | * @param callback Function to call for every path. | ||
2152 | * @param cls Closure for @a callback. | ||
2153 | * | ||
2154 | * @return Number of iterated paths. | ||
2155 | */ | ||
2156 | unsigned int | ||
2157 | GCP_iterate_paths (struct CadetPeer *peer, | ||
2158 | GCP_path_iterator callback, | ||
2159 | void *cls) | ||
2160 | { | ||
2161 | struct CadetPeerPath *iter; | ||
2162 | unsigned int i; | ||
2163 | |||
2164 | for (iter = peer->path_head, i = 0; NULL != iter; iter = iter->next) | ||
2165 | { | ||
2166 | i++; | ||
2167 | if (GNUNET_YES != callback (cls, peer, iter)) | ||
2168 | break; | ||
2169 | } | ||
2170 | |||
2171 | return i; | ||
2172 | } | ||
2173 | |||
2174 | |||
2175 | /** | ||
2176 | * Iterate all known peers. | ||
2177 | * | ||
2178 | * @param iter Iterator. | ||
2179 | * @param cls Closure for @c iter. | ||
2180 | */ | ||
2181 | void | ||
2182 | GCP_iterate_all (GNUNET_CONTAINER_PeerMapIterator iter, | ||
2183 | void *cls) | ||
2184 | { | ||
2185 | GCC_check_connections (); | ||
2186 | GNUNET_CONTAINER_multipeermap_iterate (peers, | ||
2187 | iter, | ||
2188 | cls); | ||
2189 | GCC_check_connections (); | ||
2190 | } | ||
2191 | |||
2192 | |||
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 | */ | ||
2200 | const char * | ||
2201 | GCP_2s (const struct CadetPeer *peer) | ||
2202 | { | ||
2203 | if (NULL == peer) | ||
2204 | return "(NULL)"; | ||
2205 | return GNUNET_i2s (GNUNET_PEER_resolve2 (peer->id)); | ||
2206 | } | ||
2207 | |||
2208 | |||
2209 | /* end of gnunet-service-cadet_peer.c */ | ||
diff --git a/src/cadet/gnunet-service-cadet_peer.h b/src/cadet/gnunet-service-cadet_peer.h deleted file mode 100644 index 1e206e10f..000000000 --- a/src/cadet/gnunet-service-cadet_peer.h +++ /dev/null | |||
@@ -1,483 +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_peer.h | ||
23 | * @brief cadet service; dealing with remote peers | ||
24 | * @author Bartlomiej Polot | ||
25 | * | ||
26 | * All functions in this file should use the prefix GMP (Gnunet Cadet Peer) | ||
27 | */ | ||
28 | |||
29 | #ifndef GNUNET_SERVICE_CADET_PEER_H | ||
30 | #define GNUNET_SERVICE_CADET_PEER_H | ||
31 | |||
32 | #ifdef __cplusplus | ||
33 | extern "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 | #include "cadet_path.h" | ||
43 | |||
44 | /** | ||
45 | * Struct containing all information regarding a given peer | ||
46 | */ | ||
47 | struct CadetPeer; | ||
48 | |||
49 | /** | ||
50 | * Handle to queued messages on a peer level. | ||
51 | */ | ||
52 | struct 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 | */ | ||
70 | typedef 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 | |||
81 | /** | ||
82 | * Peer path iterator. | ||
83 | * | ||
84 | * @param cls Closure. | ||
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 | */ | ||
90 | typedef 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 | * | ||
103 | * @param c Configuration. | ||
104 | */ | ||
105 | void | ||
106 | GCP_init (const struct GNUNET_CONFIGURATION_Handle *c); | ||
107 | |||
108 | /** | ||
109 | * Shut down the peer subsystem. | ||
110 | */ | ||
111 | void | ||
112 | GCP_shutdown (void); | ||
113 | |||
114 | |||
115 | /** | ||
116 | * Retrieve the CadetPeer stucture associated with the peer. Optionally create | ||
117 | * one and insert it in the appropriate structures if the peer is not known yet. | ||
118 | * | ||
119 | * @param peer_id Full identity of the peer. | ||
120 | * @param create #GNUNET_YES if a new peer should be created if unknown. | ||
121 | * #GNUNET_NO otherwise. | ||
122 | * | ||
123 | * @return Existing or newly created peer structure. | ||
124 | * NULL if unknown and not requested @a create | ||
125 | */ | ||
126 | struct CadetPeer * | ||
127 | GCP_get (const struct GNUNET_PeerIdentity *peer_id, int create); | ||
128 | |||
129 | |||
130 | /** | ||
131 | * Retrieve the CadetPeer stucture associated with the peer. Optionally create | ||
132 | * one and insert it in the appropriate structures if the peer is not known yet. | ||
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 | * | ||
138 | * @return Existing or newly created peer structure. | ||
139 | * NULL if unknown and not requested @a create | ||
140 | */ | ||
141 | struct CadetPeer * | ||
142 | GCP_get_short (const GNUNET_PEER_Id peer, int create); | ||
143 | |||
144 | |||
145 | /** | ||
146 | * Try to establish a new connection to this peer (in its tunnel). | ||
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 | */ | ||
152 | void | ||
153 | GCP_connect (struct CadetPeer *peer); | ||
154 | |||
155 | /** | ||
156 | * @brief Send a message to another peer (using CORE). | ||
157 | * | ||
158 | * @param peer Peer towards which to queue the message. | ||
159 | * @param message Message to send. | ||
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 | */ | ||
169 | struct CadetPeerQueue * | ||
170 | GCP_send (struct CadetPeer *peer, | ||
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 | |||
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 | */ | ||
188 | void | ||
189 | GCP_send_cancel (struct CadetPeerQueue *q); | ||
190 | |||
191 | /** | ||
192 | * Set tunnel. | ||
193 | * | ||
194 | * @param peer Peer. | ||
195 | * @param t Tunnel. | ||
196 | */ | ||
197 | void | ||
198 | GCP_set_tunnel (struct CadetPeer *peer, struct CadetTunnel *t); | ||
199 | |||
200 | |||
201 | /** | ||
202 | * Check whether there is a direct (core level) connection to peer. | ||
203 | * | ||
204 | * @param peer Peer to check. | ||
205 | * | ||
206 | * @return #GNUNET_YES if there is a direct connection. | ||
207 | */ | ||
208 | int | ||
209 | GCP_is_neighbor (const struct CadetPeer *peer); | ||
210 | |||
211 | |||
212 | /** | ||
213 | * Create and initialize a new tunnel towards a peer, in case it has none. | ||
214 | * | ||
215 | * Does not generate any traffic, just creates the local data structures. | ||
216 | * | ||
217 | * @param peer Peer towards which to create the tunnel. | ||
218 | */ | ||
219 | void | ||
220 | GCP_add_tunnel (struct CadetPeer *peer); | ||
221 | |||
222 | |||
223 | /** | ||
224 | * Add a connection to a neighboring peer. | ||
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 | * | ||
230 | * @param peer Peer to add connection to. | ||
231 | * @param c Connection to add. | ||
232 | * @param pred #GNUNET_YES if we are predecessor, #GNUNET_NO if we are successor | ||
233 | */ | ||
234 | void | ||
235 | GCP_add_connection (struct CadetPeer *peer, | ||
236 | struct CadetConnection *c, | ||
237 | int pred); | ||
238 | |||
239 | |||
240 | /** | ||
241 | * Add the path to the peer and update the path used to reach it in case this | ||
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 | * | ||
249 | * @return path if path was taken, pointer to existing duplicate if exists | ||
250 | * NULL on error. | ||
251 | */ | ||
252 | struct CadetPeerPath * | ||
253 | GCP_add_path (struct CadetPeer *peer, | ||
254 | struct CadetPeerPath *p, | ||
255 | int trusted); | ||
256 | |||
257 | |||
258 | /** | ||
259 | * Add the path to the origin peer and update the path used to reach it in case | ||
260 | * this is the shortest. | ||
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 | * | ||
269 | * @return path if path was taken, pointer to existing duplicate if exists | ||
270 | * NULL on error. | ||
271 | */ | ||
272 | struct CadetPeerPath * | ||
273 | GCP_add_path_to_origin (struct CadetPeer *peer, | ||
274 | struct CadetPeerPath *path, | ||
275 | int trusted); | ||
276 | |||
277 | /** | ||
278 | * Adds a path to the info of all the peers in the path | ||
279 | * | ||
280 | * @param p Path to process. | ||
281 | * @param confirmed Whether we know if the path works or not. | ||
282 | */ | ||
283 | void | ||
284 | GCP_add_path_to_all (const struct CadetPeerPath *p, int confirmed); | ||
285 | |||
286 | |||
287 | /** | ||
288 | * Remove any path to the peer that has the extact same peers as the one given. | ||
289 | * | ||
290 | * @param peer Peer to remove the path from. | ||
291 | * @param path Path to remove. Is always destroyed . | ||
292 | */ | ||
293 | void | ||
294 | GCP_remove_path (struct CadetPeer *peer, | ||
295 | struct CadetPeerPath *path); | ||
296 | |||
297 | |||
298 | /** | ||
299 | * Check that we are aware of a connection from a neighboring peer. | ||
300 | * | ||
301 | * @param peer Peer to the connection is with | ||
302 | * @param c Connection that should be in the map with this peer. | ||
303 | */ | ||
304 | void | ||
305 | GCP_check_connection (const struct CadetPeer *peer, | ||
306 | const struct CadetConnection *c); | ||
307 | |||
308 | |||
309 | /** | ||
310 | * Remove a connection from a neighboring peer. | ||
311 | * | ||
312 | * @param peer Peer to remove connection from. | ||
313 | * @param c Connection to remove. | ||
314 | */ | ||
315 | void | ||
316 | GCP_remove_connection (struct CadetPeer *peer, | ||
317 | const struct CadetConnection *c); | ||
318 | |||
319 | |||
320 | /** | ||
321 | * Start the DHT search for new paths towards the peer: we don't have | ||
322 | * enough good connections. | ||
323 | * | ||
324 | * @param peer Destination peer. | ||
325 | */ | ||
326 | void | ||
327 | GCP_start_search (struct CadetPeer *peer); | ||
328 | |||
329 | |||
330 | /** | ||
331 | * Stop the DHT search for new paths towards the peer: we already have | ||
332 | * enough good connections. | ||
333 | * | ||
334 | * @param peer Destination peer. | ||
335 | */ | ||
336 | void | ||
337 | GCP_stop_search (struct CadetPeer *peer); | ||
338 | |||
339 | |||
340 | /** | ||
341 | * Get the Full ID of a peer. | ||
342 | * | ||
343 | * @param peer Peer to get from. | ||
344 | * | ||
345 | * @return Full ID of peer. | ||
346 | */ | ||
347 | const struct GNUNET_PeerIdentity * | ||
348 | GCP_get_id (const struct CadetPeer *peer); | ||
349 | |||
350 | |||
351 | /** | ||
352 | * Get the Short ID of a peer. | ||
353 | * | ||
354 | * @param peer Peer to get from. | ||
355 | * | ||
356 | * @return Short ID of peer. | ||
357 | */ | ||
358 | GNUNET_PEER_Id | ||
359 | GCP_get_short_id (const struct CadetPeer *peer); | ||
360 | |||
361 | |||
362 | /** | ||
363 | * Get the tunnel towards a peer. | ||
364 | * | ||
365 | * @param peer Peer to get from. | ||
366 | * | ||
367 | * @return Tunnel towards peer. | ||
368 | */ | ||
369 | struct CadetTunnel * | ||
370 | GCP_get_tunnel (const struct CadetPeer *peer); | ||
371 | |||
372 | |||
373 | /** | ||
374 | * Set the hello message. | ||
375 | * | ||
376 | * @param peer Peer whose message to set. | ||
377 | * @param hello Hello message. | ||
378 | */ | ||
379 | void | ||
380 | GCP_set_hello (struct CadetPeer *peer, | ||
381 | const struct GNUNET_HELLO_Message *hello); | ||
382 | |||
383 | |||
384 | /** | ||
385 | * Get the hello message. | ||
386 | * | ||
387 | * @param peer Peer whose message to get. | ||
388 | * | ||
389 | * @return Hello message. | ||
390 | */ | ||
391 | struct GNUNET_HELLO_Message * | ||
392 | GCP_get_hello (struct CadetPeer *peer); | ||
393 | |||
394 | |||
395 | /** | ||
396 | * Try to connect to a peer on TRANSPORT level. | ||
397 | * | ||
398 | * @param peer Peer to whom to connect. | ||
399 | */ | ||
400 | void | ||
401 | GCP_try_connect (struct CadetPeer *peer); | ||
402 | |||
403 | /** | ||
404 | * Notify a peer that a link between two other peers is broken. If any path | ||
405 | * used that link, eliminate it. | ||
406 | * | ||
407 | * @param peer Peer affected by the change. | ||
408 | * @param peer1 Peer whose link is broken. | ||
409 | * @param peer2 Peer whose link is broken. | ||
410 | */ | ||
411 | void | ||
412 | GCP_notify_broken_link (struct CadetPeer *peer, | ||
413 | const struct GNUNET_PeerIdentity *peer1, | ||
414 | const struct GNUNET_PeerIdentity *peer2); | ||
415 | |||
416 | |||
417 | /** | ||
418 | * Count the number of known paths toward the peer. | ||
419 | * | ||
420 | * @param peer Peer to get path info. | ||
421 | * | ||
422 | * @return Number of known paths. | ||
423 | */ | ||
424 | unsigned int | ||
425 | GCP_count_paths (const struct CadetPeer *peer); | ||
426 | |||
427 | /** | ||
428 | * Iterate over the paths to a peer. | ||
429 | * | ||
430 | * @param peer Peer to get path info. | ||
431 | * @param callback Function to call for every path. | ||
432 | * @param cls Closure for @a callback. | ||
433 | * | ||
434 | * @return Number of iterated paths. | ||
435 | */ | ||
436 | unsigned int | ||
437 | GCP_iterate_paths (struct CadetPeer *peer, | ||
438 | GCP_path_iterator callback, | ||
439 | void *cls); | ||
440 | |||
441 | |||
442 | /** | ||
443 | * Iterate all known peers. | ||
444 | * | ||
445 | * @param iter Iterator. | ||
446 | * @param cls Closure for @c iter. | ||
447 | */ | ||
448 | void | ||
449 | GCP_iterate_all (GNUNET_CONTAINER_PeerMapIterator iter, | ||
450 | void *cls); | ||
451 | |||
452 | |||
453 | /** | ||
454 | * Get the static string for a peer ID. | ||
455 | * | ||
456 | * @param peer Peer. | ||
457 | * | ||
458 | * @return Static string for it's ID. | ||
459 | */ | ||
460 | const char * | ||
461 | GCP_2s (const struct CadetPeer *peer); | ||
462 | |||
463 | |||
464 | /** | ||
465 | * Log all kinds of info about a peer. | ||
466 | * | ||
467 | * @param peer Peer. | ||
468 | */ | ||
469 | void | ||
470 | GCP_debug (const struct CadetPeer *p, | ||
471 | enum GNUNET_ErrorType level); | ||
472 | |||
473 | |||
474 | #if 0 /* keep Emacsens' auto-indent happy */ | ||
475 | { | ||
476 | #endif | ||
477 | #ifdef __cplusplus | ||
478 | } | ||
479 | #endif | ||
480 | |||
481 | /* ifndef GNUNET_CADET_SERVICE_PEER_H */ | ||
482 | #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 a94e8f4ff..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 | |||
58 | struct 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 | */ | ||
69 | struct 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 | */ | ||
101 | struct 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 | */ | ||
138 | struct 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 | */ | ||
251 | struct 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 | */ | ||
347 | struct 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 | */ | ||
375 | struct 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 | */ | ||
406 | extern struct GNUNET_STATISTICS_Handle *stats; | ||
407 | |||
408 | /** | ||
409 | * Local peer own ID (memory efficient handle). | ||
410 | */ | ||
411 | extern GNUNET_PEER_Id myid; | ||
412 | |||
413 | /** | ||
414 | * Local peer own ID (full value). | ||
415 | */ | ||
416 | extern struct GNUNET_PeerIdentity my_full_id; | ||
417 | |||
418 | |||
419 | /** | ||
420 | * Don't try to recover tunnels if shutting down. | ||
421 | */ | ||
422 | extern 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 | */ | ||
429 | static struct GNUNET_CONTAINER_MultiPeerMap *tunnels; | ||
430 | |||
431 | /** | ||
432 | * Own Peer ID private key. | ||
433 | */ | ||
434 | const 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 | */ | ||
442 | static unsigned long long ratchet_messages; | ||
443 | |||
444 | /** | ||
445 | * How long until we trigger a ratched advance. | ||
446 | */ | ||
447 | static 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 | */ | ||
461 | static const char * | ||
462 | cstate2s (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 | */ | ||
493 | static const char * | ||
494 | estate2s (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_AX_SENT: | ||
503 | return "CADET_TUNNEL_KEY_AX_SENT"; | ||
504 | case CADET_TUNNEL_KEY_AX_AUTH_SENT: | ||
505 | return "CADET_TUNNEL_KEY_AX_AUTH_SENT"; | ||
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 | */ | ||
527 | static int | ||
528 | is_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_AX_AUTH_SENT == 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 | */ | ||
551 | static unsigned int | ||
552 | get_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 | */ | ||
570 | static int | ||
571 | get_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 | */ | ||
589 | static unsigned int | ||
590 | get_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 | */ | ||
608 | static unsigned int | ||
609 | get_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 | */ | ||
625 | static void | ||
626 | new_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 | */ | ||
650 | static void | ||
651 | t_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 | */ | ||
682 | static void | ||
683 | t_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 | */ | ||
705 | static void | ||
706 | t_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 | */ | ||
729 | static int | ||
730 | t_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 | */ | ||
806 | static int | ||
807 | t_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 | */ | ||
846 | static void | ||
847 | t_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 | */ | ||
877 | static void | ||
878 | t_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 | */ | ||
915 | static int | ||
916 | try_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 | */ | ||
997 | static void | ||
998 | store_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 | */ | ||
1027 | static void | ||
1028 | delete_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 | */ | ||
1048 | static int | ||
1049 | store_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 | */ | ||
1094 | static int | ||
1095 | t_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 | */ | ||
1188 | static struct CadetConnection * | ||
1189 | tunnel_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 | */ | ||
1231 | static void | ||
1232 | tun_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 | |||
1249 | static unsigned int | ||
1250 | count_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 | */ | ||
1267 | static void | ||
1268 | unqueue_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 | */ | ||
1281 | static struct CadetTunnelDelayed * | ||
1282 | queue_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 | */ | ||
1316 | static struct CadetTunnelQueue * | ||
1317 | send_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 | */ | ||
1430 | static void | ||
1431 | send_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 | */ | ||
1476 | static void | ||
1477 | kx_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_AX_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 | */ | ||
1502 | static void | ||
1503 | ephm_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 | */ | ||
1537 | static int | ||
1538 | destroy_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 | */ | ||
1558 | static void | ||
1559 | send_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 | */ | ||
1586 | static void | ||
1587 | handle_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 | */ | ||
1640 | static void | ||
1641 | handle_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 | */ | ||
1677 | static void | ||
1678 | handle_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 | */ | ||
1712 | static void | ||
1713 | handle_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 | */ | ||
1753 | static void | ||
1754 | handle_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 | */ | ||
1797 | static void | ||
1798 | handle_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 | */ | ||
1830 | static void | ||
1831 | destroy_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 | */ | ||
1869 | static void | ||
1870 | handle_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 | */ | ||
1936 | void | ||
1937 | GCT_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_AX_AUTH_SENT <= 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 | */ | ||
1995 | void | ||
1996 | GCT_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_AX_AUTH_SENT); | ||
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 | */ | ||
2141 | void | ||
2142 | GCT_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 | */ | ||
2187 | void | ||
2188 | GCT_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 | */ | ||
2201 | struct CadetTunnel * | ||
2202 | GCT_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 | */ | ||
2231 | void | ||
2232 | GCT_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 | */ | ||
2277 | void | ||
2278 | GCT_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 | */ | ||
2315 | static void | ||
2316 | trim_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 | */ | ||
2356 | void | ||
2357 | GCT_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 | */ | ||
2389 | void | ||
2390 | GCT_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 | */ | ||
2448 | void | ||
2449 | GCT_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 | */ | ||
2488 | void | ||
2489 | GCT_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 | */ | ||
2517 | struct CadetChannel * | ||
2518 | GCT_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 | */ | ||
2545 | static void | ||
2546 | delayed_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 | */ | ||
2571 | void | ||
2572 | GCT_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 | */ | ||
2607 | void | ||
2608 | GCT_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 | */ | ||
2629 | void | ||
2630 | GCT_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 | */ | ||
2732 | struct CadetConnection * | ||
2733 | GCT_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 | */ | ||
2781 | unsigned int | ||
2782 | GCT_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 | */ | ||
2804 | unsigned int | ||
2805 | GCT_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 | */ | ||
2828 | unsigned int | ||
2829 | GCT_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 | */ | ||
2849 | enum CadetTunnelCState | ||
2850 | GCT_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 | */ | ||
2868 | enum CadetTunnelEState | ||
2869 | GCT_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 | */ | ||
2886 | unsigned int | ||
2887 | GCT_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 | */ | ||
2926 | unsigned int | ||
2927 | GCT_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 | */ | ||
2961 | const struct GNUNET_PeerIdentity * | ||
2962 | GCT_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 | */ | ||
2975 | struct GNUNET_CADET_ChannelTunnelNumber | ||
2976 | GCT_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 | */ | ||
3014 | void | ||
3015 | GCT_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 | */ | ||
3068 | void | ||
3069 | GCT_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 | */ | ||
3142 | void | ||
3143 | GCT_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 | */ | ||
3174 | int | ||
3175 | GCT_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 | */ | ||
3194 | struct CadetTunnelQueue * | ||
3195 | GCT_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 | */ | ||
3210 | void | ||
3211 | GCT_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_AX_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 | */ | ||
3265 | int | ||
3266 | GCT_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 | */ | ||
3280 | int | ||
3281 | GCT_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 | */ | ||
3301 | unsigned int | ||
3302 | GCT_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 | */ | ||
3346 | const char * | ||
3347 | GCT_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 | |||
3360 | static void | ||
3361 | ax_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 | */ | ||
3408 | void | ||
3409 | GCT_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 | */ | ||
3451 | void | ||
3452 | GCT_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 | */ | ||
3463 | unsigned int | ||
3464 | GCT_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 | */ | ||
3477 | void | ||
3478 | GCT_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 | */ | ||
3494 | void | ||
3495 | GCT_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 1b56a0632..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 | ||
33 | extern "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 | */ | ||
48 | enum 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 | */ | ||
80 | enum 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_AX_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_AX_AUTH_SENT, | ||
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 | */ | ||
125 | struct 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 | */ | ||
135 | struct 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 | */ | ||
145 | typedef void | ||
146 | (*GCT_sent) (void *cls, | ||
147 | struct CadetTunnel *t, | ||
148 | struct CadetTunnelQueue *q, | ||
149 | uint16_t type, size_t size); | ||
150 | |||
151 | typedef void | ||
152 | (*GCT_conn_iter) (void *cls, struct CadetConnection *c); | ||
153 | |||
154 | |||
155 | typedef 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 | */ | ||
169 | void | ||
170 | GCT_init (const struct GNUNET_CONFIGURATION_Handle *c, | ||
171 | const struct GNUNET_CRYPTO_EddsaPrivateKey *key); | ||
172 | |||
173 | |||
174 | /** | ||
175 | * Shut down the tunnel subsystem. | ||
176 | */ | ||
177 | void | ||
178 | GCT_shutdown (void); | ||
179 | |||
180 | |||
181 | /** | ||
182 | * Create a tunnel. | ||
183 | * | ||
184 | * @param destination Peer this tunnel is towards. | ||
185 | */ | ||
186 | struct CadetTunnel * | ||
187 | GCT_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 | */ | ||
197 | void | ||
198 | GCT_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 | */ | ||
206 | void | ||
207 | GCT_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 | */ | ||
221 | void | ||
222 | GCT_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 | */ | ||
231 | void | ||
232 | GCT_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 | */ | ||
241 | void | ||
242 | GCT_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 | */ | ||
251 | void | ||
252 | GCT_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 | */ | ||
261 | void | ||
262 | GCT_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 | */ | ||
271 | void | ||
272 | GCT_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 | */ | ||
281 | void | ||
282 | GCT_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 | */ | ||
293 | struct CadetChannel * | ||
294 | GCT_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 | */ | ||
305 | void | ||
306 | GCT_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 | */ | ||
316 | void | ||
317 | GCT_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 | */ | ||
331 | struct CadetConnection * | ||
332 | GCT_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 | */ | ||
342 | unsigned int | ||
343 | GCT_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 | */ | ||
353 | unsigned int | ||
354 | GCT_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 | */ | ||
364 | unsigned int | ||
365 | GCT_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 | */ | ||
375 | enum CadetTunnelCState | ||
376 | GCT_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 | */ | ||
386 | enum CadetTunnelEState | ||
387 | GCT_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 | */ | ||
397 | unsigned int | ||
398 | GCT_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 | */ | ||
408 | unsigned int | ||
409 | GCT_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 | */ | ||
419 | const struct GNUNET_PeerIdentity * | ||
420 | GCT_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 | */ | ||
430 | struct GNUNET_CADET_ChannelTunnelNumber | ||
431 | GCT_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 | */ | ||
439 | void | ||
440 | GCT_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 | */ | ||
450 | void | ||
451 | GCT_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 | */ | ||
463 | void | ||
464 | GCT_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 | */ | ||
475 | int | ||
476 | GCT_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 | */ | ||
491 | struct CadetTunnelQueue * | ||
492 | GCT_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 | */ | ||
503 | void | ||
504 | GCT_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 | */ | ||
514 | int | ||
515 | GCT_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 | */ | ||
526 | int | ||
527 | GCT_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 | */ | ||
538 | unsigned int | ||
539 | GCT_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 | */ | ||
550 | const char * | ||
551 | GCT_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 | */ | ||
560 | void | ||
561 | GCT_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 | */ | ||
570 | void | ||
571 | GCT_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 | */ | ||
579 | unsigned int | ||
580 | GCT_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 | */ | ||
590 | void | ||
591 | GCT_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 | */ | ||
601 | void | ||
602 | GCT_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 */ | ||