diff options
author | Martin Schanzenbach <mschanzenbach@posteo.de> | 2016-01-08 19:51:27 +0000 |
---|---|---|
committer | Martin Schanzenbach <mschanzenbach@posteo.de> | 2016-01-08 19:51:27 +0000 |
commit | 8feaa39e16ba33a192b32097e8087c9aca2d27d8 (patch) | |
tree | f414a57f7689d13a3dff8d55c290f80ba0bcb373 /src/identity-provider/identity_provider_api.c | |
parent | 35262a0fe27afccb154122f113adcc75947ee45d (diff) | |
download | gnunet-8feaa39e16ba33a192b32097e8087c9aca2d27d8.tar.gz gnunet-8feaa39e16ba33a192b32097e8087c9aca2d27d8.zip |
- update
Diffstat (limited to 'src/identity-provider/identity_provider_api.c')
-rw-r--r-- | src/identity-provider/identity_provider_api.c | 127 |
1 files changed, 53 insertions, 74 deletions
diff --git a/src/identity-provider/identity_provider_api.c b/src/identity-provider/identity_provider_api.c index c22151534..a1d95c2b8 100644 --- a/src/identity-provider/identity_provider_api.c +++ b/src/identity-provider/identity_provider_api.c | |||
@@ -97,11 +97,6 @@ struct GNUNET_IDENTITY_PROVIDER_Handle | |||
97 | struct GNUNET_CLIENT_Connection *client; | 97 | struct GNUNET_CLIENT_Connection *client; |
98 | 98 | ||
99 | /** | 99 | /** |
100 | * Function to call when we receive updates. | ||
101 | */ | ||
102 | GNUNET_IDENTITY_PROVIDER_Callback cb; | ||
103 | |||
104 | /** | ||
105 | * Closure for 'cb'. | 100 | * Closure for 'cb'. |
106 | */ | 101 | */ |
107 | void *cb_cls; | 102 | void *cb_cls; |
@@ -156,7 +151,7 @@ reconnect (void *cls, | |||
156 | * @param h transport service to reconnect | 151 | * @param h transport service to reconnect |
157 | */ | 152 | */ |
158 | static void | 153 | static void |
159 | reschedule_connect (struct GNUNET_IDENTITY_Handle *h) | 154 | reschedule_connect (struct GNUNET_IDENTITY_PROVIDER_Handle *h) |
160 | { | 155 | { |
161 | GNUNET_assert (h->reconnect_task == NULL); | 156 | GNUNET_assert (h->reconnect_task == NULL); |
162 | 157 | ||
@@ -196,12 +191,9 @@ message_handler (void *cls, | |||
196 | struct GNUNET_IDENTITY_PROVIDER_Token token; | 191 | struct GNUNET_IDENTITY_PROVIDER_Token token; |
197 | struct GNUNET_IDENTITY_PROVIDER_Ticket ticket; | 192 | struct GNUNET_IDENTITY_PROVIDER_Ticket ticket; |
198 | const struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage *irm; | 193 | const struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage *irm; |
199 | const struct GNUNET_IDENTITY_ExchangeResultMessage *erm; | 194 | const struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage *erm; |
200 | struct GNUNET_CRYPTO_EcdsaPublicKey pub; | ||
201 | struct GNUNET_HashCode id; | ||
202 | const char *str; | 195 | const char *str; |
203 | uint16_t size; | 196 | uint16_t size; |
204 | uint16_t name_len; | ||
205 | 197 | ||
206 | if (NULL == msg) | 198 | if (NULL == msg) |
207 | { | 199 | { |
@@ -215,22 +207,22 @@ message_handler (void *cls, | |||
215 | switch (ntohs (msg->type)) | 207 | switch (ntohs (msg->type)) |
216 | { | 208 | { |
217 | case GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE_RESULT: | 209 | case GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE_RESULT: |
218 | if (size < sizeof (struct GNUNET_IDENTITY_IssueResultMessage)) | 210 | if (size < sizeof (struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage)) |
219 | { | 211 | { |
220 | GNUNET_break (0); | 212 | GNUNET_break (0); |
221 | reschedule_connect (h); | 213 | reschedule_connect (h); |
222 | return; | 214 | return; |
223 | } | 215 | } |
224 | irm = (const struct GNUNET_IDENTITY_IssueResultMessage *) msg; | 216 | irm = (const struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage *) msg; |
225 | str = (const char *) &irm[1]; | 217 | str = (const char *) &irm[1]; |
226 | if ( (size > sizeof (struct GNUNET_IDENTITY_IssueResultMessage)) && | 218 | if ( (size > sizeof (struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage)) && |
227 | ('\0' != str[size - sizeof (struct GNUNET_IDENTITY_IssueResultMessage) - 1]) ) | 219 | ('\0' != str[size - sizeof (struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage) - 1]) ) |
228 | { | 220 | { |
229 | GNUNET_break (0); | 221 | GNUNET_break (0); |
230 | reschedule_connect (h); | 222 | reschedule_connect (h); |
231 | return; | 223 | return; |
232 | } | 224 | } |
233 | if (size == sizeof (struct GNUNET_IDENTITY_IssueResultMessage)) | 225 | if (size == sizeof (struct GNUNET_IDENTITY_PROVIDER_IssueResultMessage)) |
234 | str = NULL; | 226 | str = NULL; |
235 | 227 | ||
236 | op = h->op_head; | 228 | op = h->op_head; |
@@ -239,28 +231,28 @@ message_handler (void *cls, | |||
239 | op); | 231 | op); |
240 | GNUNET_CLIENT_receive (h->client, &message_handler, h, | 232 | GNUNET_CLIENT_receive (h->client, &message_handler, h, |
241 | GNUNET_TIME_UNIT_FOREVER_REL); | 233 | GNUNET_TIME_UNIT_FOREVER_REL); |
242 | ticket->data = str; | 234 | ticket.data = str; |
243 | if (NULL != op->iss_cb) | 235 | if (NULL != op->iss_cb) |
244 | op->iss_cb (op->cls, &ticket); | 236 | op->iss_cb (op->cls, &ticket); |
245 | GNUNET_free (op); | 237 | GNUNET_free (op); |
246 | break; | 238 | break; |
247 | case GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE_RESULT: | 239 | case GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE_RESULT: |
248 | if (size < sizeof (struct GNUNET_IDENTITY_ExchangeResultMessage)) | 240 | if (size < sizeof (struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage)) |
249 | { | 241 | { |
250 | GNUNET_break (0); | 242 | GNUNET_break (0); |
251 | reschedule_connect (h); | 243 | reschedule_connect (h); |
252 | return; | 244 | return; |
253 | } | 245 | } |
254 | erm = (const struct GNUNET_IDENTITY_ExchangeResultMessage *) msg; | 246 | erm = (const struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage *) msg; |
255 | str = (const char *) &erm[1]; | 247 | str = (const char *) &erm[1]; |
256 | if ( (size > sizeof (struct GNUNET_IDENTITY_ExchangeResultMessage)) && | 248 | if ( (size > sizeof (struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage)) && |
257 | ('\0' != str[size - sizeof (struct GNUNET_IDENTITY_ExchangeResultMessage) - 1]) ) | 249 | ('\0' != str[size - sizeof (struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage) - 1]) ) |
258 | { | 250 | { |
259 | GNUNET_break (0); | 251 | GNUNET_break (0); |
260 | reschedule_connect (h); | 252 | reschedule_connect (h); |
261 | return; | 253 | return; |
262 | } | 254 | } |
263 | if (size == sizeof (struct GNUNET_IDENTITY_ExchangeResultMessage)) | 255 | if (size == sizeof (struct GNUNET_IDENTITY_PROVIDER_ExchangeResultMessage)) |
264 | str = NULL; | 256 | str = NULL; |
265 | 257 | ||
266 | op = h->op_head; | 258 | op = h->op_head; |
@@ -269,9 +261,9 @@ message_handler (void *cls, | |||
269 | op); | 261 | op); |
270 | GNUNET_CLIENT_receive (h->client, &message_handler, h, | 262 | GNUNET_CLIENT_receive (h->client, &message_handler, h, |
271 | GNUNET_TIME_UNIT_FOREVER_REL); | 263 | GNUNET_TIME_UNIT_FOREVER_REL); |
272 | token->data = str; | 264 | token.data = str; |
273 | if (NULL != op->ex_cb) | 265 | if (NULL != op->ex_cb) |
274 | op->ex_cb (op->cls, token); | 266 | op->ex_cb (op->cls, &token); |
275 | GNUNET_free (op); | 267 | GNUNET_free (op); |
276 | break; | 268 | break; |
277 | 269 | ||
@@ -322,8 +314,8 @@ send_next_message (void *cls, | |||
322 | "Sending message of type %d to identity provider service\n", | 314 | "Sending message of type %d to identity provider service\n", |
323 | ntohs (op->msg->type)); | 315 | ntohs (op->msg->type)); |
324 | memcpy (buf, op->msg, ret); | 316 | memcpy (buf, op->msg, ret); |
325 | if ( (NULL == op->cont) && | 317 | if ( (NULL == op->iss_cb) && |
326 | (NULL == op->cb) ) | 318 | (NULL == op->ex_cb) ) |
327 | { | 319 | { |
328 | GNUNET_CONTAINER_DLL_remove (h->op_head, | 320 | GNUNET_CONTAINER_DLL_remove (h->op_head, |
329 | h->op_tail, | 321 | h->op_tail, |
@@ -375,9 +367,7 @@ transmit_next (struct GNUNET_IDENTITY_PROVIDER_Handle *h) | |||
375 | static void | 367 | static void |
376 | reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 368 | reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
377 | { | 369 | { |
378 | struct GNUNET_IDENTITY_Handle *h = cls; | 370 | struct GNUNET_IDENTITY_PROVIDER_Handle *h = cls; |
379 | struct GNUNET_IDENTITY_Operation *op; | ||
380 | struct GNUNET_MessageHeader msg; | ||
381 | 371 | ||
382 | h->reconnect_task = NULL; | 372 | h->reconnect_task = NULL; |
383 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 373 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
@@ -385,20 +375,6 @@ reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
385 | GNUNET_assert (NULL == h->client); | 375 | GNUNET_assert (NULL == h->client); |
386 | h->client = GNUNET_CLIENT_connect ("identity-provider", h->cfg); | 376 | h->client = GNUNET_CLIENT_connect ("identity-provider", h->cfg); |
387 | GNUNET_assert (NULL != h->client); | 377 | GNUNET_assert (NULL != h->client); |
388 | if ( (NULL == h->op_head) || | ||
389 | (GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_START != ntohs (h->op_head->msg->type)) ) | ||
390 | { | ||
391 | op = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_PROVIDER_Operation) + | ||
392 | sizeof (struct GNUNET_MessageHeader)); | ||
393 | op->h = h; | ||
394 | op->msg = (const struct GNUNET_MessageHeader *) &op[1]; | ||
395 | msg.size = htons (sizeof (msg)); | ||
396 | msg.type = htons (GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_START); | ||
397 | memcpy (&op[1], &msg, sizeof (msg)); | ||
398 | GNUNET_CONTAINER_DLL_insert (h->op_head, | ||
399 | h->op_tail, | ||
400 | op); | ||
401 | } | ||
402 | transmit_next (h); | 378 | transmit_next (h); |
403 | GNUNET_assert (NULL != h->th); | 379 | GNUNET_assert (NULL != h->th); |
404 | } | 380 | } |
@@ -417,9 +393,6 @@ GNUNET_IDENTITY_PROVIDER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
417 | 393 | ||
418 | h = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Handle); | 394 | h = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Handle); |
419 | h->cfg = cfg; | 395 | h->cfg = cfg; |
420 | h->cb = cb; | ||
421 | h->cb_cls = cb_cls; | ||
422 | h->egos = GNUNET_CONTAINER_multihashmap_create (16, GNUNET_YES); | ||
423 | h->reconnect_delay = GNUNET_TIME_UNIT_ZERO; | 396 | h->reconnect_delay = GNUNET_TIME_UNIT_ZERO; |
424 | h->reconnect_task = GNUNET_SCHEDULER_add_now (&reconnect, h); | 397 | h->reconnect_task = GNUNET_SCHEDULER_add_now (&reconnect, h); |
425 | return h; | 398 | return h; |
@@ -440,7 +413,8 @@ GNUNET_IDENTITY_PROVIDER_issue_token (struct GNUNET_IDENTITY_PROVIDER_Handle *id | |||
440 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss_key, | 413 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss_key, |
441 | const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, | 414 | const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, |
442 | const char* scopes, | 415 | const char* scopes, |
443 | const struct GNUNET_TIME_Absolute exp, | 416 | struct GNUNET_TIME_Absolute expiration, |
417 | uint64_t nonce, | ||
444 | GNUNET_IDENTITY_PROVIDER_IssueCallback cb, | 418 | GNUNET_IDENTITY_PROVIDER_IssueCallback cb, |
445 | void *cb_cls) | 419 | void *cb_cls) |
446 | { | 420 | { |
@@ -455,18 +429,19 @@ GNUNET_IDENTITY_PROVIDER_issue_token (struct GNUNET_IDENTITY_PROVIDER_Handle *id | |||
455 | return NULL; | 429 | return NULL; |
456 | } | 430 | } |
457 | op = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_PROVIDER_Operation) + | 431 | op = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_PROVIDER_Operation) + |
458 | sizeof (struct GNUNET_IDENTITY_IssueMessage) + | 432 | sizeof (struct GNUNET_IDENTITY_PROVIDER_IssueMessage) + |
459 | slen); | 433 | slen); |
460 | op->h = id; | 434 | op->h = id; |
461 | op->cb = cb; | 435 | op->iss_cb = cb; |
462 | op->cls = cb_cls; | 436 | op->cls = cb_cls; |
463 | im = (struct GNUNET_IDENTITY_GetDefaultMessage *) &op[1]; | 437 | im = (struct GNUNET_IDENTITY_PROVIDER_IssueMessage *) &op[1]; |
464 | im->header.type = htons (GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE); | 438 | im->header.type = htons (GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE); |
465 | im->header.size = htons (sizeof (struct GNUNET_IDENTITY_PROVIDER_IssueMessage) + | 439 | im->header.size = htons (sizeof (struct GNUNET_IDENTITY_PROVIDER_IssueMessage) + |
466 | slen); | 440 | slen); |
467 | im->iss_key = *iss_key; | 441 | im->iss_key = *iss_key; |
468 | im->aud_key = *aud_ley; | 442 | im->aud_key = *aud_key; |
469 | im->exp = exp.abs_value_ul; | 443 | im->nonce = htonl (nonce); |
444 | im->expiration = GNUNET_TIME_absolute_hton (expiration); | ||
470 | memcpy (&im[1], scopes, slen); | 445 | memcpy (&im[1], scopes, slen); |
471 | op->msg = &im->header; | 446 | op->msg = &im->header; |
472 | GNUNET_CONTAINER_DLL_insert_tail (id->op_head, | 447 | GNUNET_CONTAINER_DLL_insert_tail (id->op_head, |
@@ -488,36 +463,41 @@ GNUNET_IDENTITY_PROVIDER_issue_token (struct GNUNET_IDENTITY_PROVIDER_Handle *id | |||
488 | * @return handle to abort the operation | 463 | * @return handle to abort the operation |
489 | */ | 464 | */ |
490 | struct GNUNET_IDENTITY_PROVIDER_Operation * | 465 | struct GNUNET_IDENTITY_PROVIDER_Operation * |
491 | GNUNET_IDENTITY_PROVIDER_exchange_ticket (struct GNUNET_IDENTITY_Handle *id, | 466 | GNUNET_IDENTITY_PROVIDER_exchange_ticket (struct GNUNET_IDENTITY_PROVIDER_Handle *id, |
492 | const char *ticket, | 467 | const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, |
493 | GNUNET_IDENTITY_PROVIDER_ExchangeCallback cont, | 468 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *aud_privkey, |
494 | void *cont_cls) | 469 | GNUNET_IDENTITY_PROVIDER_ExchangeCallback cont, |
470 | void *cont_cls) | ||
495 | { | 471 | { |
496 | struct GNUNET_IDENTITY_PROVIDER_Operation *op; | 472 | struct GNUNET_IDENTITY_PROVIDER_Operation *op; |
497 | struct GNUNET_IDENTITY_PROVIDER_ExchangeMessage *em; | 473 | struct GNUNET_IDENTITY_PROVIDER_ExchangeMessage *em; |
498 | size_t slen; | 474 | size_t slen; |
475 | char *ticket_str; | ||
499 | 476 | ||
500 | slen = strlen (ticket) + 1; | 477 | ticket_str = GNUNET_IDENTITY_PROVIDER_ticket_to_string (ticket); |
501 | if (slen >= GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct GNUNET_IDENTITY_ExchangeMessage)) | 478 | |
479 | slen = strlen (ticket_str) + 1; | ||
480 | if (slen >= GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct GNUNET_IDENTITY_PROVIDER_ExchangeMessage)) | ||
502 | { | 481 | { |
503 | GNUNET_break (0); | 482 | GNUNET_break (0); |
504 | return NULL; | 483 | return NULL; |
505 | } | 484 | } |
506 | op = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_PROVIDER_Operation) + | 485 | op = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_PROVIDER_Operation) + |
507 | sizeof (struct GNUNET_IDENTITY_ExchangeMessage) + | 486 | sizeof (struct GNUNET_IDENTITY_PROVIDER_ExchangeMessage) + |
508 | slen); | 487 | slen); |
509 | op->h = id; | 488 | op->h = id; |
510 | op->cont = cont; | 489 | op->ex_cb = cont; |
511 | op->cls = cont_cls; | 490 | op->cls = cont_cls; |
512 | em = (struct GNUNET_IDENTITY_ExchangeMessage *) &op[1]; | 491 | em = (struct GNUNET_IDENTITY_PROVIDER_ExchangeMessage *) &op[1]; |
513 | em->header.type = htons (GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE); | 492 | em->header.type = htons (GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE); |
514 | em->header.size = htons (sizeof (struct GNUNET_IDENTITY_ExchangeMessage) + | 493 | em->header.size = htons (sizeof (struct GNUNET_IDENTITY_PROVIDER_ExchangeMessage) + |
515 | slen); | 494 | slen); |
516 | memcpy (&em[1], ticket, slen); | 495 | em->aud_privkey = *aud_privkey; |
496 | memcpy (&em[1], ticket_str, slen); | ||
517 | op->msg = &em->header; | 497 | op->msg = &em->header; |
518 | GNUNET_CONTAINER_DLL_insert_tail (id->op_head, | 498 | GNUNET_CONTAINER_DLL_insert_tail (id->op_head, |
519 | id->op_tail, | 499 | id->op_tail, |
520 | op); | 500 | op); |
521 | if (NULL == id->th) | 501 | if (NULL == id->th) |
522 | transmit_next (id); | 502 | transmit_next (id); |
523 | return op; | 503 | return op; |
@@ -535,7 +515,7 @@ GNUNET_IDENTITY_PROVIDER_exchange_ticket (struct GNUNET_IDENTITY_Handle *id, | |||
535 | void | 515 | void |
536 | GNUNET_IDENTITY_PROVIDER_cancel (struct GNUNET_IDENTITY_PROVIDER_Operation *op) | 516 | GNUNET_IDENTITY_PROVIDER_cancel (struct GNUNET_IDENTITY_PROVIDER_Operation *op) |
537 | { | 517 | { |
538 | struct GNUNET_IDENTITY_Handle *h = op->h; | 518 | struct GNUNET_IDENTITY_PROVIDER_Handle *h = op->h; |
539 | 519 | ||
540 | if ( (h->op_head != op) || | 520 | if ( (h->op_head != op) || |
541 | (NULL == h->client) ) | 521 | (NULL == h->client) ) |
@@ -544,8 +524,8 @@ GNUNET_IDENTITY_PROVIDER_cancel (struct GNUNET_IDENTITY_PROVIDER_Operation *op) | |||
544 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 524 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
545 | "Client aborted non-head operation, simply removing it\n"); | 525 | "Client aborted non-head operation, simply removing it\n"); |
546 | GNUNET_CONTAINER_DLL_remove (h->op_head, | 526 | GNUNET_CONTAINER_DLL_remove (h->op_head, |
547 | h->op_tail, | 527 | h->op_tail, |
548 | op); | 528 | op); |
549 | GNUNET_free (op); | 529 | GNUNET_free (op); |
550 | return; | 530 | return; |
551 | } | 531 | } |
@@ -557,8 +537,8 @@ GNUNET_IDENTITY_PROVIDER_cancel (struct GNUNET_IDENTITY_PROVIDER_Operation *op) | |||
557 | GNUNET_CLIENT_notify_transmit_ready_cancel (h->th); | 537 | GNUNET_CLIENT_notify_transmit_ready_cancel (h->th); |
558 | h->th = NULL; | 538 | h->th = NULL; |
559 | GNUNET_CONTAINER_DLL_remove (h->op_head, | 539 | GNUNET_CONTAINER_DLL_remove (h->op_head, |
560 | h->op_tail, | 540 | h->op_tail, |
561 | op); | 541 | op); |
562 | GNUNET_free (op); | 542 | GNUNET_free (op); |
563 | transmit_next (h); | 543 | transmit_next (h); |
564 | return; | 544 | return; |
@@ -594,10 +574,9 @@ GNUNET_IDENTITY_PROVIDER_disconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *h) | |||
594 | } | 574 | } |
595 | while (NULL != (op = h->op_head)) | 575 | while (NULL != (op = h->op_head)) |
596 | { | 576 | { |
597 | GNUNET_break (NULL == op->cont); | ||
598 | GNUNET_CONTAINER_DLL_remove (h->op_head, | 577 | GNUNET_CONTAINER_DLL_remove (h->op_head, |
599 | h->op_tail, | 578 | h->op_tail, |
600 | op); | 579 | op); |
601 | GNUNET_free (op); | 580 | GNUNET_free (op); |
602 | } | 581 | } |
603 | if (NULL != h->client) | 582 | if (NULL != h->client) |