diff options
author | Christian Grothoff <christian@grothoff.org> | 2014-04-11 11:49:51 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2014-04-11 11:49:51 +0000 |
commit | 24712c94e185b72c30da25ea1b3a1784bde0defa (patch) | |
tree | 1ca399a023e0cdf48dbf9b411bb4b245081a1100 /src | |
parent | a61a4e0ffd7d563f3ae4d758f06a894edee71f58 (diff) | |
download | gnunet-24712c94e185b72c30da25ea1b3a1784bde0defa.tar.gz gnunet-24712c94e185b72c30da25ea1b3a1784bde0defa.zip |
towards fixing #3363: replacing old iteration API with new monitoring API for core (needs testing, gnunet-core incomplete)
Diffstat (limited to 'src')
-rw-r--r-- | src/core/core.h | 41 | ||||
-rw-r--r-- | src/core/core_api_iterate_peers.c | 242 | ||||
-rw-r--r-- | src/core/gnunet-core.c | 186 | ||||
-rw-r--r-- | src/core/gnunet-service-core.c | 15 | ||||
-rw-r--r-- | src/core/gnunet-service-core_clients.c | 12 | ||||
-rw-r--r-- | src/core/gnunet-service-core_kx.c | 268 | ||||
-rw-r--r-- | src/core/gnunet-service-core_kx.h | 21 | ||||
-rw-r--r-- | src/core/gnunet-service-core_sessions.c | 53 | ||||
-rw-r--r-- | src/core/gnunet-service-core_sessions.h | 17 | ||||
-rw-r--r-- | src/include/gnunet_core_service.h | 137 | ||||
-rw-r--r-- | src/include/gnunet_protocols.h | 8 |
11 files changed, 578 insertions, 422 deletions
diff --git a/src/core/core.h b/src/core/core.h index 1c6e0bc72..fba9ad1f3 100644 --- a/src/core/core.h +++ b/src/core/core.h | |||
@@ -62,7 +62,7 @@ struct InitMessage | |||
62 | { | 62 | { |
63 | 63 | ||
64 | /** | 64 | /** |
65 | * Header with type GNUNET_MESSAGE_TYPE_CORE_INIT. | 65 | * Header with type #GNUNET_MESSAGE_TYPE_CORE_INIT. |
66 | */ | 66 | */ |
67 | struct GNUNET_MessageHeader header; | 67 | struct GNUNET_MessageHeader header; |
68 | 68 | ||
@@ -82,7 +82,7 @@ struct InitReplyMessage | |||
82 | { | 82 | { |
83 | 83 | ||
84 | /** | 84 | /** |
85 | * Header with type GNUNET_MESSAGE_TYPE_CORE_INIT_REPLY | 85 | * Header with type #GNUNET_MESSAGE_TYPE_CORE_INIT_REPLY |
86 | */ | 86 | */ |
87 | struct GNUNET_MessageHeader header; | 87 | struct GNUNET_MessageHeader header; |
88 | 88 | ||
@@ -106,7 +106,7 @@ struct InitReplyMessage | |||
106 | struct ConnectNotifyMessage | 106 | struct ConnectNotifyMessage |
107 | { | 107 | { |
108 | /** | 108 | /** |
109 | * Header with type GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT | 109 | * Header with type #GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT |
110 | */ | 110 | */ |
111 | struct GNUNET_MessageHeader header; | 111 | struct GNUNET_MessageHeader header; |
112 | 112 | ||
@@ -130,7 +130,7 @@ struct ConnectNotifyMessage | |||
130 | struct DisconnectNotifyMessage | 130 | struct DisconnectNotifyMessage |
131 | { | 131 | { |
132 | /** | 132 | /** |
133 | * Header with type GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT. | 133 | * Header with type #GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT. |
134 | */ | 134 | */ |
135 | struct GNUNET_MessageHeader header; | 135 | struct GNUNET_MessageHeader header; |
136 | 136 | ||
@@ -159,8 +159,8 @@ struct DisconnectNotifyMessage | |||
159 | struct NotifyTrafficMessage | 159 | struct NotifyTrafficMessage |
160 | { | 160 | { |
161 | /** | 161 | /** |
162 | * Header with type GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND | 162 | * Header with type #GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND |
163 | * or GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND. | 163 | * or #GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND. |
164 | */ | 164 | */ |
165 | struct GNUNET_MessageHeader header; | 165 | struct GNUNET_MessageHeader header; |
166 | 166 | ||
@@ -291,6 +291,35 @@ struct SendMessage | |||
291 | }; | 291 | }; |
292 | 292 | ||
293 | 293 | ||
294 | /** | ||
295 | * Message sent by the service to monitor clients to notify them | ||
296 | * about a peer changing status. | ||
297 | */ | ||
298 | struct MonitorNotifyMessage | ||
299 | { | ||
300 | /** | ||
301 | * Header with type #GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY | ||
302 | */ | ||
303 | struct GNUNET_MessageHeader header; | ||
304 | |||
305 | /** | ||
306 | * New peer state, an `enum GNUNET_CORE_KxState` in NBO. | ||
307 | */ | ||
308 | uint32_t state GNUNET_PACKED; | ||
309 | |||
310 | /** | ||
311 | * Identity of the peer. | ||
312 | */ | ||
313 | struct GNUNET_PeerIdentity peer; | ||
314 | |||
315 | /** | ||
316 | * How long will we stay in this state (if nothing else happens)? | ||
317 | */ | ||
318 | struct GNUNET_TIME_AbsoluteNBO timeout; | ||
319 | |||
320 | }; | ||
321 | |||
322 | |||
294 | GNUNET_NETWORK_STRUCT_END | 323 | GNUNET_NETWORK_STRUCT_END |
295 | #endif | 324 | #endif |
296 | /* end of core.h */ | 325 | /* end of core.h */ |
diff --git a/src/core/core_api_iterate_peers.c b/src/core/core_api_iterate_peers.c index 4889e638a..425d3579c 100644 --- a/src/core/core_api_iterate_peers.c +++ b/src/core/core_api_iterate_peers.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | (C) 2009, 2010 Christian Grothoff (and other contributing authors) | 3 | (C) 2009-2014 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -19,7 +19,7 @@ | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | /** | 21 | /** |
22 | * @file core/core_api_iterate_peers.c | 22 | * @file core/core_api_monitor_peers.c |
23 | * @brief implementation of the peer_iterate function | 23 | * @brief implementation of the peer_iterate function |
24 | * @author Christian Grothoff | 24 | * @author Christian Grothoff |
25 | * @author Nathan Evans | 25 | * @author Nathan Evans |
@@ -29,15 +29,23 @@ | |||
29 | #include "core.h" | 29 | #include "core.h" |
30 | 30 | ||
31 | 31 | ||
32 | struct GNUNET_CORE_RequestContext | 32 | /** |
33 | * Handle to a CORE monitoring operation. | ||
34 | */ | ||
35 | struct GNUNET_CORE_MonitorHandle | ||
33 | { | 36 | { |
37 | |||
38 | /** | ||
39 | * Our configuration. | ||
40 | */ | ||
41 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
42 | |||
34 | /** | 43 | /** |
35 | * Our connection to the service. | 44 | * Our connection to the service. |
36 | */ | 45 | */ |
37 | struct GNUNET_CLIENT_Connection *client; | 46 | struct GNUNET_CLIENT_Connection *client; |
38 | 47 | ||
39 | /** | 48 | /** |
40 | |||
41 | * Handle for transmitting a request. | 49 | * Handle for transmitting a request. |
42 | */ | 50 | */ |
43 | struct GNUNET_CLIENT_TransmitHandle *th; | 51 | struct GNUNET_CLIENT_TransmitHandle *th; |
@@ -45,140 +53,200 @@ struct GNUNET_CORE_RequestContext | |||
45 | /** | 53 | /** |
46 | * Function called with the peer. | 54 | * Function called with the peer. |
47 | */ | 55 | */ |
48 | GNUNET_CORE_ConnectEventHandler peer_cb; | 56 | GNUNET_CORE_MonitorCallback peer_cb; |
49 | 57 | ||
50 | /** | 58 | /** |
51 | * Peer to check for. | 59 | * Closure for @e peer_cb. |
52 | */ | 60 | */ |
53 | struct GNUNET_PeerIdentity *peer; | 61 | void *peer_cb_cls; |
54 | |||
55 | /** | ||
56 | * Closure for peer_cb. | ||
57 | */ | ||
58 | void *cb_cls; | ||
59 | 62 | ||
60 | }; | 63 | }; |
61 | 64 | ||
62 | 65 | ||
63 | /** | 66 | /** |
64 | * Receive reply from core service with information about a peer. | 67 | * Transmits the monitor request to the CORE service. |
68 | * | ||
69 | * Function is called to notify a client about the socket begin ready | ||
70 | * to queue more data. @a buf will be NULL and @a size zero if the | ||
71 | * socket was closed for writing in the meantime. | ||
72 | * | ||
73 | * @param cls closure, our `struct GNUNET_CORE_MonitorHandle *` | ||
74 | * @param size number of bytes available in @a buf | ||
75 | * @param buf where the callee should write the message | ||
76 | * @return number of bytes written to @a buf | ||
77 | */ | ||
78 | static size_t | ||
79 | transmit_monitor_request (void *cls, | ||
80 | size_t size, | ||
81 | void *buf); | ||
82 | |||
83 | |||
84 | /** | ||
85 | * Protocol error, reconnect to CORE service and notify | ||
86 | * client. | ||
87 | * | ||
88 | * @param mh monitoring session to reconnect to CORE | ||
89 | */ | ||
90 | static void | ||
91 | reconnect (struct GNUNET_CORE_MonitorHandle *mh) | ||
92 | { | ||
93 | GNUNET_CLIENT_disconnect (mh->client); | ||
94 | /* FIXME: use backoff? */ | ||
95 | mh->client = GNUNET_CLIENT_connect ("core", mh->cfg); | ||
96 | GNUNET_assert (NULL != mh->client); | ||
97 | mh->th = | ||
98 | GNUNET_CLIENT_notify_transmit_ready (mh->client, | ||
99 | sizeof (struct GNUNET_MessageHeader), | ||
100 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
101 | GNUNET_YES, | ||
102 | &transmit_monitor_request, mh); | ||
103 | /* notify callback about reconnect */ | ||
104 | mh->peer_cb (mh->peer_cb_cls, | ||
105 | NULL, | ||
106 | GNUNET_CORE_KX_CORE_DISCONNECT, | ||
107 | GNUNET_TIME_UNIT_FOREVER_ABS); | ||
108 | } | ||
109 | |||
110 | |||
111 | /** | ||
112 | * Receive reply from CORE service with information about a peer. | ||
65 | * | 113 | * |
66 | * @param cls our 'struct GNUNET_CORE_RequestContext *' | 114 | * @param cls our `struct GNUNET_CORE_MonitorHandle *` |
67 | * @param msg NULL on error or last entry | 115 | * @param msg NULL on error or last entry |
68 | */ | 116 | */ |
69 | static void | 117 | static void |
70 | receive_info (void *cls, const struct GNUNET_MessageHeader *msg) | 118 | receive_info (void *cls, |
119 | const struct GNUNET_MessageHeader *msg) | ||
71 | { | 120 | { |
72 | struct GNUNET_CORE_RequestContext *request_context = cls; | 121 | struct GNUNET_CORE_MonitorHandle *mh = cls; |
73 | const struct ConnectNotifyMessage *connect_message; | 122 | const struct MonitorNotifyMessage *mon_message; |
74 | uint16_t msize; | 123 | uint16_t msize; |
75 | 124 | ||
76 | /* Handle last message or error case, disconnect and clean up */ | 125 | if (NULL == msg) |
77 | if ((msg == NULL) || | ||
78 | ((ntohs (msg->type) == GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS_END) && | ||
79 | (ntohs (msg->size) == sizeof (struct GNUNET_MessageHeader)))) | ||
80 | { | 126 | { |
81 | if (request_context->peer_cb != NULL) | 127 | reconnect (mh); |
82 | request_context->peer_cb (request_context->cb_cls, NULL); | ||
83 | GNUNET_CLIENT_disconnect (request_context->client); | ||
84 | GNUNET_free (request_context); | ||
85 | return; | 128 | return; |
86 | } | 129 | } |
87 | |||
88 | msize = ntohs (msg->size); | 130 | msize = ntohs (msg->size); |
89 | /* Handle incorrect message type or size, disconnect and clean up */ | 131 | /* Handle incorrect message type or size, disconnect and clean up */ |
90 | if ((ntohs (msg->type) != GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT) || | 132 | if ((ntohs (msg->type) != GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY) || |
91 | (msize < sizeof (struct ConnectNotifyMessage))) | 133 | (sizeof (struct MonitorNotifyMessage) != msize)) |
92 | { | 134 | { |
93 | GNUNET_break (0); | 135 | GNUNET_break (0); |
94 | if (request_context->peer_cb != NULL) | 136 | reconnect (mh); |
95 | request_context->peer_cb (request_context->cb_cls, NULL); | ||
96 | GNUNET_CLIENT_disconnect (request_context->client); | ||
97 | GNUNET_free (request_context); | ||
98 | return; | 137 | return; |
99 | } | 138 | } |
100 | connect_message = (const struct ConnectNotifyMessage *) msg; | 139 | mon_message = (const struct MonitorNotifyMessage *) msg; |
101 | if (msize != sizeof (struct ConnectNotifyMessage)) | 140 | GNUNET_CLIENT_receive (mh->client, |
102 | { | 141 | &receive_info, mh, |
103 | GNUNET_break (0); | 142 | GNUNET_TIME_UNIT_FOREVER_REL); |
104 | if (request_context->peer_cb != NULL) | 143 | mh->peer_cb (mh->peer_cb_cls, |
105 | request_context->peer_cb (request_context->cb_cls, NULL); | 144 | &mon_message->peer, |
106 | GNUNET_CLIENT_disconnect (request_context->client); | 145 | (enum GNUNET_CORE_KxState) ntohl (mon_message->state), |
107 | GNUNET_free (request_context); | 146 | GNUNET_TIME_absolute_ntoh (mon_message->timeout)); |
108 | return; | ||
109 | } | ||
110 | /* Normal case */ | ||
111 | if (request_context->peer_cb != NULL) | ||
112 | request_context->peer_cb (request_context->cb_cls, &connect_message->peer); | ||
113 | GNUNET_CLIENT_receive (request_context->client, &receive_info, | ||
114 | request_context, GNUNET_TIME_UNIT_FOREVER_REL); | ||
115 | } | 147 | } |
116 | 148 | ||
117 | 149 | ||
118 | /** | 150 | /** |
119 | * Function called to notify a client about the socket | 151 | * Transmits the monitor request to the CORE service. |
120 | * begin ready to queue more data. "buf" will be | ||
121 | * NULL and "size" zero if the socket was closed for | ||
122 | * writing in the meantime. | ||
123 | * | 152 | * |
124 | * @param cls closure, always NULL | 153 | * Function is called to notify a client about the socket begin ready |
125 | * @param size number of bytes available in buf | 154 | * to queue more data. @a buf will be NULL and @a size zero if the |
155 | * socket was closed for writing in the meantime. | ||
156 | * | ||
157 | * @param cls closure, our `struct GNUNET_CORE_MonitorHandle *` | ||
158 | * @param size number of bytes available in @a buf | ||
126 | * @param buf where the callee should write the message | 159 | * @param buf where the callee should write the message |
127 | * @return number of bytes written to buf | 160 | * @return number of bytes written to @a buf |
128 | */ | 161 | */ |
129 | static size_t | 162 | static size_t |
130 | transmit_request (void *cls, size_t size, void *buf) | 163 | transmit_monitor_request (void *cls, |
164 | size_t size, | ||
165 | void *buf) | ||
131 | { | 166 | { |
167 | struct GNUNET_CORE_MonitorHandle *mh = cls; | ||
132 | struct GNUNET_MessageHeader *msg; | 168 | struct GNUNET_MessageHeader *msg; |
133 | int msize; | 169 | int msize; |
134 | 170 | ||
135 | msize = sizeof (struct GNUNET_MessageHeader); | 171 | msize = sizeof (struct GNUNET_MessageHeader); |
136 | if ((size < msize) || (buf == NULL)) | 172 | if ((size < msize) || (NULL == buf)) |
173 | { | ||
174 | reconnect (mh); | ||
137 | return 0; | 175 | return 0; |
176 | } | ||
138 | msg = (struct GNUNET_MessageHeader *) buf; | 177 | msg = (struct GNUNET_MessageHeader *) buf; |
139 | msg->size = htons (msize); | 178 | msg->size = htons (msize); |
140 | msg->type = htons (GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS); | 179 | msg->type = htons (GNUNET_MESSAGE_TYPE_CORE_MONITOR_PEERS); |
141 | 180 | GNUNET_CLIENT_receive (mh->client, | |
181 | &receive_info, mh, | ||
182 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
142 | return msize; | 183 | return msize; |
143 | } | 184 | } |
144 | 185 | ||
145 | 186 | ||
146 | /** | 187 | /** |
147 | * Iterate over all currently connected peers. | 188 | * Monitor connectivity and KX status of all peers known to CORE. |
148 | * Calls peer_cb with each connected peer, and then | 189 | * Calls @a peer_cb with the current status for each connected peer, |
149 | * once with NULL to indicate that all peers have | 190 | * and then once with NULL to indicate that all peers that are |
150 | * been handled. | 191 | * currently active have been handled. After that, the iteration |
192 | * continues until it is cancelled. Normal users of the CORE API are | ||
193 | * not expected to use this function. It is different in that it | ||
194 | * truly lists all connections (including those where the KX is in | ||
195 | * progress), not just those relevant to the application. This | ||
196 | * function is used by special applications for diagnostics. | ||
151 | * | 197 | * |
152 | * @param cfg configuration to use | 198 | * @param cfg configuration handle |
153 | * @param peer_cb function to call with the peer information | 199 | * @param peer_cb function to call with the peer information |
154 | * @param cb_cls closure for @a peer_cb | 200 | * @param peer_cb_cls closure for @a peer_cb |
155 | * @return #GNUNET_OK if iterating, #GNUNET_SYSERR on error | 201 | * @return NULL on error |
156 | */ | 202 | */ |
157 | int | 203 | struct GNUNET_CORE_MonitorHandle * |
158 | GNUNET_CORE_iterate_peers (const struct GNUNET_CONFIGURATION_Handle *cfg, | 204 | GNUNET_CORE_monitor_start (const struct GNUNET_CONFIGURATION_Handle *cfg, |
159 | GNUNET_CORE_ConnectEventHandler peer_cb, | 205 | GNUNET_CORE_MonitorCallback peer_cb, |
160 | void *cb_cls) | 206 | void *peer_cb_cls) |
161 | { | 207 | { |
162 | struct GNUNET_CORE_RequestContext *request_context; | 208 | struct GNUNET_CORE_MonitorHandle *mh; |
163 | struct GNUNET_CLIENT_Connection *client; | 209 | struct GNUNET_CLIENT_Connection *client; |
164 | 210 | ||
211 | GNUNET_assert (NULL != peer_cb); | ||
165 | client = GNUNET_CLIENT_connect ("core", cfg); | 212 | client = GNUNET_CLIENT_connect ("core", cfg); |
166 | if (client == NULL) | 213 | if (NULL == client) |
167 | return GNUNET_SYSERR; | 214 | return NULL; |
168 | request_context = GNUNET_new (struct GNUNET_CORE_RequestContext); | 215 | mh = GNUNET_new (struct GNUNET_CORE_MonitorHandle); |
169 | request_context->client = client; | 216 | mh->cfg = cfg; |
170 | request_context->peer_cb = peer_cb; | 217 | mh->client = client; |
171 | request_context->cb_cls = cb_cls; | 218 | mh->peer_cb = peer_cb; |
172 | 219 | mh->peer_cb_cls = peer_cb_cls; | |
173 | request_context->th = | 220 | mh->th = |
174 | GNUNET_CLIENT_notify_transmit_ready (client, | 221 | GNUNET_CLIENT_notify_transmit_ready (client, |
175 | sizeof (struct GNUNET_MessageHeader), | 222 | sizeof (struct GNUNET_MessageHeader), |
176 | GNUNET_TIME_UNIT_FOREVER_REL, | 223 | GNUNET_TIME_UNIT_FOREVER_REL, |
177 | GNUNET_YES, &transmit_request, NULL); | 224 | GNUNET_YES, |
178 | 225 | &transmit_monitor_request, mh); | |
179 | GNUNET_CLIENT_receive (client, &receive_info, request_context, | 226 | return mh; |
180 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
181 | return GNUNET_OK; | ||
182 | } | 227 | } |
183 | 228 | ||
184 | /* end of core_api_iterate_peers.c */ | 229 | |
230 | /** | ||
231 | * Stop monitoring CORE activity. | ||
232 | * | ||
233 | * @param mh monitor to stop | ||
234 | */ | ||
235 | void | ||
236 | GNUNET_CORE_monitor_stop (struct GNUNET_CORE_MonitorHandle *mh) | ||
237 | { | ||
238 | if (NULL != mh->th) | ||
239 | { | ||
240 | GNUNET_CLIENT_notify_transmit_ready_cancel (mh->th); | ||
241 | mh->th = NULL; | ||
242 | } | ||
243 | if (NULL != mh->client) | ||
244 | { | ||
245 | GNUNET_CLIENT_disconnect (mh->client); | ||
246 | mh->client = NULL; | ||
247 | } | ||
248 | GNUNET_free (mh); | ||
249 | } | ||
250 | |||
251 | |||
252 | /* end of core_api_monitor_peers.c */ | ||
diff --git a/src/core/gnunet-core.c b/src/core/gnunet-core.c index 6309b39e0..36dc5fc6f 100644 --- a/src/core/gnunet-core.c +++ b/src/core/gnunet-core.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | (C) 2011, 2012 Christian Grothoff (and other contributing authors) | 3 | (C) 2011, 2012, 2014 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -24,13 +24,9 @@ | |||
24 | * @author Nathan Evans | 24 | * @author Nathan Evans |
25 | */ | 25 | */ |
26 | #include "platform.h" | 26 | #include "platform.h" |
27 | #include "gnunet_crypto_lib.h" | 27 | #include "gnunet_util_lib.h" |
28 | #include "gnunet_configuration_lib.h" | ||
29 | #include "gnunet_getopt_lib.h" | ||
30 | #include "gnunet_peerinfo_service.h" | ||
31 | #include "gnunet_transport_service.h" | ||
32 | #include "gnunet_core_service.h" | 28 | #include "gnunet_core_service.h" |
33 | #include "gnunet_program_lib.h" | 29 | |
34 | 30 | ||
35 | /** | 31 | /** |
36 | * Option -m. | 32 | * Option -m. |
@@ -40,11 +36,13 @@ static int monitor_connections; | |||
40 | /** | 36 | /** |
41 | * Current number of connections in monitor mode | 37 | * Current number of connections in monitor mode |
42 | */ | 38 | */ |
43 | static int monitor_connections_counter; | 39 | // static unsigned int monitor_connections_counter; |
44 | 40 | ||
45 | static struct GNUNET_CORE_Handle *ch; | 41 | /** |
42 | * Handle to the CORE monitor. | ||
43 | */ | ||
44 | static struct GNUNET_CORE_MonitorHandle *mh; | ||
46 | 45 | ||
47 | static struct GNUNET_PeerIdentity my_id; | ||
48 | 46 | ||
49 | /** | 47 | /** |
50 | * Task run in monitor mode when the user presses CTRL-C to abort. | 48 | * Task run in monitor mode when the user presses CTRL-C to abort. |
@@ -57,143 +55,81 @@ static void | |||
57 | shutdown_task (void *cls, | 55 | shutdown_task (void *cls, |
58 | const struct GNUNET_SCHEDULER_TaskContext *tc) | 56 | const struct GNUNET_SCHEDULER_TaskContext *tc) |
59 | { | 57 | { |
60 | if (NULL != ch) | 58 | if (NULL != mh) |
61 | { | 59 | { |
62 | GNUNET_CORE_disconnect (ch); | 60 | GNUNET_CORE_monitor_stop (mh); |
63 | ch = NULL; | 61 | mh = NULL; |
64 | } | 62 | } |
65 | } | 63 | } |
66 | 64 | ||
67 | 65 | ||
68 | /** | 66 | /** |
69 | * Callback for retrieving a list of connected peers. | ||
70 | * | ||
71 | * @param cls closure (unused) | ||
72 | * @param peer peer identity this notification is about | ||
73 | */ | ||
74 | static void | ||
75 | connected_peer_callback (void *cls, | ||
76 | const struct GNUNET_PeerIdentity *peer) | ||
77 | { | ||
78 | if (NULL == peer) | ||
79 | return; | ||
80 | printf (_("Peer `%s'\n"), | ||
81 | GNUNET_i2s_full (peer)); | ||
82 | } | ||
83 | |||
84 | |||
85 | static void | ||
86 | monitor_notify_startup (void *cls, | ||
87 | const struct GNUNET_PeerIdentity *my_identity) | ||
88 | { | ||
89 | my_id = (*my_identity); | ||
90 | } | ||
91 | |||
92 | |||
93 | /** | ||
94 | * Function called to notify core users that another | 67 | * Function called to notify core users that another |
95 | * peer connected to us. | 68 | * peer changed its state with us. |
96 | * | 69 | * |
97 | * @param cls closure | 70 | * @param cls closure |
98 | * @param peer the peer that connected | 71 | * @param peer the peer that changed state |
72 | * @param state new state of the peer | ||
73 | * @param timeout timeout for the new state | ||
99 | */ | 74 | */ |
100 | static void | 75 | static void |
101 | monitor_notify_connect (void *cls, const struct GNUNET_PeerIdentity *peer) | 76 | monitor_cb (void *cls, |
77 | const struct GNUNET_PeerIdentity *peer, | ||
78 | enum GNUNET_CORE_KxState state, | ||
79 | struct GNUNET_TIME_Absolute timeout) | ||
102 | { | 80 | { |
103 | struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get(); | 81 | struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get(); |
104 | const char *now_str; | 82 | const char *now_str; |
105 | 83 | ||
106 | if (0 != memcmp (&my_id, peer, sizeof (my_id))) | 84 | if ( (NULL == peer) && |
85 | (GNUNET_NO == monitor_connections) ) | ||
107 | { | 86 | { |
108 | monitor_connections_counter ++; | 87 | GNUNET_SCHEDULER_shutdown (); |
109 | now_str = GNUNET_STRINGS_absolute_time_to_string (now); | 88 | return; |
110 | FPRINTF (stdout, _("%24s: %-17s %4s (%u connections in total)\n"), | ||
111 | now_str, | ||
112 | _("Connected to"), | ||
113 | GNUNET_i2s (peer), | ||
114 | monitor_connections_counter); | ||
115 | } | 89 | } |
90 | now_str = GNUNET_STRINGS_absolute_time_to_string (now); | ||
91 | FPRINTF (stdout, | ||
92 | _("%24s: %-17s %d %4s\n"), | ||
93 | now_str, | ||
94 | "FIXME", | ||
95 | state, | ||
96 | GNUNET_i2s (peer)); | ||
116 | } | 97 | } |
117 | 98 | ||
118 | 99 | ||
119 | /** | 100 | /** |
120 | * Function called to notify core users that another | 101 | * Function called with the result of the check if the CORE |
121 | * peer disconnected from us. | ||
122 | * | ||
123 | * @param cls closure | ||
124 | * @param peer the peer that disconnected | ||
125 | */ | ||
126 | static void | ||
127 | monitor_notify_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) | ||
128 | { | ||
129 | struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get(); | ||
130 | const char *now_str; | ||
131 | |||
132 | if (0 != memcmp (&my_id, peer, sizeof (my_id))) | ||
133 | { | ||
134 | now_str = GNUNET_STRINGS_absolute_time_to_string (now); | ||
135 | |||
136 | GNUNET_assert (monitor_connections_counter > 0); | ||
137 | monitor_connections_counter--; | ||
138 | FPRINTF (stdout, _("%24s: %-17s %4s (%u connections in total)\n"), | ||
139 | now_str, | ||
140 | _("Disconnected from"), | ||
141 | GNUNET_i2s (peer), | ||
142 | monitor_connections_counter); | ||
143 | } | ||
144 | } | ||
145 | |||
146 | /** | ||
147 | * Function called with the result of the check if the 'transport' | ||
148 | * service is running. | 102 | * service is running. |
149 | * | 103 | * |
150 | * @param cls closure with our configuration | 104 | * @param cls closure with our configuration |
151 | * @param result #GNUNET_YES if transport is running | 105 | * @param result #GNUNET_YES if CORE is running |
152 | */ | 106 | */ |
153 | static void | 107 | static void |
154 | testservice_task (void *cls, int result) | 108 | testservice_task (void *cls, |
109 | int result) | ||
155 | { | 110 | { |
156 | const struct GNUNET_CONFIGURATION_Handle *cfg = cls; | 111 | const struct GNUNET_CONFIGURATION_Handle *cfg = cls; |
157 | static const struct GNUNET_CORE_MessageHandler handlers[] = { | ||
158 | {NULL, 0, 0} | ||
159 | }; | ||
160 | |||
161 | if (result != GNUNET_OK) | ||
162 | { | ||
163 | FPRINTF (stderr, _("Service `%s' is not running\n"), "core"); | ||
164 | return; | ||
165 | } | ||
166 | 112 | ||
167 | if (GNUNET_NO == monitor_connections) | 113 | if (GNUNET_OK != result) |
168 | { | 114 | { |
169 | if (GNUNET_OK != GNUNET_CORE_iterate_peers (cfg, &connected_peer_callback, NULL)) | 115 | FPRINTF (stderr, _("Service `%s' is not running\n"), "core"); |
170 | { | 116 | return; |
171 | fprintf (stderr, ("Failed to connect to CORE service to iterate peers!\n")); | ||
172 | return; | ||
173 | } | ||
174 | } | 117 | } |
175 | else | 118 | |
119 | mh = GNUNET_CORE_monitor_start (cfg, | ||
120 | &monitor_cb, | ||
121 | NULL); | ||
122 | if (NULL == mh) | ||
176 | { | 123 | { |
177 | memset(&my_id, '\0', sizeof (my_id)); | 124 | GNUNET_SCHEDULER_add_now (shutdown_task, NULL); |
178 | ch = GNUNET_CORE_connect (cfg, NULL, | 125 | fprintf (stderr, ("Failed to connect to CORE service!\n")); |
179 | monitor_notify_startup, | 126 | return; |
180 | monitor_notify_connect, | ||
181 | monitor_notify_disconnect, | ||
182 | NULL, GNUNET_NO, | ||
183 | NULL, GNUNET_NO, | ||
184 | handlers); | ||
185 | |||
186 | if (NULL == ch) | ||
187 | { | ||
188 | GNUNET_SCHEDULER_add_now (shutdown_task, NULL); | ||
189 | fprintf (stderr, ("Failed to connect to CORE service!\n")); | ||
190 | return; | ||
191 | } | ||
192 | else | ||
193 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, shutdown_task, NULL); | ||
194 | } | 127 | } |
128 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, | ||
129 | &shutdown_task, NULL); | ||
195 | } | 130 | } |
196 | 131 | ||
132 | |||
197 | /** | 133 | /** |
198 | * Main function that will be run by the scheduler. | 134 | * Main function that will be run by the scheduler. |
199 | * | 135 | * |
@@ -206,19 +142,21 @@ static void | |||
206 | run (void *cls, char *const *args, const char *cfgfile, | 142 | run (void *cls, char *const *args, const char *cfgfile, |
207 | const struct GNUNET_CONFIGURATION_Handle *cfg) | 143 | const struct GNUNET_CONFIGURATION_Handle *cfg) |
208 | { | 144 | { |
209 | if (args[0] != NULL) | 145 | if (NULL != args[0]) |
210 | { | 146 | { |
211 | FPRINTF (stderr, _("Invalid command line argument `%s'\n"), args[0]); | 147 | FPRINTF (stderr, |
148 | _("Invalid command line argument `%s'\n"), | ||
149 | args[0]); | ||
212 | return; | 150 | return; |
213 | } | 151 | } |
214 | 152 | GNUNET_CLIENT_service_test ("core", cfg, | |
215 | GNUNET_CLIENT_service_test ("core", cfg, GNUNET_TIME_UNIT_SECONDS, | 153 | GNUNET_TIME_UNIT_SECONDS, |
216 | &testservice_task, (void *) cfg); | 154 | &testservice_task, (void *) cfg); |
217 | } | 155 | } |
218 | 156 | ||
219 | 157 | ||
220 | /** | 158 | /** |
221 | * The main function to obtain peer information. | 159 | * The main function to obtain peer information from CORE. |
222 | * | 160 | * |
223 | * @param argc number of arguments from the command line | 161 | * @param argc number of arguments from the command line |
224 | * @param argv command line arguments | 162 | * @param argv command line arguments |
@@ -237,19 +175,15 @@ main (int argc, char *const *argv) | |||
237 | 175 | ||
238 | if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) | 176 | if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) |
239 | return 2; | 177 | return 2; |
240 | |||
241 | |||
242 | res = GNUNET_PROGRAM_run (argc, argv, "gnunet-core", | 178 | res = GNUNET_PROGRAM_run (argc, argv, "gnunet-core", |
243 | gettext_noop | 179 | gettext_noop |
244 | ("Print information about connected peers."), | 180 | ("Print information about connected peers."), |
245 | options, &run, NULL); | 181 | options, &run, NULL); |
246 | 182 | ||
247 | GNUNET_free ((void *) argv); | 183 | GNUNET_free ((void *) argv); |
248 | |||
249 | if (GNUNET_OK == res) | 184 | if (GNUNET_OK == res) |
250 | return 0; | 185 | return 0; |
251 | else | 186 | return 1; |
252 | return 1; | ||
253 | } | 187 | } |
254 | 188 | ||
255 | /* end of gnunet-core.c */ | 189 | /* end of gnunet-core.c */ |
diff --git a/src/core/gnunet-service-core.c b/src/core/gnunet-service-core.c index c6eeb070b..05e461278 100644 --- a/src/core/gnunet-service-core.c +++ b/src/core/gnunet-service-core.c | |||
@@ -101,20 +101,21 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, | |||
101 | &keyfile)) | 101 | &keyfile)) |
102 | { | 102 | { |
103 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 103 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
104 | _ | 104 | _("Core service is lacking HOSTKEY configuration setting. Exiting.\n")); |
105 | ("Core service is lacking HOSTKEY configuration setting. Exiting.\n")); | ||
106 | GNUNET_SCHEDULER_shutdown (); | 105 | GNUNET_SCHEDULER_shutdown (); |
107 | return; | 106 | return; |
108 | } | 107 | } |
109 | GSC_stats = GNUNET_STATISTICS_create ("core", GSC_cfg); | 108 | GSC_stats = GNUNET_STATISTICS_create ("core", GSC_cfg); |
110 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, | 109 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, |
110 | &shutdown_task, | ||
111 | NULL); | 111 | NULL); |
112 | GNUNET_SERVER_suspend (server); | 112 | GNUNET_SERVER_suspend (server); |
113 | GSC_TYPEMAP_init (); | 113 | GSC_TYPEMAP_init (); |
114 | pk = GNUNET_CRYPTO_eddsa_key_create_from_file (keyfile); | 114 | pk = GNUNET_CRYPTO_eddsa_key_create_from_file (keyfile); |
115 | GNUNET_free (keyfile); | 115 | GNUNET_free (keyfile); |
116 | GNUNET_assert (NULL != pk); | 116 | GNUNET_assert (NULL != pk); |
117 | if ((GNUNET_OK != GSC_KX_init (pk)) || | 117 | if ((GNUNET_OK != GSC_KX_init (pk, |
118 | server)) || | ||
118 | (GNUNET_OK != GSC_NEIGHBOURS_init ())) | 119 | (GNUNET_OK != GSC_NEIGHBOURS_init ())) |
119 | { | 120 | { |
120 | GNUNET_SCHEDULER_shutdown (); | 121 | GNUNET_SCHEDULER_shutdown (); |
@@ -123,7 +124,8 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, | |||
123 | GSC_SESSIONS_init (); | 124 | GSC_SESSIONS_init (); |
124 | GSC_CLIENTS_init (GSC_server); | 125 | GSC_CLIENTS_init (GSC_server); |
125 | GNUNET_SERVER_resume (GSC_server); | 126 | GNUNET_SERVER_resume (GSC_server); |
126 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Core service of `%4s' ready.\n"), | 127 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
128 | _("Core service of `%4s' ready.\n"), | ||
127 | GNUNET_i2s (&GSC_my_identity)); | 129 | GNUNET_i2s (&GSC_my_identity)); |
128 | } | 130 | } |
129 | 131 | ||
@@ -139,7 +141,8 @@ int | |||
139 | main (int argc, char *const *argv) | 141 | main (int argc, char *const *argv) |
140 | { | 142 | { |
141 | return (GNUNET_OK == | 143 | return (GNUNET_OK == |
142 | GNUNET_SERVICE_run (argc, argv, "core", GNUNET_SERVICE_OPTION_NONE, | 144 | GNUNET_SERVICE_run (argc, argv, "core", |
145 | GNUNET_SERVICE_OPTION_NONE, | ||
143 | &run, NULL)) ? 0 : 1; | 146 | &run, NULL)) ? 0 : 1; |
144 | } | 147 | } |
145 | 148 | ||
diff --git a/src/core/gnunet-service-core_clients.c b/src/core/gnunet-service-core_clients.c index 5a30138a0..634959674 100644 --- a/src/core/gnunet-service-core_clients.c +++ b/src/core/gnunet-service-core_clients.c | |||
@@ -600,11 +600,12 @@ destroy_active_client_request (void *cls, | |||
600 | * @param client identification of the client | 600 | * @param client identification of the client |
601 | */ | 601 | */ |
602 | static void | 602 | static void |
603 | handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client) | 603 | handle_client_disconnect (void *cls, |
604 | struct GNUNET_SERVER_Client *client) | ||
604 | { | 605 | { |
605 | struct GSC_Client *c; | 606 | struct GSC_Client *c; |
606 | 607 | ||
607 | if (client == NULL) | 608 | if (NULL == client) |
608 | return; | 609 | return; |
609 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 610 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
610 | "Client %p has disconnected from core service.\n", client); | 611 | "Client %p has disconnected from core service.\n", client); |
@@ -840,8 +841,8 @@ GSC_CLIENTS_init (struct GNUNET_SERVER_Handle *server) | |||
840 | static const struct GNUNET_SERVER_MessageHandler handlers[] = { | 841 | static const struct GNUNET_SERVER_MessageHandler handlers[] = { |
841 | {&handle_client_init, NULL, | 842 | {&handle_client_init, NULL, |
842 | GNUNET_MESSAGE_TYPE_CORE_INIT, 0}, | 843 | GNUNET_MESSAGE_TYPE_CORE_INIT, 0}, |
843 | {&GSC_SESSIONS_handle_client_iterate_peers, NULL, | 844 | {&GSC_KX_handle_client_monitor_peers, NULL, |
844 | GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS, | 845 | GNUNET_MESSAGE_TYPE_CORE_MONITOR_PEERS, |
845 | sizeof (struct GNUNET_MessageHeader)}, | 846 | sizeof (struct GNUNET_MessageHeader)}, |
846 | {&handle_client_send_request, NULL, | 847 | {&handle_client_send_request, NULL, |
847 | GNUNET_MESSAGE_TYPE_CORE_SEND_REQUEST, | 848 | GNUNET_MESSAGE_TYPE_CORE_SEND_REQUEST, |
@@ -855,7 +856,8 @@ GSC_CLIENTS_init (struct GNUNET_SERVER_Handle *server) | |||
855 | client_mst = GNUNET_SERVER_mst_create (&client_tokenizer_callback, NULL); | 856 | client_mst = GNUNET_SERVER_mst_create (&client_tokenizer_callback, NULL); |
856 | notifier = | 857 | notifier = |
857 | GNUNET_SERVER_notification_context_create (server, MAX_NOTIFY_QUEUE); | 858 | GNUNET_SERVER_notification_context_create (server, MAX_NOTIFY_QUEUE); |
858 | GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL); | 859 | GNUNET_SERVER_disconnect_notify (server, |
860 | &handle_client_disconnect, NULL); | ||
859 | GNUNET_SERVER_add_handlers (server, handlers); | 861 | GNUNET_SERVER_add_handlers (server, handlers); |
860 | } | 862 | } |
861 | 863 | ||
diff --git a/src/core/gnunet-service-core_kx.c b/src/core/gnunet-service-core_kx.c index 4a516461f..4ab902fbe 100644 --- a/src/core/gnunet-service-core_kx.c +++ b/src/core/gnunet-service-core_kx.c | |||
@@ -237,50 +237,6 @@ GNUNET_NETWORK_STRUCT_END | |||
237 | 237 | ||
238 | 238 | ||
239 | /** | 239 | /** |
240 | * State machine for our P2P encryption handshake. Everyone starts in | ||
241 | * "DOWN", if we receive the other peer's key (other peer initiated) | ||
242 | * we start in state RECEIVED (since we will immediately send our | ||
243 | * own); otherwise we start in SENT. If we get back a PONG from | ||
244 | * within either state, we move up to CONFIRMED (the PONG will always | ||
245 | * be sent back encrypted with the key we sent to the other peer). | ||
246 | */ | ||
247 | enum KxStateMachine | ||
248 | { | ||
249 | /** | ||
250 | * No handshake yet. | ||
251 | */ | ||
252 | KX_STATE_DOWN, | ||
253 | |||
254 | /** | ||
255 | * We've sent our session key. | ||
256 | */ | ||
257 | KX_STATE_KEY_SENT, | ||
258 | |||
259 | /** | ||
260 | * We've received the other peers session key. | ||
261 | */ | ||
262 | KX_STATE_KEY_RECEIVED, | ||
263 | |||
264 | /** | ||
265 | * The other peer has confirmed our session key + PING with a PONG | ||
266 | * message encrypted with his session key (which we got). Key | ||
267 | * exchange is done. | ||
268 | */ | ||
269 | KX_STATE_UP, | ||
270 | |||
271 | /** | ||
272 | * We're rekeying (or had a timeout), so we have sent the other peer | ||
273 | * our new ephemeral key, but we did not get a matching PONG yet. | ||
274 | * This is equivalent to being 'KX_STATE_KEY_RECEIVED', except that | ||
275 | * the session is marked as 'up' with sessions (as we don't want to | ||
276 | * drop and re-establish P2P connections simply due to rekeying). | ||
277 | */ | ||
278 | KX_STATE_REKEY_SENT | ||
279 | |||
280 | }; | ||
281 | |||
282 | |||
283 | /** | ||
284 | * Information about the status of a key exchange with another peer. | 240 | * Information about the status of a key exchange with another peer. |
285 | */ | 241 | */ |
286 | struct GSC_KeyExchangeInfo | 242 | struct GSC_KeyExchangeInfo |
@@ -373,7 +329,7 @@ struct GSC_KeyExchangeInfo | |||
373 | /** | 329 | /** |
374 | * What is our connection status? | 330 | * What is our connection status? |
375 | */ | 331 | */ |
376 | enum KxStateMachine status; | 332 | enum GNUNET_CORE_KxState status; |
377 | 333 | ||
378 | }; | 334 | }; |
379 | 335 | ||
@@ -414,6 +370,57 @@ static struct GSC_KeyExchangeInfo *kx_tail; | |||
414 | */ | 370 | */ |
415 | static GNUNET_SCHEDULER_TaskIdentifier rekey_task; | 371 | static GNUNET_SCHEDULER_TaskIdentifier rekey_task; |
416 | 372 | ||
373 | /** | ||
374 | * Notification context for all monitors. | ||
375 | */ | ||
376 | static struct GNUNET_SERVER_NotificationContext *nc; | ||
377 | |||
378 | |||
379 | /** | ||
380 | * Inform the given monitor about the KX state of | ||
381 | * the given peer. | ||
382 | * | ||
383 | * @param mc monitor to inform | ||
384 | * @param kx key exchange state to inform about | ||
385 | */ | ||
386 | static void | ||
387 | monitor_notify (struct GNUNET_SERVER_Client *client, | ||
388 | struct GSC_KeyExchangeInfo *kx) | ||
389 | { | ||
390 | struct MonitorNotifyMessage msg; | ||
391 | |||
392 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY); | ||
393 | msg.header.size = htons (sizeof (msg)); | ||
394 | msg.state = htonl ((uint32_t) kx->status); | ||
395 | msg.peer = kx->peer; | ||
396 | msg.timeout = GNUNET_TIME_absolute_hton (kx->timeout); | ||
397 | GNUNET_SERVER_notification_context_unicast (nc, | ||
398 | client, | ||
399 | &msg.header, | ||
400 | GNUNET_NO); | ||
401 | } | ||
402 | |||
403 | |||
404 | /** | ||
405 | * Inform all monitors about the KX state of the given peer. | ||
406 | * | ||
407 | * @param kx key exchange state to inform about | ||
408 | */ | ||
409 | static void | ||
410 | monitor_notify_all (struct GSC_KeyExchangeInfo *kx) | ||
411 | { | ||
412 | struct MonitorNotifyMessage msg; | ||
413 | |||
414 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY); | ||
415 | msg.header.size = htons (sizeof (msg)); | ||
416 | msg.state = htonl ((uint32_t) kx->status); | ||
417 | msg.peer = kx->peer; | ||
418 | msg.timeout = GNUNET_TIME_absolute_hton (kx->timeout); | ||
419 | GNUNET_SERVER_notification_context_broadcast (nc, | ||
420 | &msg.header, | ||
421 | GNUNET_NO); | ||
422 | } | ||
423 | |||
417 | 424 | ||
418 | /** | 425 | /** |
419 | * Derive an authentication key from "set key" information | 426 | * Derive an authentication key from "set key" information |
@@ -570,8 +577,9 @@ do_decrypt (struct GSC_KeyExchangeInfo *kx, | |||
570 | GNUNET_break (0); | 577 | GNUNET_break (0); |
571 | return GNUNET_NO; | 578 | return GNUNET_NO; |
572 | } | 579 | } |
573 | if ( (kx->status != KX_STATE_KEY_RECEIVED) && (kx->status != KX_STATE_UP) && | 580 | if ( (kx->status != GNUNET_CORE_KX_STATE_KEY_RECEIVED) && |
574 | (kx->status != KX_STATE_REKEY_SENT) ) | 581 | (kx->status != GNUNET_CORE_KX_STATE_UP) && |
582 | (kx->status != GNUNET_CORE_KX_STATE_REKEY_SENT) ) | ||
575 | { | 583 | { |
576 | GNUNET_break_op (0); | 584 | GNUNET_break_op (0); |
577 | return GNUNET_SYSERR; | 585 | return GNUNET_SYSERR; |
@@ -622,7 +630,7 @@ set_key_retry_task (void *cls, | |||
622 | 630 | ||
623 | kx->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK; | 631 | kx->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK; |
624 | kx->set_key_retry_frequency = GNUNET_TIME_STD_BACKOFF (kx->set_key_retry_frequency); | 632 | kx->set_key_retry_frequency = GNUNET_TIME_STD_BACKOFF (kx->set_key_retry_frequency); |
625 | GNUNET_assert (KX_STATE_DOWN != kx->status); | 633 | GNUNET_assert (GNUNET_CORE_KX_STATE_DOWN != kx->status); |
626 | send_key (kx); | 634 | send_key (kx); |
627 | } | 635 | } |
628 | 636 | ||
@@ -678,10 +686,14 @@ GSC_KX_start (const struct GNUNET_PeerIdentity *pid) | |||
678 | GNUNET_CONTAINER_DLL_insert (kx_head, | 686 | GNUNET_CONTAINER_DLL_insert (kx_head, |
679 | kx_tail, | 687 | kx_tail, |
680 | kx); | 688 | kx); |
681 | GNUNET_CRYPTO_hash (pid, sizeof (struct GNUNET_PeerIdentity), &h1); | 689 | kx->status = GNUNET_CORE_KX_STATE_KEY_SENT; |
682 | GNUNET_CRYPTO_hash (&GSC_my_identity, sizeof (struct GNUNET_PeerIdentity), &h2); | 690 | monitor_notify_all (kx); |
683 | 691 | GNUNET_CRYPTO_hash (pid, | |
684 | kx->status = KX_STATE_KEY_SENT; | 692 | sizeof (struct GNUNET_PeerIdentity), |
693 | &h1); | ||
694 | GNUNET_CRYPTO_hash (&GSC_my_identity, | ||
695 | sizeof (struct GNUNET_PeerIdentity), | ||
696 | &h2); | ||
685 | if (0 < GNUNET_CRYPTO_hash_cmp (&h1, | 697 | if (0 < GNUNET_CRYPTO_hash_cmp (&h1, |
686 | &h2)) | 698 | &h2)) |
687 | { | 699 | { |
@@ -722,6 +734,8 @@ GSC_KX_stop (struct GSC_KeyExchangeInfo *kx) | |||
722 | GNUNET_SCHEDULER_cancel (kx->keep_alive_task); | 734 | GNUNET_SCHEDULER_cancel (kx->keep_alive_task); |
723 | kx->keep_alive_task = GNUNET_SCHEDULER_NO_TASK; | 735 | kx->keep_alive_task = GNUNET_SCHEDULER_NO_TASK; |
724 | } | 736 | } |
737 | kx->status = GNUNET_CORE_KX_PEER_DISCONNECT; | ||
738 | monitor_notify_all (kx); | ||
725 | GNUNET_CONTAINER_DLL_remove (kx_head, | 739 | GNUNET_CONTAINER_DLL_remove (kx_head, |
726 | kx_tail, | 740 | kx_tail, |
727 | kx); | 741 | kx); |
@@ -791,7 +805,7 @@ GSC_KX_handle_ephemeral_key (struct GSC_KeyExchangeInfo *kx, | |||
791 | struct GNUNET_TIME_Absolute start_t; | 805 | struct GNUNET_TIME_Absolute start_t; |
792 | struct GNUNET_TIME_Absolute end_t; | 806 | struct GNUNET_TIME_Absolute end_t; |
793 | struct GNUNET_TIME_Absolute now; | 807 | struct GNUNET_TIME_Absolute now; |
794 | enum KxStateMachine sender_status; | 808 | enum GNUNET_CORE_KxState sender_status; |
795 | uint16_t size; | 809 | uint16_t size; |
796 | 810 | ||
797 | size = ntohs (msg->size); | 811 | size = ntohs (msg->size); |
@@ -802,9 +816,9 @@ GSC_KX_handle_ephemeral_key (struct GSC_KeyExchangeInfo *kx, | |||
802 | } | 816 | } |
803 | m = (const struct EphemeralKeyMessage *) msg; | 817 | m = (const struct EphemeralKeyMessage *) msg; |
804 | end_t = GNUNET_TIME_absolute_ntoh (m->expiration_time); | 818 | end_t = GNUNET_TIME_absolute_ntoh (m->expiration_time); |
805 | if ( ( (KX_STATE_KEY_RECEIVED == kx->status) || | 819 | if ( ( (GNUNET_CORE_KX_STATE_KEY_RECEIVED == kx->status) || |
806 | (KX_STATE_UP == kx->status) || | 820 | (GNUNET_CORE_KX_STATE_UP == kx->status) || |
807 | (KX_STATE_REKEY_SENT == kx->status) ) && | 821 | (GNUNET_CORE_KX_STATE_REKEY_SENT == kx->status) ) && |
808 | (end_t.abs_value_us <= kx->foreign_key_expires.abs_value_us) ) | 822 | (end_t.abs_value_us <= kx->foreign_key_expires.abs_value_us) ) |
809 | { | 823 | { |
810 | GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# old ephemeral keys ignored"), | 824 | GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# old ephemeral keys ignored"), |
@@ -862,18 +876,18 @@ GSC_KX_handle_ephemeral_key (struct GSC_KeyExchangeInfo *kx, | |||
862 | GNUNET_NO); | 876 | GNUNET_NO); |
863 | 877 | ||
864 | /* check if we still need to send the sender our key */ | 878 | /* check if we still need to send the sender our key */ |
865 | sender_status = (enum KxStateMachine) ntohl (m->sender_status); | 879 | sender_status = (enum GNUNET_CORE_KxState) ntohl (m->sender_status); |
866 | switch (sender_status) | 880 | switch (sender_status) |
867 | { | 881 | { |
868 | case KX_STATE_DOWN: | 882 | case GNUNET_CORE_KX_STATE_DOWN: |
869 | GNUNET_break_op (0); | 883 | GNUNET_break_op (0); |
870 | break; | 884 | break; |
871 | case KX_STATE_KEY_SENT: | 885 | case GNUNET_CORE_KX_STATE_KEY_SENT: |
872 | /* fine, need to send our key after updating our status, see below */ | 886 | /* fine, need to send our key after updating our status, see below */ |
873 | break; | 887 | break; |
874 | case KX_STATE_KEY_RECEIVED: | 888 | case GNUNET_CORE_KX_STATE_KEY_RECEIVED: |
875 | case KX_STATE_UP: | 889 | case GNUNET_CORE_KX_STATE_UP: |
876 | case KX_STATE_REKEY_SENT: | 890 | case GNUNET_CORE_KX_STATE_REKEY_SENT: |
877 | /* other peer already got our key */ | 891 | /* other peer already got our key */ |
878 | break; | 892 | break; |
879 | default: | 893 | default: |
@@ -883,35 +897,38 @@ GSC_KX_handle_ephemeral_key (struct GSC_KeyExchangeInfo *kx, | |||
883 | /* check if we need to confirm everything is fine via PING + PONG */ | 897 | /* check if we need to confirm everything is fine via PING + PONG */ |
884 | switch (kx->status) | 898 | switch (kx->status) |
885 | { | 899 | { |
886 | case KX_STATE_DOWN: | 900 | case GNUNET_CORE_KX_STATE_DOWN: |
887 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == kx->keep_alive_task); | 901 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == kx->keep_alive_task); |
888 | kx->status = KX_STATE_KEY_RECEIVED; | 902 | kx->status = GNUNET_CORE_KX_STATE_KEY_RECEIVED; |
889 | if (KX_STATE_KEY_SENT == sender_status) | 903 | monitor_notify_all (kx); |
904 | if (GNUNET_CORE_KX_STATE_KEY_SENT == sender_status) | ||
890 | send_key (kx); | 905 | send_key (kx); |
891 | send_ping (kx); | 906 | send_ping (kx); |
892 | break; | 907 | break; |
893 | case KX_STATE_KEY_SENT: | 908 | case GNUNET_CORE_KX_STATE_KEY_SENT: |
894 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == kx->keep_alive_task); | 909 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == kx->keep_alive_task); |
895 | kx->status = KX_STATE_KEY_RECEIVED; | 910 | kx->status = GNUNET_CORE_KX_STATE_KEY_RECEIVED; |
896 | if (KX_STATE_KEY_SENT == sender_status) | 911 | monitor_notify_all (kx); |
912 | if (GNUNET_CORE_KX_STATE_KEY_SENT == sender_status) | ||
897 | send_key (kx); | 913 | send_key (kx); |
898 | send_ping (kx); | 914 | send_ping (kx); |
899 | break; | 915 | break; |
900 | case KX_STATE_KEY_RECEIVED: | 916 | case GNUNET_CORE_KX_STATE_KEY_RECEIVED: |
901 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == kx->keep_alive_task); | 917 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == kx->keep_alive_task); |
902 | if (KX_STATE_KEY_SENT == sender_status) | 918 | if (GNUNET_CORE_KX_STATE_KEY_SENT == sender_status) |
903 | send_key (kx); | 919 | send_key (kx); |
904 | send_ping (kx); | 920 | send_ping (kx); |
905 | break; | 921 | break; |
906 | case KX_STATE_UP: | 922 | case GNUNET_CORE_KX_STATE_UP: |
907 | kx->status = KX_STATE_REKEY_SENT; | 923 | kx->status = GNUNET_CORE_KX_STATE_REKEY_SENT; |
908 | if (KX_STATE_KEY_SENT == sender_status) | 924 | monitor_notify_all (kx); |
925 | if (GNUNET_CORE_KX_STATE_KEY_SENT == sender_status) | ||
909 | send_key (kx); | 926 | send_key (kx); |
910 | /* we got a new key, need to reconfirm! */ | 927 | /* we got a new key, need to reconfirm! */ |
911 | send_ping (kx); | 928 | send_ping (kx); |
912 | break; | 929 | break; |
913 | case KX_STATE_REKEY_SENT: | 930 | case GNUNET_CORE_KX_STATE_REKEY_SENT: |
914 | if (KX_STATE_KEY_SENT == sender_status) | 931 | if (GNUNET_CORE_KX_STATE_KEY_SENT == sender_status) |
915 | send_key (kx); | 932 | send_key (kx); |
916 | /* we got a new key, need to reconfirm! */ | 933 | /* we got a new key, need to reconfirm! */ |
917 | send_ping (kx); | 934 | send_ping (kx); |
@@ -950,9 +967,9 @@ GSC_KX_handle_ping (struct GSC_KeyExchangeInfo *kx, | |||
950 | GNUNET_STATISTICS_update (GSC_stats, | 967 | GNUNET_STATISTICS_update (GSC_stats, |
951 | gettext_noop ("# PING messages received"), 1, | 968 | gettext_noop ("# PING messages received"), 1, |
952 | GNUNET_NO); | 969 | GNUNET_NO); |
953 | if ( (kx->status != KX_STATE_KEY_RECEIVED) && | 970 | if ( (kx->status != GNUNET_CORE_KX_STATE_KEY_RECEIVED) && |
954 | (kx->status != KX_STATE_UP) && | 971 | (kx->status != GNUNET_CORE_KX_STATE_UP) && |
955 | (kx->status != KX_STATE_REKEY_SENT)) | 972 | (kx->status != GNUNET_CORE_KX_STATE_REKEY_SENT)) |
956 | { | 973 | { |
957 | /* ignore */ | 974 | /* ignore */ |
958 | GNUNET_STATISTICS_update (GSC_stats, | 975 | GNUNET_STATISTICS_update (GSC_stats, |
@@ -1029,7 +1046,8 @@ send_keep_alive (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1029 | gettext_noop ("# sessions terminated by timeout"), | 1046 | gettext_noop ("# sessions terminated by timeout"), |
1030 | 1, GNUNET_NO); | 1047 | 1, GNUNET_NO); |
1031 | GSC_SESSIONS_end (&kx->peer); | 1048 | GSC_SESSIONS_end (&kx->peer); |
1032 | kx->status = KX_STATE_KEY_SENT; | 1049 | kx->status = GNUNET_CORE_KX_STATE_KEY_SENT; |
1050 | monitor_notify_all (kx); | ||
1033 | send_key (kx); | 1051 | send_key (kx); |
1034 | return; | 1052 | return; |
1035 | } | 1053 | } |
@@ -1097,21 +1115,21 @@ GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *kx, | |||
1097 | GNUNET_NO); | 1115 | GNUNET_NO); |
1098 | switch (kx->status) | 1116 | switch (kx->status) |
1099 | { | 1117 | { |
1100 | case KX_STATE_DOWN: | 1118 | case GNUNET_CORE_KX_STATE_DOWN: |
1101 | GNUNET_STATISTICS_update (GSC_stats, | 1119 | GNUNET_STATISTICS_update (GSC_stats, |
1102 | gettext_noop ("# PONG messages dropped (connection down)"), 1, | 1120 | gettext_noop ("# PONG messages dropped (connection down)"), 1, |
1103 | GNUNET_NO); | 1121 | GNUNET_NO); |
1104 | return; | 1122 | return; |
1105 | case KX_STATE_KEY_SENT: | 1123 | case GNUNET_CORE_KX_STATE_KEY_SENT: |
1106 | GNUNET_STATISTICS_update (GSC_stats, | 1124 | GNUNET_STATISTICS_update (GSC_stats, |
1107 | gettext_noop ("# PONG messages dropped (out of order)"), 1, | 1125 | gettext_noop ("# PONG messages dropped (out of order)"), 1, |
1108 | GNUNET_NO); | 1126 | GNUNET_NO); |
1109 | return; | 1127 | return; |
1110 | case KX_STATE_KEY_RECEIVED: | 1128 | case GNUNET_CORE_KX_STATE_KEY_RECEIVED: |
1111 | break; | 1129 | break; |
1112 | case KX_STATE_UP: | 1130 | case GNUNET_CORE_KX_STATE_UP: |
1113 | break; | 1131 | break; |
1114 | case KX_STATE_REKEY_SENT: | 1132 | case GNUNET_CORE_KX_STATE_REKEY_SENT: |
1115 | break; | 1133 | break; |
1116 | default: | 1134 | default: |
1117 | GNUNET_break (0); | 1135 | GNUNET_break (0); |
@@ -1159,35 +1177,37 @@ GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *kx, | |||
1159 | } | 1177 | } |
1160 | switch (kx->status) | 1178 | switch (kx->status) |
1161 | { | 1179 | { |
1162 | case KX_STATE_DOWN: | 1180 | case GNUNET_CORE_KX_STATE_DOWN: |
1163 | GNUNET_assert (0); /* should be impossible */ | 1181 | GNUNET_assert (0); /* should be impossible */ |
1164 | return; | 1182 | return; |
1165 | case KX_STATE_KEY_SENT: | 1183 | case GNUNET_CORE_KX_STATE_KEY_SENT: |
1166 | GNUNET_assert (0); /* should be impossible */ | 1184 | GNUNET_assert (0); /* should be impossible */ |
1167 | return; | 1185 | return; |
1168 | case KX_STATE_KEY_RECEIVED: | 1186 | case GNUNET_CORE_KX_STATE_KEY_RECEIVED: |
1169 | GNUNET_STATISTICS_update (GSC_stats, | 1187 | GNUNET_STATISTICS_update (GSC_stats, |
1170 | gettext_noop | 1188 | gettext_noop |
1171 | ("# session keys confirmed via PONG"), 1, | 1189 | ("# session keys confirmed via PONG"), 1, |
1172 | GNUNET_NO); | 1190 | GNUNET_NO); |
1173 | kx->status = KX_STATE_UP; | 1191 | kx->status = GNUNET_CORE_KX_STATE_UP; |
1192 | monitor_notify_all (kx); | ||
1174 | GSC_SESSIONS_create (&kx->peer, kx); | 1193 | GSC_SESSIONS_create (&kx->peer, kx); |
1175 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == kx->keep_alive_task); | 1194 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == kx->keep_alive_task); |
1176 | update_timeout (kx); | 1195 | update_timeout (kx); |
1177 | break; | 1196 | break; |
1178 | case KX_STATE_UP: | 1197 | case GNUNET_CORE_KX_STATE_UP: |
1179 | GNUNET_STATISTICS_update (GSC_stats, | 1198 | GNUNET_STATISTICS_update (GSC_stats, |
1180 | gettext_noop | 1199 | gettext_noop |
1181 | ("# timeouts prevented via PONG"), 1, | 1200 | ("# timeouts prevented via PONG"), 1, |
1182 | GNUNET_NO); | 1201 | GNUNET_NO); |
1183 | update_timeout (kx); | 1202 | update_timeout (kx); |
1184 | break; | 1203 | break; |
1185 | case KX_STATE_REKEY_SENT: | 1204 | case GNUNET_CORE_KX_STATE_REKEY_SENT: |
1186 | GNUNET_STATISTICS_update (GSC_stats, | 1205 | GNUNET_STATISTICS_update (GSC_stats, |
1187 | gettext_noop | 1206 | gettext_noop |
1188 | ("# rekey operations confirmed via PONG"), 1, | 1207 | ("# rekey operations confirmed via PONG"), 1, |
1189 | GNUNET_NO); | 1208 | GNUNET_NO); |
1190 | kx->status = KX_STATE_UP; | 1209 | kx->status = GNUNET_CORE_KX_STATE_UP; |
1210 | monitor_notify_all (kx); | ||
1191 | update_timeout (kx); | 1211 | update_timeout (kx); |
1192 | break; | 1212 | break; |
1193 | default: | 1213 | default: |
@@ -1205,7 +1225,7 @@ GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *kx, | |||
1205 | static void | 1225 | static void |
1206 | send_key (struct GSC_KeyExchangeInfo *kx) | 1226 | send_key (struct GSC_KeyExchangeInfo *kx) |
1207 | { | 1227 | { |
1208 | GNUNET_assert (KX_STATE_DOWN != kx->status); | 1228 | GNUNET_assert (GNUNET_CORE_KX_STATE_DOWN != kx->status); |
1209 | if (GNUNET_SCHEDULER_NO_TASK != kx->retry_set_key_task) | 1229 | if (GNUNET_SCHEDULER_NO_TASK != kx->retry_set_key_task) |
1210 | { | 1230 | { |
1211 | GNUNET_SCHEDULER_cancel (kx->retry_set_key_task); | 1231 | GNUNET_SCHEDULER_cancel (kx->retry_set_key_task); |
@@ -1321,7 +1341,7 @@ GSC_KX_handle_encrypted_message (struct GSC_KeyExchangeInfo *kx, | |||
1321 | return; | 1341 | return; |
1322 | } | 1342 | } |
1323 | m = (const struct EncryptedMessage *) msg; | 1343 | m = (const struct EncryptedMessage *) msg; |
1324 | if (KX_STATE_UP != kx->status) | 1344 | if (GNUNET_CORE_KX_STATE_UP != kx->status) |
1325 | { | 1345 | { |
1326 | GNUNET_STATISTICS_update (GSC_stats, | 1346 | GNUNET_STATISTICS_update (GSC_stats, |
1327 | gettext_noop | 1347 | gettext_noop |
@@ -1343,7 +1363,8 @@ GSC_KX_handle_encrypted_message (struct GSC_KeyExchangeInfo *kx, | |||
1343 | GNUNET_SCHEDULER_cancel (kx->keep_alive_task); | 1363 | GNUNET_SCHEDULER_cancel (kx->keep_alive_task); |
1344 | kx->keep_alive_task = GNUNET_SCHEDULER_NO_TASK; | 1364 | kx->keep_alive_task = GNUNET_SCHEDULER_NO_TASK; |
1345 | } | 1365 | } |
1346 | kx->status = KX_STATE_KEY_SENT; | 1366 | kx->status = GNUNET_CORE_KX_STATE_KEY_SENT; |
1367 | monitor_notify_all (kx); | ||
1347 | send_key (kx); | 1368 | send_key (kx); |
1348 | return; | 1369 | return; |
1349 | } | 1370 | } |
@@ -1473,7 +1494,7 @@ deliver_message (void *cls, | |||
1473 | { | 1494 | { |
1474 | struct DeliverMessageContext *dmc = client; | 1495 | struct DeliverMessageContext *dmc = client; |
1475 | 1496 | ||
1476 | if (KX_STATE_UP != dmc->kx->status) | 1497 | if (GNUNET_CORE_KX_STATE_UP != dmc->kx->status) |
1477 | { | 1498 | { |
1478 | GNUNET_STATISTICS_update (GSC_stats, | 1499 | GNUNET_STATISTICS_update (GSC_stats, |
1479 | gettext_noop | 1500 | gettext_noop |
@@ -1560,15 +1581,18 @@ do_rekey (void *cls, | |||
1560 | sign_ephemeral_key (); | 1581 | sign_ephemeral_key (); |
1561 | for (pos = kx_head; NULL != pos; pos = pos->next) | 1582 | for (pos = kx_head; NULL != pos; pos = pos->next) |
1562 | { | 1583 | { |
1563 | if (KX_STATE_UP == pos->status) | 1584 | if (GNUNET_CORE_KX_STATE_UP == pos->status) |
1564 | { | 1585 | { |
1565 | pos->status = KX_STATE_REKEY_SENT; | 1586 | pos->status = GNUNET_CORE_KX_STATE_REKEY_SENT; |
1587 | monitor_notify_all (pos); | ||
1566 | derive_session_keys (pos); | 1588 | derive_session_keys (pos); |
1567 | } | 1589 | } |
1568 | if (KX_STATE_DOWN == pos->status) | 1590 | if (GNUNET_CORE_KX_STATE_DOWN == pos->status) |
1569 | { | 1591 | { |
1570 | pos->status = KX_STATE_KEY_SENT; | 1592 | pos->status = GNUNET_CORE_KX_STATE_KEY_SENT; |
1593 | monitor_notify_all (pos); | ||
1571 | } | 1594 | } |
1595 | monitor_notify_all (pos); | ||
1572 | send_key (pos); | 1596 | send_key (pos); |
1573 | } | 1597 | } |
1574 | } | 1598 | } |
@@ -1578,11 +1602,15 @@ do_rekey (void *cls, | |||
1578 | * Initialize KX subsystem. | 1602 | * Initialize KX subsystem. |
1579 | * | 1603 | * |
1580 | * @param pk private key to use for the peer | 1604 | * @param pk private key to use for the peer |
1605 | * @param server the server of the CORE service | ||
1581 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure | 1606 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure |
1582 | */ | 1607 | */ |
1583 | int | 1608 | int |
1584 | GSC_KX_init (struct GNUNET_CRYPTO_EddsaPrivateKey *pk) | 1609 | GSC_KX_init (struct GNUNET_CRYPTO_EddsaPrivateKey *pk, |
1610 | struct GNUNET_SERVER_Handle *server) | ||
1585 | { | 1611 | { |
1612 | nc = GNUNET_SERVER_notification_context_create (server, | ||
1613 | 1); | ||
1586 | my_private_key = pk; | 1614 | my_private_key = pk; |
1587 | GNUNET_CRYPTO_eddsa_key_get_public (my_private_key, | 1615 | GNUNET_CRYPTO_eddsa_key_get_public (my_private_key, |
1588 | &GSC_my_identity.public_key); | 1616 | &GSC_my_identity.public_key); |
@@ -1629,6 +1657,46 @@ GSC_KX_done () | |||
1629 | GNUNET_SERVER_mst_destroy (mst); | 1657 | GNUNET_SERVER_mst_destroy (mst); |
1630 | mst = NULL; | 1658 | mst = NULL; |
1631 | } | 1659 | } |
1660 | if (NULL != nc) | ||
1661 | { | ||
1662 | GNUNET_SERVER_notification_context_destroy (nc); | ||
1663 | nc = NULL; | ||
1664 | } | ||
1632 | } | 1665 | } |
1633 | 1666 | ||
1667 | |||
1668 | /** | ||
1669 | * Handle #GNUNET_MESSAGE_TYPE_CORE_MONITOR_PEERS request. For this | ||
1670 | * request type, the client does not have to have transmitted an INIT | ||
1671 | * request. All current peers are returned, regardless of which | ||
1672 | * message types they accept. | ||
1673 | * | ||
1674 | * @param cls unused | ||
1675 | * @param client client sending the iteration request | ||
1676 | * @param message iteration request message | ||
1677 | */ | ||
1678 | void | ||
1679 | GSC_KX_handle_client_monitor_peers (void *cls, | ||
1680 | struct GNUNET_SERVER_Client *client, | ||
1681 | const struct GNUNET_MessageHeader *message) | ||
1682 | { | ||
1683 | struct MonitorNotifyMessage done_msg; | ||
1684 | struct GSC_KeyExchangeInfo *kx; | ||
1685 | |||
1686 | GNUNET_SERVER_notification_context_add (nc, | ||
1687 | client); | ||
1688 | for (kx = kx_head; NULL != kx; kx = kx->next) | ||
1689 | monitor_notify (client, kx); | ||
1690 | done_msg.header.size = htons (sizeof (struct MonitorNotifyMessage)); | ||
1691 | done_msg.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY); | ||
1692 | done_msg.state = htonl ((uint32_t) GNUNET_CORE_KX_ITERATION_FINISHED); | ||
1693 | memset (&done_msg.peer, 0, sizeof (struct GNUNET_PeerIdentity)); | ||
1694 | done_msg.timeout = GNUNET_TIME_absolute_hton (GNUNET_TIME_UNIT_FOREVER_ABS); | ||
1695 | GNUNET_SERVER_notification_context_unicast (nc, | ||
1696 | client, | ||
1697 | &done_msg.header, | ||
1698 | GNUNET_NO); | ||
1699 | } | ||
1700 | |||
1701 | |||
1634 | /* end of gnunet-service-core_kx.c */ | 1702 | /* end of gnunet-service-core_kx.c */ |
diff --git a/src/core/gnunet-service-core_kx.h b/src/core/gnunet-service-core_kx.h index c6b346ec3..abe6c3ccd 100644 --- a/src/core/gnunet-service-core_kx.h +++ b/src/core/gnunet-service-core_kx.h | |||
@@ -118,10 +118,12 @@ GSC_KX_stop (struct GSC_KeyExchangeInfo *kx); | |||
118 | * Initialize KX subsystem. | 118 | * Initialize KX subsystem. |
119 | * | 119 | * |
120 | * @param pk private key to use for the peer | 120 | * @param pk private key to use for the peer |
121 | * @param server the server of the CORE service | ||
121 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure | 122 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure |
122 | */ | 123 | */ |
123 | int | 124 | int |
124 | GSC_KX_init (struct GNUNET_CRYPTO_EddsaPrivateKey *pk); | 125 | GSC_KX_init (struct GNUNET_CRYPTO_EddsaPrivateKey *pk, |
126 | struct GNUNET_SERVER_Handle *server); | ||
125 | 127 | ||
126 | 128 | ||
127 | /** | 129 | /** |
@@ -130,5 +132,22 @@ GSC_KX_init (struct GNUNET_CRYPTO_EddsaPrivateKey *pk); | |||
130 | void | 132 | void |
131 | GSC_KX_done (void); | 133 | GSC_KX_done (void); |
132 | 134 | ||
135 | |||
136 | /** | ||
137 | * Handle #GNUNET_MESSAGE_TYPE_CORE_MONITOR_PEERS request. For this | ||
138 | * request type, the client does not have to have transmitted an INIT | ||
139 | * request. All current peers are returned, regardless of which | ||
140 | * message types they accept. | ||
141 | * | ||
142 | * @param cls unused | ||
143 | * @param client client sending the iteration request | ||
144 | * @param message iteration request message | ||
145 | */ | ||
146 | void | ||
147 | GSC_KX_handle_client_monitor_peers (void *cls, | ||
148 | struct GNUNET_SERVER_Client *client, | ||
149 | const struct GNUNET_MessageHeader *message); | ||
150 | |||
151 | |||
133 | #endif | 152 | #endif |
134 | /* end of gnunet-service-core_kx.h */ | 153 | /* end of gnunet-service-core_kx.h */ |
diff --git a/src/core/gnunet-service-core_sessions.c b/src/core/gnunet-service-core_sessions.c index 5e8bd537f..eb0013790 100644 --- a/src/core/gnunet-service-core_sessions.c +++ b/src/core/gnunet-service-core_sessions.c | |||
@@ -732,59 +732,6 @@ GSC_SESSIONS_transmit (struct GSC_ClientActiveRequest *car, | |||
732 | 732 | ||
733 | 733 | ||
734 | /** | 734 | /** |
735 | * Helper function for #GSC_SESSIONS_handle_client_iterate_peers(). | ||
736 | * | ||
737 | * @param cls the `struct GNUNET_SERVER_TransmitContext` to queue replies | ||
738 | * @param key identity of the connected peer | ||
739 | * @param value the `struct Neighbour` for the peer | ||
740 | * @return #GNUNET_OK (continue to iterate) | ||
741 | */ | ||
742 | static int | ||
743 | queue_connect_message (void *cls, | ||
744 | const struct GNUNET_PeerIdentity *key, | ||
745 | void *value) | ||
746 | { | ||
747 | struct GNUNET_SERVER_TransmitContext *tc = cls; | ||
748 | struct Session *session = value; | ||
749 | struct ConnectNotifyMessage cnm; | ||
750 | |||
751 | /* FIXME: code duplication with clients... */ | ||
752 | cnm.header.size = htons (sizeof (struct ConnectNotifyMessage)); | ||
753 | cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT); | ||
754 | cnm.reserved = htonl (0); | ||
755 | cnm.peer = session->peer; | ||
756 | GNUNET_SERVER_transmit_context_append_message (tc, &cnm.header); | ||
757 | return GNUNET_OK; | ||
758 | } | ||
759 | |||
760 | |||
761 | /** | ||
762 | * Handle CORE_ITERATE_PEERS request. For this request type, the client | ||
763 | * does not have to have transmitted an INIT request. All current peers | ||
764 | * are returned, regardless of which message types they accept. | ||
765 | * | ||
766 | * @param cls unused | ||
767 | * @param client client sending the iteration request | ||
768 | * @param message iteration request message | ||
769 | */ | ||
770 | void | ||
771 | GSC_SESSIONS_handle_client_iterate_peers (void *cls, | ||
772 | struct GNUNET_SERVER_Client *client, | ||
773 | const struct GNUNET_MessageHeader *message) | ||
774 | { | ||
775 | struct GNUNET_MessageHeader done_msg; | ||
776 | struct GNUNET_SERVER_TransmitContext *tc; | ||
777 | |||
778 | tc = GNUNET_SERVER_transmit_context_create (client); | ||
779 | GNUNET_CONTAINER_multipeermap_iterate (sessions, &queue_connect_message, tc); | ||
780 | done_msg.size = htons (sizeof (struct GNUNET_MessageHeader)); | ||
781 | done_msg.type = htons (GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS_END); | ||
782 | GNUNET_SERVER_transmit_context_append_message (tc, &done_msg); | ||
783 | GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL); | ||
784 | } | ||
785 | |||
786 | |||
787 | /** | ||
788 | * We've received a typemap message from a peer, update ours. | 735 | * We've received a typemap message from a peer, update ours. |
789 | * Notifies clients about the session. | 736 | * Notifies clients about the session. |
790 | * | 737 | * |
diff --git a/src/core/gnunet-service-core_sessions.h b/src/core/gnunet-service-core_sessions.h index 034026bb8..81581e84d 100644 --- a/src/core/gnunet-service-core_sessions.h +++ b/src/core/gnunet-service-core_sessions.h | |||
@@ -118,6 +118,7 @@ GSC_SESSIONS_broadcast (const struct GNUNET_MessageHeader *msg); | |||
118 | void | 118 | void |
119 | GSC_SESSIONS_notify_client_about_sessions (struct GSC_Client *client); | 119 | GSC_SESSIONS_notify_client_about_sessions (struct GSC_Client *client); |
120 | 120 | ||
121 | |||
121 | /** | 122 | /** |
122 | * We've received a typemap message from a peer, update ours. | 123 | * We've received a typemap message from a peer, update ours. |
123 | * Notifies clients about the session. | 124 | * Notifies clients about the session. |
@@ -144,22 +145,6 @@ GSC_SESSIONS_add_to_typemap (const struct GNUNET_PeerIdentity *peer, | |||
144 | 145 | ||
145 | 146 | ||
146 | /** | 147 | /** |
147 | * Handle CORE_ITERATE_PEERS request. For this request type, the client | ||
148 | * does not have to have transmitted an INIT request. All current peers | ||
149 | * are returned, regardless of which message types they accept. | ||
150 | * | ||
151 | * @param cls unused | ||
152 | * @param client client sending the iteration request | ||
153 | * @param message iteration request message | ||
154 | */ | ||
155 | void | ||
156 | GSC_SESSIONS_handle_client_iterate_peers (void *cls, | ||
157 | struct GNUNET_SERVER_Client *client, | ||
158 | const struct GNUNET_MessageHeader | ||
159 | *message); | ||
160 | |||
161 | |||
162 | /** | ||
163 | * Initialize sessions subsystem. | 148 | * Initialize sessions subsystem. |
164 | */ | 149 | */ |
165 | void | 150 | void |
diff --git a/src/include/gnunet_core_service.h b/src/include/gnunet_core_service.h index b0248323a..c4acd3564 100644 --- a/src/include/gnunet_core_service.h +++ b/src/include/gnunet_core_service.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | (C) 2009-2013 Christian Grothoff (and other contributing authors) | 3 | (C) 2009-2014 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -280,31 +280,132 @@ GNUNET_CORE_notify_transmit_ready (struct GNUNET_CORE_Handle *handle, | |||
280 | * @param th handle that was returned by "notify_transmit_ready". | 280 | * @param th handle that was returned by "notify_transmit_ready". |
281 | */ | 281 | */ |
282 | void | 282 | void |
283 | GNUNET_CORE_notify_transmit_ready_cancel (struct GNUNET_CORE_TransmitHandle | 283 | GNUNET_CORE_notify_transmit_ready_cancel (struct GNUNET_CORE_TransmitHandle *th); |
284 | *th); | ||
285 | 284 | ||
286 | 285 | ||
287 | /** | 286 | /** |
288 | * Iterate over all connected peers. Calls @a peer_cb with each | 287 | * Handle to a CORE monitoring operation. |
289 | * connected peer, and then once with NULL to indicate that all peers | 288 | */ |
290 | * have been handled. Normal users of the CORE API are not expected | 289 | struct GNUNET_CORE_MonitorHandle; |
291 | * to use this function. It is different in that it truly lists | 290 | |
292 | * all connections, not just those relevant to the application. This | 291 | |
293 | * function is used by special applications for diagnostics. This | 292 | /** |
294 | * function is NOT part of the 'versioned', 'official' API. | 293 | * State machine for our P2P encryption handshake. Everyone starts in |
294 | * #GNUNET_CORE_KX_STATE_DOWN, if we receive the other peer's key | ||
295 | * (other peer initiated) we start in state | ||
296 | * #GNUNET_CORE_KX_STATE_KEY_RECEIVED (since we will immediately send | ||
297 | * our own); otherwise we start in #GNUNET_CORE_KX_STATE_KEY_SENT. If | ||
298 | * we get back a PONG from within either state, we move up to | ||
299 | * #GNUNET_CORE_KX_STATE_UP (the PONG will always be sent back | ||
300 | * encrypted with the key we sent to the other peer). Eventually, | ||
301 | * we will try to rekey, for this we will enter | ||
302 | * #GNUNET_CORE_KX_STATE_REKEY_SENT until the rekey operation is | ||
303 | * confirmed by a PONG from the other peer. | ||
304 | */ | ||
305 | enum GNUNET_CORE_KxState | ||
306 | { | ||
307 | /** | ||
308 | * No handshake yet. | ||
309 | */ | ||
310 | GNUNET_CORE_KX_STATE_DOWN, | ||
311 | |||
312 | /** | ||
313 | * We've sent our session key. | ||
314 | */ | ||
315 | GNUNET_CORE_KX_STATE_KEY_SENT, | ||
316 | |||
317 | /** | ||
318 | * We've received the other peers session key. | ||
319 | */ | ||
320 | GNUNET_CORE_KX_STATE_KEY_RECEIVED, | ||
321 | |||
322 | /** | ||
323 | * The other peer has confirmed our session key + PING with a PONG | ||
324 | * message encrypted with his session key (which we got). Key | ||
325 | * exchange is done. | ||
326 | */ | ||
327 | GNUNET_CORE_KX_STATE_UP, | ||
328 | |||
329 | /** | ||
330 | * We're rekeying (or had a timeout), so we have sent the other peer | ||
331 | * our new ephemeral key, but we did not get a matching PONG yet. | ||
332 | * This is equivalent to being #GNUNET_CORE_KX_STATE_KEY_RECEIVED, | ||
333 | * except that the session is marked as 'up' with sessions (as we | ||
334 | * don't want to drop and re-establish P2P connections simply due to | ||
335 | * rekeying). | ||
336 | */ | ||
337 | GNUNET_CORE_KX_STATE_REKEY_SENT, | ||
338 | |||
339 | /** | ||
340 | * Last state of a KX (when it is being terminated). Set | ||
341 | * just before CORE frees the internal state for this peer. | ||
342 | */ | ||
343 | GNUNET_CORE_KX_PEER_DISCONNECT, | ||
344 | |||
345 | /** | ||
346 | * This is not a state in a peer's state machine, but a special | ||
347 | * value used with the #GNUNET_CORE_MonitorCallback to indicate | ||
348 | * that we finished the initial iteration over the peers. | ||
349 | */ | ||
350 | GNUNET_CORE_KX_ITERATION_FINISHED, | ||
351 | |||
352 | /** | ||
353 | * This is not a state in a peer's state machine, but a special | ||
354 | * value used with the #GNUNET_CORE_MonitorCallback to indicate | ||
355 | * that we lost the connection to the CORE service (and will try | ||
356 | * to reconnect). If this happens, most likely the CORE service | ||
357 | * crashed and thus all connection state should be assumed lost. | ||
358 | */ | ||
359 | GNUNET_CORE_KX_CORE_DISCONNECT | ||
360 | |||
361 | }; | ||
362 | |||
363 | |||
364 | /** | ||
365 | * Function called by the monitor callback whenever | ||
366 | * a peer's connection status changes. | ||
295 | * | 367 | * |
296 | * FIXME: we should probably make it possible to 'cancel' the | 368 | * @param cls closure |
297 | * operation... | 369 | * @param pid identity of the peer this update is about |
370 | * @param state current key exchange state of the peer | ||
371 | * @param timeout when does the current state expire | ||
372 | */ | ||
373 | typedef void | ||
374 | (*GNUNET_CORE_MonitorCallback)(void *cls, | ||
375 | const struct GNUNET_PeerIdentity *pid, | ||
376 | enum GNUNET_CORE_KxState state, | ||
377 | struct GNUNET_TIME_Absolute timeout); | ||
378 | |||
379 | |||
380 | /** | ||
381 | * Monitor connectivity and KX status of all peers known to CORE. | ||
382 | * Calls @a peer_cb with the current status for each connected peer, | ||
383 | * and then once with NULL to indicate that all peers that are | ||
384 | * currently active have been handled. After that, the iteration | ||
385 | * continues until it is cancelled. Normal users of the CORE API are | ||
386 | * not expected to use this function. It is different in that it | ||
387 | * truly lists all connections (including those where the KX is in | ||
388 | * progress), not just those relevant to the application. This | ||
389 | * function is used by special applications for diagnostics. | ||
298 | * | 390 | * |
299 | * @param cfg configuration handle | 391 | * @param cfg configuration handle |
300 | * @param peer_cb function to call with the peer information | 392 | * @param peer_cb function to call with the peer information |
301 | * @param cb_cls closure for @a peer_cb | 393 | * @param peer_cb_cls closure for @a peer_cb |
302 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on errors | 394 | * @return NULL on error |
303 | */ | 395 | */ |
304 | int | 396 | struct GNUNET_CORE_MonitorHandle * |
305 | GNUNET_CORE_iterate_peers (const struct GNUNET_CONFIGURATION_Handle *cfg, | 397 | GNUNET_CORE_monitor_start (const struct GNUNET_CONFIGURATION_Handle *cfg, |
306 | GNUNET_CORE_ConnectEventHandler peer_cb, | 398 | GNUNET_CORE_MonitorCallback peer_cb, |
307 | void *cb_cls); | 399 | void *peer_cb_cls); |
400 | |||
401 | |||
402 | /** | ||
403 | * Stop monitoring CORE activity. | ||
404 | * | ||
405 | * @param mh monitor to stop | ||
406 | */ | ||
407 | void | ||
408 | GNUNET_CORE_monitor_stop (struct GNUNET_CORE_MonitorHandle *mh); | ||
308 | 409 | ||
309 | 410 | ||
310 | /** | 411 | /** |
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index be19b7de3..e651310ad 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h | |||
@@ -334,14 +334,14 @@ extern "C" | |||
334 | #define GNUNET_MESSAGE_TYPE_CORE_SEND 76 | 334 | #define GNUNET_MESSAGE_TYPE_CORE_SEND 76 |
335 | 335 | ||
336 | /** | 336 | /** |
337 | * Request for peer iteration from CORE service. | 337 | * Request for connection monitoring from CORE service. |
338 | */ | 338 | */ |
339 | #define GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS 78 | 339 | #define GNUNET_MESSAGE_TYPE_CORE_MONITOR_PEERS 78 |
340 | 340 | ||
341 | /** | 341 | /** |
342 | * Last reply from core to request for peer iteration from CORE service. | 342 | * Reply for monitor by CORE service. |
343 | */ | 343 | */ |
344 | #define GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS_END 79 | 344 | #define GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY 79 |
345 | 345 | ||
346 | /** | 346 | /** |
347 | * Encapsulation for an encrypted message between peers. | 347 | * Encapsulation for an encrypted message between peers. |