diff options
author | Martin Schanzenbach <mschanzenbach@posteo.de> | 2016-07-15 09:28:14 +0000 |
---|---|---|
committer | Martin Schanzenbach <mschanzenbach@posteo.de> | 2016-07-15 09:28:14 +0000 |
commit | 01fb59c86f5c7e039c58b45ce3271c96029e9058 (patch) | |
tree | 6f2306d633b4b3ac32a95e03ab90e423bb34e8dc /src/identity-provider | |
parent | d921631157c5bfbabee1eb4ee2884c6ad45ac805 (diff) | |
download | gnunet-01fb59c86f5c7e039c58b45ce3271c96029e9058.tar.gz gnunet-01fb59c86f5c7e039c58b45ce3271c96029e9058.zip |
move to MQ api
Diffstat (limited to 'src/identity-provider')
-rw-r--r-- | src/identity-provider/gnunet-service-identity-provider.c | 16 | ||||
-rw-r--r-- | src/identity-provider/identity_provider.h | 23 | ||||
-rw-r--r-- | src/identity-provider/identity_provider_api.c | 538 |
3 files changed, 277 insertions, 300 deletions
diff --git a/src/identity-provider/gnunet-service-identity-provider.c b/src/identity-provider/gnunet-service-identity-provider.c index 80c15f85f..358017d5b 100644 --- a/src/identity-provider/gnunet-service-identity-provider.c +++ b/src/identity-provider/gnunet-service-identity-provider.c | |||
@@ -191,6 +191,11 @@ struct ExchangeHandle | |||
191 | * Label to return | 191 | * Label to return |
192 | */ | 192 | */ |
193 | char *label; | 193 | char *label; |
194 | |||
195 | /** | ||
196 | * request id | ||
197 | */ | ||
198 | uint32_t r_id; | ||
194 | }; | 199 | }; |
195 | 200 | ||
196 | struct IssueHandle | 201 | struct IssueHandle |
@@ -260,6 +265,11 @@ struct IssueHandle | |||
260 | * The label the token is stored under | 265 | * The label the token is stored under |
261 | */ | 266 | */ |
262 | char *label; | 267 | char *label; |
268 | |||
269 | /** | ||
270 | * request id | ||
271 | */ | ||
272 | uint32_t r_id; | ||
263 | }; | 273 | }; |
264 | 274 | ||
265 | /** | 275 | /** |
@@ -1016,6 +1026,7 @@ store_token_issue_cont (void *cls, | |||
1016 | irm = create_issue_result_message (handle->label, | 1026 | irm = create_issue_result_message (handle->label, |
1017 | ticket_str, | 1027 | ticket_str, |
1018 | token_str); | 1028 | token_str); |
1029 | irm->id = handle->r_id; | ||
1019 | GNUNET_SERVER_notification_context_unicast (nc, | 1030 | GNUNET_SERVER_notification_context_unicast (nc, |
1020 | handle->client, | 1031 | handle->client, |
1021 | &irm->header, | 1032 | &irm->header, |
@@ -1250,6 +1261,7 @@ process_lookup_result (void *cls, uint32_t rd_count, | |||
1250 | erm = create_exchange_result_message (token_str, | 1261 | erm = create_exchange_result_message (token_str, |
1251 | handle->label, | 1262 | handle->label, |
1252 | handle->ticket->payload->nonce); | 1263 | handle->ticket->payload->nonce); |
1264 | erm->id = handle->r_id; | ||
1253 | GNUNET_SERVER_notification_context_unicast (nc, | 1265 | GNUNET_SERVER_notification_context_unicast (nc, |
1254 | handle->client, | 1266 | handle->client, |
1255 | &erm->header, | 1267 | &erm->header, |
@@ -1298,7 +1310,7 @@ handle_exchange_message (void *cls, | |||
1298 | ticket); | 1310 | ticket); |
1299 | xchange_handle = GNUNET_malloc (sizeof (struct ExchangeHandle)); | 1311 | xchange_handle = GNUNET_malloc (sizeof (struct ExchangeHandle)); |
1300 | xchange_handle->aud_privkey = em->aud_privkey; | 1312 | xchange_handle->aud_privkey = em->aud_privkey; |
1301 | 1313 | xchange_handle->r_id = em->id; | |
1302 | if (GNUNET_SYSERR == ticket_parse (ticket, | 1314 | if (GNUNET_SYSERR == ticket_parse (ticket, |
1303 | &xchange_handle->aud_privkey, | 1315 | &xchange_handle->aud_privkey, |
1304 | &xchange_handle->ticket)) | 1316 | &xchange_handle->ticket)) |
@@ -1537,7 +1549,7 @@ handle_issue_message (void *cls, | |||
1537 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); | 1549 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); |
1538 | } | 1550 | } |
1539 | GNUNET_free (scopes_tmp); | 1551 | GNUNET_free (scopes_tmp); |
1540 | 1552 | issue_handle->r_id = im->id; | |
1541 | issue_handle->aud_key = im->aud_key; | 1553 | issue_handle->aud_key = im->aud_key; |
1542 | issue_handle->iss_key = im->iss_key; | 1554 | issue_handle->iss_key = im->iss_key; |
1543 | GNUNET_CRYPTO_ecdsa_key_get_public (&im->iss_key, | 1555 | GNUNET_CRYPTO_ecdsa_key_get_public (&im->iss_key, |
diff --git a/src/identity-provider/identity_provider.h b/src/identity-provider/identity_provider.h index 682a20760..da7470bf9 100644 --- a/src/identity-provider/identity_provider.h +++ b/src/identity-provider/identity_provider.h | |||
@@ -65,6 +65,11 @@ struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage | |||
65 | */ | 65 | */ |
66 | struct GNUNET_MessageHeader header; | 66 | struct GNUNET_MessageHeader header; |
67 | 67 | ||
68 | /** | ||
69 | * Unique identifier for this request (for key collisions). | ||
70 | */ | ||
71 | uint32_t id GNUNET_PACKED; | ||
72 | |||
68 | /* followed by 0-terminated label,ticket,token */ | 73 | /* followed by 0-terminated label,ticket,token */ |
69 | 74 | ||
70 | }; | 75 | }; |
@@ -81,6 +86,11 @@ struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage | |||
81 | struct GNUNET_MessageHeader header; | 86 | struct GNUNET_MessageHeader header; |
82 | 87 | ||
83 | /** | 88 | /** |
89 | * Unique identifier for this request (for key collisions). | ||
90 | */ | ||
91 | uint32_t id GNUNET_PACKED; | ||
92 | |||
93 | /** | ||
84 | * Nonce found in ticket. NBO | 94 | * Nonce found in ticket. NBO |
85 | * 0 on error. | 95 | * 0 on error. |
86 | */ | 96 | */ |
@@ -103,6 +113,12 @@ struct GNUNET_IDENTITY_PROVIDER_IssueMessage | |||
103 | struct GNUNET_MessageHeader header; | 113 | struct GNUNET_MessageHeader header; |
104 | 114 | ||
105 | /** | 115 | /** |
116 | * Unique identifier for this request (for key collisions). | ||
117 | */ | ||
118 | uint32_t id GNUNET_PACKED; | ||
119 | |||
120 | |||
121 | /** | ||
106 | * Issuer identity private key | 122 | * Issuer identity private key |
107 | */ | 123 | */ |
108 | struct GNUNET_CRYPTO_EcdsaPrivateKey iss_key; | 124 | struct GNUNET_CRYPTO_EcdsaPrivateKey iss_key; |
@@ -137,7 +153,12 @@ struct GNUNET_IDENTITY_PROVIDER_ExchangeMessage | |||
137 | * Type: #GNUNET_MESSAGE_TYPE_IDENTITY_SET_DEFAULT | 153 | * Type: #GNUNET_MESSAGE_TYPE_IDENTITY_SET_DEFAULT |
138 | */ | 154 | */ |
139 | struct GNUNET_MessageHeader header; | 155 | struct GNUNET_MessageHeader header; |
140 | 156 | ||
157 | /** | ||
158 | * Unique identifier for this request (for key collisions). | ||
159 | */ | ||
160 | uint32_t id GNUNET_PACKED; | ||
161 | |||
141 | /** | 162 | /** |
142 | * Audience identity private key | 163 | * Audience identity private key |
143 | */ | 164 | */ |
diff --git a/src/identity-provider/identity_provider_api.c b/src/identity-provider/identity_provider_api.c index d0413c748..6e1b867de 100644 --- a/src/identity-provider/identity_provider_api.c +++ b/src/identity-provider/identity_provider_api.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include "gnunet_util_lib.h" | 27 | #include "gnunet_util_lib.h" |
28 | #include "gnunet_constants.h" | 28 | #include "gnunet_constants.h" |
29 | #include "gnunet_protocols.h" | 29 | #include "gnunet_protocols.h" |
30 | #include "gnunet_mq_lib.h" | ||
30 | #include "gnunet_identity_provider_service.h" | 31 | #include "gnunet_identity_provider_service.h" |
31 | #include "identity_provider.h" | 32 | #include "identity_provider.h" |
32 | 33 | ||
@@ -74,6 +75,16 @@ struct GNUNET_IDENTITY_PROVIDER_Operation | |||
74 | GNUNET_IDENTITY_PROVIDER_IssueCallback iss_cb; | 75 | GNUNET_IDENTITY_PROVIDER_IssueCallback iss_cb; |
75 | 76 | ||
76 | /** | 77 | /** |
78 | * Envelope with the message for this queue entry. | ||
79 | */ | ||
80 | struct GNUNET_MQ_Envelope *env; | ||
81 | |||
82 | /** | ||
83 | * request id | ||
84 | */ | ||
85 | uint32_t r_id; | ||
86 | |||
87 | /** | ||
77 | * Closure for @e cont or @e cb. | 88 | * Closure for @e cont or @e cb. |
78 | */ | 89 | */ |
79 | void *cls; | 90 | void *cls; |
@@ -124,7 +135,17 @@ struct GNUNET_IDENTITY_PROVIDER_Handle | |||
124 | /** | 135 | /** |
125 | * Time for next connect retry. | 136 | * Time for next connect retry. |
126 | */ | 137 | */ |
127 | struct GNUNET_TIME_Relative reconnect_delay; | 138 | struct GNUNET_TIME_Relative reconnect_backoff; |
139 | |||
140 | /** | ||
141 | * Connection to service (if available). | ||
142 | */ | ||
143 | struct GNUNET_MQ_Handle *mq; | ||
144 | |||
145 | /** | ||
146 | * Request Id generator. Incremented by one for each request. | ||
147 | */ | ||
148 | uint32_t r_id_gen; | ||
128 | 149 | ||
129 | /** | 150 | /** |
130 | * Are we polling for incoming messages right now? | 151 | * Are we polling for incoming messages right now? |
@@ -140,256 +161,199 @@ struct GNUNET_IDENTITY_PROVIDER_Handle | |||
140 | * @param cls handle to the service. | 161 | * @param cls handle to the service. |
141 | */ | 162 | */ |
142 | static void | 163 | static void |
143 | reconnect (void *cls); | 164 | reconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *handle); |
144 | |||
145 | 165 | ||
146 | /** | 166 | /** |
147 | * Reschedule a connect attempt to the service. | 167 | * Reconnect |
148 | * | 168 | * |
149 | * @param h transport service to reconnect | 169 | * @param cls the handle |
150 | */ | 170 | */ |
151 | static void | 171 | static void |
152 | reschedule_connect (struct GNUNET_IDENTITY_PROVIDER_Handle *h) | 172 | reconnect_task (void *cls) |
153 | { | 173 | { |
154 | GNUNET_assert (h->reconnect_task == NULL); | 174 | struct GNUNET_IDENTITY_PROVIDER_Handle *handle = cls; |
155 | 175 | ||
156 | if (NULL != h->th) | 176 | handle->reconnect_task = NULL; |
157 | { | 177 | reconnect (handle); |
158 | GNUNET_CLIENT_notify_transmit_ready_cancel (h->th); | ||
159 | h->th = NULL; | ||
160 | } | ||
161 | if (NULL != h->client) | ||
162 | { | ||
163 | GNUNET_CLIENT_disconnect (h->client); | ||
164 | h->client = NULL; | ||
165 | } | ||
166 | h->in_receive = GNUNET_NO; | ||
167 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
168 | "Scheduling task to reconnect to identity provider service in %s.\n", | ||
169 | GNUNET_STRINGS_relative_time_to_string (h->reconnect_delay, GNUNET_YES)); | ||
170 | h->reconnect_task = | ||
171 | GNUNET_SCHEDULER_add_delayed (h->reconnect_delay, &reconnect, h); | ||
172 | h->reconnect_delay = GNUNET_TIME_STD_BACKOFF (h->reconnect_delay); | ||
173 | } | 178 | } |
174 | 179 | ||
175 | 180 | ||
176 | /** | 181 | /** |
177 | * Type of a function to call when we receive a message | 182 | * Disconnect from service and then reconnect. |
178 | * from the service. | ||
179 | * | 183 | * |
180 | * @param cls closure | 184 | * @param handle our handle |
181 | * @param msg message received, NULL on timeout or fatal error | ||
182 | */ | 185 | */ |
183 | static void | 186 | static void |
184 | message_handler (void *cls, | 187 | force_reconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *handle) |
185 | const struct GNUNET_MessageHeader *msg) | ||
186 | { | 188 | { |
187 | struct GNUNET_IDENTITY_PROVIDER_Handle *h = cls; | 189 | GNUNET_MQ_destroy (handle->mq); |
188 | struct GNUNET_IDENTITY_PROVIDER_Operation *op; | 190 | handle->mq = NULL; |
189 | struct GNUNET_IDENTITY_PROVIDER_Token token; | 191 | handle->reconnect_backoff |
190 | struct GNUNET_IDENTITY_PROVIDER_Ticket ticket; | 192 | = GNUNET_TIME_STD_BACKOFF (handle->reconnect_backoff); |
191 | const struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage *irm; | 193 | handle->reconnect_task |
192 | const struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage *erm; | 194 | = GNUNET_SCHEDULER_add_delayed (handle->reconnect_backoff, |
193 | char *str; | 195 | &reconnect_task, |
194 | char *ticket_str; | 196 | handle); |
195 | char *token_str; | ||
196 | char *label_str; | ||
197 | uint16_t size; | ||
198 | uint64_t ticket_nonce; | ||
199 | |||
200 | if (NULL == msg) | ||
201 | { | ||
202 | reschedule_connect (h); | ||
203 | return; | ||
204 | } | ||
205 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
206 | "Received message of type %d from identity provider service\n", | ||
207 | ntohs (msg->type)); | ||
208 | size = ntohs (msg->size); | ||
209 | switch (ntohs (msg->type)) | ||
210 | { | ||
211 | case GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE_RESULT: | ||
212 | if (size < sizeof (struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage)) | ||
213 | { | ||
214 | GNUNET_break (0); | ||
215 | reschedule_connect (h); | ||
216 | return; | ||
217 | } | ||
218 | irm = (const struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage *) msg; | ||
219 | str = GNUNET_strdup ((char *) &irm[1]); | ||
220 | if ( (size > sizeof (struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage)) && | ||
221 | ('\0' != str[size - sizeof (struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage) - 1]) ) | ||
222 | { | ||
223 | GNUNET_free (str); | ||
224 | GNUNET_break (0); | ||
225 | reschedule_connect (h); | ||
226 | return; | ||
227 | } | ||
228 | if (size == sizeof (struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage)) | ||
229 | { | ||
230 | GNUNET_free (str); | ||
231 | str = NULL; | ||
232 | } | ||
233 | label_str = strtok (str, ","); | ||
234 | |||
235 | if (NULL == label_str) | ||
236 | { | ||
237 | GNUNET_free (str); | ||
238 | GNUNET_break (0); | ||
239 | reschedule_connect (h); | ||
240 | return; | ||
241 | } | ||
242 | ticket_str = strtok (NULL, ","); | ||
243 | if (NULL == ticket_str) | ||
244 | { | ||
245 | GNUNET_free (str); | ||
246 | GNUNET_break (0); | ||
247 | reschedule_connect (h); | ||
248 | return; | ||
249 | } | ||
250 | token_str = strtok (NULL, ","); | ||
251 | if (NULL == token_str) | ||
252 | { | ||
253 | GNUNET_free (str); | ||
254 | GNUNET_break (0); | ||
255 | reschedule_connect (h); | ||
256 | return; | ||
257 | } | ||
258 | op = h->op_head; | ||
259 | GNUNET_CONTAINER_DLL_remove (h->op_head, | ||
260 | h->op_tail, | ||
261 | op); | ||
262 | GNUNET_CLIENT_receive (h->client, &message_handler, h, | ||
263 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
264 | ticket.data = ticket_str; | ||
265 | token.data = token_str; | ||
266 | if (NULL != op->iss_cb) | ||
267 | op->iss_cb (op->cls, label_str, &ticket, &token); | ||
268 | GNUNET_free (str); | ||
269 | GNUNET_free (op); | ||
270 | break; | ||
271 | case GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE_RESULT: | ||
272 | if (size < sizeof (struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage)) | ||
273 | { | ||
274 | GNUNET_break (0); | ||
275 | reschedule_connect (h); | ||
276 | return; | ||
277 | } | ||
278 | erm = (const struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage *) msg; | ||
279 | str = (char *) &erm[1]; | ||
280 | if ( (size > sizeof (struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage)) && | ||
281 | ('\0' != str[size - sizeof (struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage) - 1]) ) | ||
282 | { | ||
283 | GNUNET_break (0); | ||
284 | reschedule_connect (h); | ||
285 | return; | ||
286 | } | ||
287 | if (size == sizeof (struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage)) | ||
288 | str = NULL; | ||
289 | |||
290 | op = h->op_head; | ||
291 | GNUNET_CONTAINER_DLL_remove (h->op_head, | ||
292 | h->op_tail, | ||
293 | op); | ||
294 | GNUNET_CLIENT_receive (h->client, &message_handler, h, | ||
295 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
296 | token.data = str; | ||
297 | ticket_nonce = ntohl (erm->ticket_nonce); | ||
298 | if (NULL != op->ex_cb) | ||
299 | op->ex_cb (op->cls, &token, ticket_nonce); | ||
300 | GNUNET_free (op); | ||
301 | break; | ||
302 | |||
303 | default: | ||
304 | GNUNET_break (0); | ||
305 | reschedule_connect (h); | ||
306 | return; | ||
307 | } | ||
308 | } | 197 | } |
309 | 198 | ||
310 | |||
311 | /** | 199 | /** |
312 | * Schedule transmission of the next message from our queue. | 200 | * Generic error handler, called with the appropriate error code and |
201 | * the same closure specified at the creation of the message queue. | ||
202 | * Not every message queue implementation supports an error handler. | ||
313 | * | 203 | * |
314 | * @param h identity handle | 204 | * @param cls closure with the `struct GNUNET_GNS_Handle *` |
205 | * @param error error code | ||
315 | */ | 206 | */ |
316 | static void | 207 | static void |
317 | transmit_next (struct GNUNET_IDENTITY_PROVIDER_Handle *h); | 208 | mq_error_handler (void *cls, |
318 | 209 | enum GNUNET_MQ_Error error) | |
210 | { | ||
211 | struct GNUNET_IDENTITY_PROVIDER_Handle *handle = cls; | ||
212 | force_reconnect (handle); | ||
213 | } | ||
319 | 214 | ||
320 | /** | 215 | /** |
321 | * Transmit next message to service. | 216 | * Check validity of message received from the service |
322 | * | 217 | * |
323 | * @param cls the `struct GNUNET_IDENTITY_PROVIDER_Handle`. | 218 | * @param cls the `struct GNUNET_IDENTITY_PROVIDER_Handle *` |
324 | * @param size number of bytes available in @a buf | 219 | * @param result_msg the incoming message |
325 | * @param buf where to copy the message | ||
326 | * @return number of bytes copied to buf | ||
327 | */ | 220 | */ |
328 | static size_t | 221 | static int |
329 | send_next_message (void *cls, | 222 | check_exchange_result (void *cls, |
330 | size_t size, | 223 | const struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage *erm) |
331 | void *buf) | ||
332 | { | 224 | { |
333 | struct GNUNET_IDENTITY_PROVIDER_Handle *h = cls; | 225 | char *str; |
334 | struct GNUNET_IDENTITY_PROVIDER_Operation *op = h->op_head; | 226 | size_t size = ntohs (erm->header.size) - sizeof (*erm); |
335 | size_t ret; | 227 | |
336 | 228 | ||
337 | h->th = NULL; | 229 | str = (char *) &erm[1]; |
338 | if (NULL == op) | 230 | if ( (size > sizeof (struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage)) && |
339 | return 0; | 231 | ('\0' != str[size - sizeof (struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage) - 1]) ) |
340 | ret = ntohs (op->msg->size); | ||
341 | if (ret > size) | ||
342 | { | ||
343 | reschedule_connect (h); | ||
344 | return 0; | ||
345 | } | ||
346 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
347 | "Sending message of type %d to identity provider service\n", | ||
348 | ntohs (op->msg->type)); | ||
349 | GNUNET_memcpy (buf, op->msg, ret); | ||
350 | if ( (NULL == op->iss_cb) && | ||
351 | (NULL == op->ex_cb) ) | ||
352 | { | 232 | { |
353 | GNUNET_CONTAINER_DLL_remove (h->op_head, | 233 | GNUNET_break (0); |
354 | h->op_tail, | 234 | return GNUNET_SYSERR; |
355 | op); | ||
356 | GNUNET_free (op); | ||
357 | transmit_next (h); | ||
358 | } | 235 | } |
359 | if (GNUNET_NO == h->in_receive) | 236 | return GNUNET_OK; |
237 | } | ||
238 | |||
239 | |||
240 | /** | ||
241 | * Check validity of message received from the service | ||
242 | * | ||
243 | * @param cls the `struct GNUNET_IDENTITY_PROVIDER_Handle *` | ||
244 | * @param result_msg the incoming message | ||
245 | */ | ||
246 | static int | ||
247 | check_result (void *cls, | ||
248 | const struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage *irm) | ||
249 | { | ||
250 | char *str; | ||
251 | size_t size = ntohs (irm->header.size) - sizeof (*irm); | ||
252 | str = (char*) &irm[1]; | ||
253 | if ( (size > sizeof (struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage)) && | ||
254 | ('\0' != str[size - sizeof (struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage) - 1]) ) | ||
360 | { | 255 | { |
361 | h->in_receive = GNUNET_YES; | 256 | GNUNET_break (0); |
362 | GNUNET_CLIENT_receive (h->client, | 257 | return GNUNET_SYSERR; |
363 | &message_handler, h, | ||
364 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
365 | } | 258 | } |
366 | return ret; | 259 | return GNUNET_OK; |
367 | } | 260 | } |
368 | 261 | ||
262 | /** | ||
263 | * Handler for messages received from the GNS service | ||
264 | * | ||
265 | * @param cls the `struct GNUNET_GNS_Handle *` | ||
266 | * @param loookup_msg the incoming message | ||
267 | */ | ||
268 | static void | ||
269 | handle_exchange_result (void *cls, | ||
270 | const struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage *erm) | ||
271 | { | ||
272 | struct GNUNET_IDENTITY_PROVIDER_Handle *handle = cls; | ||
273 | struct GNUNET_IDENTITY_PROVIDER_Operation *op; | ||
274 | struct GNUNET_IDENTITY_PROVIDER_Token token; | ||
275 | uint64_t ticket_nonce; | ||
276 | uint32_t r_id = ntohl (erm->id); | ||
277 | char *str; | ||
278 | |||
279 | for (op = handle->op_head; NULL != op; op = op->next) | ||
280 | if (op->r_id == r_id) | ||
281 | break; | ||
282 | if (NULL == op) | ||
283 | return; | ||
284 | str = GNUNET_strdup ((char*)&erm[1]); | ||
285 | op = handle->op_head; | ||
286 | GNUNET_CONTAINER_DLL_remove (handle->op_head, | ||
287 | handle->op_tail, | ||
288 | op); | ||
289 | token.data = str; | ||
290 | ticket_nonce = ntohl (erm->ticket_nonce); | ||
291 | if (NULL != op->ex_cb) | ||
292 | op->ex_cb (op->cls, &token, ticket_nonce); | ||
293 | GNUNET_free (str); | ||
294 | GNUNET_free (op); | ||
295 | |||
296 | } | ||
369 | 297 | ||
370 | /** | 298 | /** |
371 | * Schedule transmission of the next message from our queue. | 299 | * Handler for messages received from the GNS service |
372 | * | 300 | * |
373 | * @param h identity provider handle | 301 | * @param cls the `struct GNUNET_GNS_Handle *` |
302 | * @param loookup_msg the incoming message | ||
374 | */ | 303 | */ |
375 | static void | 304 | static void |
376 | transmit_next (struct GNUNET_IDENTITY_PROVIDER_Handle *h) | 305 | handle_result (void *cls, |
306 | const struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage *irm) | ||
377 | { | 307 | { |
378 | struct GNUNET_IDENTITY_PROVIDER_Operation *op = h->op_head; | 308 | struct GNUNET_IDENTITY_PROVIDER_Handle *handle = cls; |
309 | struct GNUNET_IDENTITY_PROVIDER_Operation *op; | ||
310 | struct GNUNET_IDENTITY_PROVIDER_Token token; | ||
311 | struct GNUNET_IDENTITY_PROVIDER_Ticket ticket; | ||
312 | uint32_t r_id = ntohl (irm->id); | ||
313 | char *str; | ||
314 | char *label_str; | ||
315 | char *ticket_str; | ||
316 | char *token_str; | ||
379 | 317 | ||
380 | GNUNET_assert (NULL == h->th); | 318 | for (op = handle->op_head; NULL != op; op = op->next) |
319 | if (op->r_id == r_id) | ||
320 | break; | ||
381 | if (NULL == op) | 321 | if (NULL == op) |
382 | return; | 322 | return; |
383 | if (NULL == h->client) | 323 | str = GNUNET_strdup ((char*)&irm[1]); |
324 | label_str = strtok (str, ","); | ||
325 | |||
326 | if (NULL == label_str) | ||
327 | { | ||
328 | GNUNET_free (str); | ||
329 | GNUNET_break (0); | ||
384 | return; | 330 | return; |
385 | h->th = GNUNET_CLIENT_notify_transmit_ready (h->client, | 331 | } |
386 | ntohs (op->msg->size), | 332 | ticket_str = strtok (NULL, ","); |
387 | GNUNET_TIME_UNIT_FOREVER_REL, | 333 | if (NULL == ticket_str) |
388 | GNUNET_NO, | 334 | { |
389 | &send_next_message, | 335 | GNUNET_free (str); |
390 | h); | 336 | GNUNET_break (0); |
391 | } | 337 | return; |
338 | } | ||
339 | token_str = strtok (NULL, ","); | ||
340 | if (NULL == token_str) | ||
341 | { | ||
342 | GNUNET_free (str); | ||
343 | GNUNET_break (0); | ||
344 | return; | ||
345 | } | ||
346 | GNUNET_CONTAINER_DLL_remove (handle->op_head, | ||
347 | handle->op_tail, | ||
348 | op); | ||
349 | ticket.data = ticket_str; | ||
350 | token.data = token_str; | ||
351 | if (NULL != op->iss_cb) | ||
352 | op->iss_cb (op->cls, label_str, &ticket, &token); | ||
353 | GNUNET_free (str); | ||
354 | GNUNET_free (op); | ||
392 | 355 | ||
356 | } | ||
393 | 357 | ||
394 | /** | 358 | /** |
395 | * Try again to connect to the service. | 359 | * Try again to connect to the service. |
@@ -397,18 +361,35 @@ transmit_next (struct GNUNET_IDENTITY_PROVIDER_Handle *h) | |||
397 | * @param cls handle to the identity provider service. | 361 | * @param cls handle to the identity provider service. |
398 | */ | 362 | */ |
399 | static void | 363 | static void |
400 | reconnect (void *cls) | 364 | reconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *h) |
401 | { | 365 | { |
402 | struct GNUNET_IDENTITY_PROVIDER_Handle *h = cls; | 366 | GNUNET_MQ_hd_var_size (result, |
367 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE_RESULT, | ||
368 | struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage); | ||
369 | GNUNET_MQ_hd_var_size (exchange_result, | ||
370 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE_RESULT, | ||
371 | struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage); | ||
372 | struct GNUNET_MQ_MessageHandler handlers[] = { | ||
373 | make_result_handler (h), | ||
374 | make_exchange_result_handler (h), | ||
375 | GNUNET_MQ_handler_end () | ||
376 | }; | ||
377 | struct GNUNET_IDENTITY_PROVIDER_Operation *op; | ||
403 | 378 | ||
404 | h->reconnect_task = NULL; | 379 | GNUNET_assert (NULL == h->mq); |
405 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 380 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
406 | "Connecting to identity provider service.\n"); | 381 | "Connecting to identity provider service.\n"); |
407 | GNUNET_assert (NULL == h->client); | 382 | |
408 | h->client = GNUNET_CLIENT_connect ("identity-provider", h->cfg); | 383 | h->mq = GNUNET_CLIENT_connecT (h->cfg, |
409 | GNUNET_assert (NULL != h->client); | 384 | "identity-provider", |
410 | transmit_next (h); | 385 | handlers, |
411 | GNUNET_assert (NULL != h->th); | 386 | &mq_error_handler, |
387 | h); | ||
388 | if (NULL == h->mq) | ||
389 | return; | ||
390 | for (op = h->op_head; NULL != op; op = op->next) | ||
391 | GNUNET_MQ_send_copy (h->mq, | ||
392 | op->env); | ||
412 | } | 393 | } |
413 | 394 | ||
414 | 395 | ||
@@ -425,8 +406,12 @@ GNUNET_IDENTITY_PROVIDER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
425 | 406 | ||
426 | h = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Handle); | 407 | h = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Handle); |
427 | h->cfg = cfg; | 408 | h->cfg = cfg; |
428 | h->reconnect_delay = GNUNET_TIME_UNIT_ZERO; | 409 | reconnect (h); |
429 | h->reconnect_task = GNUNET_SCHEDULER_add_now (&reconnect, h); | 410 | if (NULL == h->mq) |
411 | { | ||
412 | GNUNET_free (h); | ||
413 | return NULL; | ||
414 | } | ||
430 | return h; | 415 | return h; |
431 | } | 416 | } |
432 | 417 | ||
@@ -442,13 +427,13 @@ GNUNET_IDENTITY_PROVIDER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
442 | */ | 427 | */ |
443 | struct GNUNET_IDENTITY_PROVIDER_Operation * | 428 | struct GNUNET_IDENTITY_PROVIDER_Operation * |
444 | GNUNET_IDENTITY_PROVIDER_issue_token (struct GNUNET_IDENTITY_PROVIDER_Handle *id, | 429 | GNUNET_IDENTITY_PROVIDER_issue_token (struct GNUNET_IDENTITY_PROVIDER_Handle *id, |
445 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss_key, | 430 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss_key, |
446 | const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, | 431 | const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, |
447 | const char* scopes, | 432 | const char* scopes, |
448 | struct GNUNET_TIME_Absolute expiration, | 433 | struct GNUNET_TIME_Absolute expiration, |
449 | uint64_t nonce, | 434 | uint64_t nonce, |
450 | GNUNET_IDENTITY_PROVIDER_IssueCallback cb, | 435 | GNUNET_IDENTITY_PROVIDER_IssueCallback cb, |
451 | void *cb_cls) | 436 | void *cb_cls) |
452 | { | 437 | { |
453 | struct GNUNET_IDENTITY_PROVIDER_Operation *op; | 438 | struct GNUNET_IDENTITY_PROVIDER_Operation *op; |
454 | struct GNUNET_IDENTITY_PROVIDER_IssueMessage *im; | 439 | struct GNUNET_IDENTITY_PROVIDER_IssueMessage *im; |
@@ -460,27 +445,26 @@ GNUNET_IDENTITY_PROVIDER_issue_token (struct GNUNET_IDENTITY_PROVIDER_Handle *id | |||
460 | GNUNET_break (0); | 445 | GNUNET_break (0); |
461 | return NULL; | 446 | return NULL; |
462 | } | 447 | } |
463 | op = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_PROVIDER_Operation) + | 448 | op = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Operation); |
464 | sizeof (struct GNUNET_IDENTITY_PROVIDER_IssueMessage) + | ||
465 | slen); | ||
466 | op->h = id; | 449 | op->h = id; |
467 | op->iss_cb = cb; | 450 | op->iss_cb = cb; |
468 | op->cls = cb_cls; | 451 | op->cls = cb_cls; |
469 | im = (struct GNUNET_IDENTITY_PROVIDER_IssueMessage *) &op[1]; | 452 | op->r_id = id->r_id_gen++; |
470 | im->header.type = htons (GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE); | 453 | op->env = GNUNET_MQ_msg_extra (im, |
471 | im->header.size = htons (sizeof (struct GNUNET_IDENTITY_PROVIDER_IssueMessage) + | 454 | slen, |
472 | slen); | 455 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE); |
456 | im->id = op->r_id; | ||
473 | im->iss_key = *iss_key; | 457 | im->iss_key = *iss_key; |
474 | im->aud_key = *aud_key; | 458 | im->aud_key = *aud_key; |
475 | im->nonce = htonl (nonce); | 459 | im->nonce = htonl (nonce); |
476 | im->expiration = GNUNET_TIME_absolute_hton (expiration); | 460 | im->expiration = GNUNET_TIME_absolute_hton (expiration); |
477 | GNUNET_memcpy (&im[1], scopes, slen); | 461 | GNUNET_memcpy (&im[1], scopes, slen); |
478 | op->msg = &im->header; | ||
479 | GNUNET_CONTAINER_DLL_insert_tail (id->op_head, | 462 | GNUNET_CONTAINER_DLL_insert_tail (id->op_head, |
480 | id->op_tail, | 463 | id->op_tail, |
481 | op); | 464 | op); |
482 | if (NULL == id->th) | 465 | if (NULL != id->mq) |
483 | transmit_next (id); | 466 | GNUNET_MQ_send_copy (id->mq, |
467 | op->env); | ||
484 | return op; | 468 | return op; |
485 | } | 469 | } |
486 | 470 | ||
@@ -515,25 +499,24 @@ GNUNET_IDENTITY_PROVIDER_exchange_ticket (struct GNUNET_IDENTITY_PROVIDER_Handle | |||
515 | GNUNET_break (0); | 499 | GNUNET_break (0); |
516 | return NULL; | 500 | return NULL; |
517 | } | 501 | } |
518 | op = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_PROVIDER_Operation) + | 502 | op = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Operation); |
519 | sizeof (struct GNUNET_IDENTITY_PROVIDER_ExchangeMessage) + | ||
520 | slen); | ||
521 | op->h = id; | 503 | op->h = id; |
522 | op->ex_cb = cont; | 504 | op->ex_cb = cont; |
523 | op->cls = cont_cls; | 505 | op->cls = cont_cls; |
524 | em = (struct GNUNET_IDENTITY_PROVIDER_ExchangeMessage *) &op[1]; | 506 | op->r_id = id->r_id_gen++; |
525 | em->header.type = htons (GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE); | 507 | op->env = GNUNET_MQ_msg_extra (em, |
526 | em->header.size = htons (sizeof (struct GNUNET_IDENTITY_PROVIDER_ExchangeMessage) + | 508 | slen, |
527 | slen); | 509 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE); |
528 | em->aud_privkey = *aud_privkey; | 510 | em->aud_privkey = *aud_privkey; |
511 | em->id = htonl (op->r_id); | ||
529 | GNUNET_memcpy (&em[1], ticket_str, slen); | 512 | GNUNET_memcpy (&em[1], ticket_str, slen); |
530 | GNUNET_free (ticket_str); | 513 | GNUNET_free (ticket_str); |
531 | op->msg = &em->header; | ||
532 | GNUNET_CONTAINER_DLL_insert_tail (id->op_head, | 514 | GNUNET_CONTAINER_DLL_insert_tail (id->op_head, |
533 | id->op_tail, | 515 | id->op_tail, |
534 | op); | 516 | op); |
535 | if (NULL == id->th) | 517 | if (NULL != id->mq) |
536 | transmit_next (id); | 518 | GNUNET_MQ_send_copy (id->mq, |
519 | op->env); | ||
537 | return op; | 520 | return op; |
538 | } | 521 | } |
539 | 522 | ||
@@ -551,37 +534,11 @@ GNUNET_IDENTITY_PROVIDER_cancel (struct GNUNET_IDENTITY_PROVIDER_Operation *op) | |||
551 | { | 534 | { |
552 | struct GNUNET_IDENTITY_PROVIDER_Handle *h = op->h; | 535 | struct GNUNET_IDENTITY_PROVIDER_Handle *h = op->h; |
553 | 536 | ||
554 | if ( (h->op_head != op) || | 537 | GNUNET_CONTAINER_DLL_remove (h->op_head, |
555 | (NULL == h->client) ) | 538 | h->op_tail, |
556 | { | 539 | op); |
557 | /* request not active, can simply remove */ | 540 | GNUNET_MQ_discard (op->env); |
558 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 541 | GNUNET_free (op); |
559 | "Client aborted non-head operation, simply removing it\n"); | ||
560 | GNUNET_CONTAINER_DLL_remove (h->op_head, | ||
561 | h->op_tail, | ||
562 | op); | ||
563 | GNUNET_free (op); | ||
564 | return; | ||
565 | } | ||
566 | if (NULL != h->th) | ||
567 | { | ||
568 | /* request active but not yet with service, can still abort */ | ||
569 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
570 | "Client aborted head operation prior to transmission, aborting it\n"); | ||
571 | GNUNET_CLIENT_notify_transmit_ready_cancel (h->th); | ||
572 | h->th = NULL; | ||
573 | GNUNET_CONTAINER_DLL_remove (h->op_head, | ||
574 | h->op_tail, | ||
575 | op); | ||
576 | GNUNET_free (op); | ||
577 | transmit_next (h); | ||
578 | return; | ||
579 | } | ||
580 | /* request active with service, simply ensure continuations are not called */ | ||
581 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
582 | "Client aborted active request, NULLing continuation\n"); | ||
583 | op->ex_cb = NULL; | ||
584 | op->iss_cb = NULL; | ||
585 | } | 542 | } |
586 | 543 | ||
587 | 544 | ||
@@ -593,31 +550,18 @@ GNUNET_IDENTITY_PROVIDER_cancel (struct GNUNET_IDENTITY_PROVIDER_Operation *op) | |||
593 | void | 550 | void |
594 | GNUNET_IDENTITY_PROVIDER_disconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *h) | 551 | GNUNET_IDENTITY_PROVIDER_disconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *h) |
595 | { | 552 | { |
596 | struct GNUNET_IDENTITY_PROVIDER_Operation *op; | ||
597 | |||
598 | GNUNET_assert (NULL != h); | 553 | GNUNET_assert (NULL != h); |
599 | if (h->reconnect_task != NULL) | 554 | if (NULL != h->mq) |
600 | { | ||
601 | GNUNET_SCHEDULER_cancel (h->reconnect_task); | ||
602 | h->reconnect_task = NULL; | ||
603 | } | ||
604 | if (NULL != h->th) | ||
605 | { | 555 | { |
606 | GNUNET_CLIENT_notify_transmit_ready_cancel (h->th); | 556 | GNUNET_MQ_destroy (h->mq); |
607 | h->th = NULL; | 557 | h->mq = NULL; |
608 | } | 558 | } |
609 | while (NULL != (op = h->op_head)) | 559 | if (NULL != h->reconnect_task) |
610 | { | 560 | { |
611 | GNUNET_CONTAINER_DLL_remove (h->op_head, | 561 | GNUNET_SCHEDULER_cancel (h->reconnect_task); |
612 | h->op_tail, | 562 | h->reconnect_task = NULL; |
613 | op); | ||
614 | GNUNET_free (op); | ||
615 | } | ||
616 | if (NULL != h->client) | ||
617 | { | ||
618 | GNUNET_CLIENT_disconnect (h->client); | ||
619 | h->client = NULL; | ||
620 | } | 563 | } |
564 | GNUNET_assert (NULL == h->op_head); | ||
621 | GNUNET_free (h); | 565 | GNUNET_free (h); |
622 | } | 566 | } |
623 | 567 | ||