diff options
Diffstat (limited to 'src/reclaim/gnunet-service-reclaim_tickets.c')
-rw-r--r-- | src/reclaim/gnunet-service-reclaim_tickets.c | 205 |
1 files changed, 37 insertions, 168 deletions
diff --git a/src/reclaim/gnunet-service-reclaim_tickets.c b/src/reclaim/gnunet-service-reclaim_tickets.c index 54e5659a4..16e831e22 100644 --- a/src/reclaim/gnunet-service-reclaim_tickets.c +++ b/src/reclaim/gnunet-service-reclaim_tickets.c | |||
@@ -236,28 +236,6 @@ static struct GNUNET_GNS_Handle *gns; | |||
236 | /* Handle to the statistics service */ | 236 | /* Handle to the statistics service */ |
237 | static struct GNUNET_STATISTICS_Handle *stats; | 237 | static struct GNUNET_STATISTICS_Handle *stats; |
238 | 238 | ||
239 | static int create_sym_key_from_ecdh ( | ||
240 | const struct GNUNET_HashCode *new_key_hash, | ||
241 | struct GNUNET_CRYPTO_SymmetricSessionKey *skey, | ||
242 | struct GNUNET_CRYPTO_SymmetricInitializationVector *iv) | ||
243 | { | ||
244 | struct GNUNET_CRYPTO_HashAsciiEncoded new_key_hash_str; | ||
245 | |||
246 | GNUNET_CRYPTO_hash_to_enc (new_key_hash, &new_key_hash_str); | ||
247 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating symmetric rsa key from %s\n", | ||
248 | (char *)&new_key_hash_str); | ||
249 | static const char ctx_key[] = "gnuid-aes-ctx-key"; | ||
250 | GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey), | ||
251 | new_key_hash, sizeof (struct GNUNET_HashCode), ctx_key, | ||
252 | strlen (ctx_key), NULL, 0); | ||
253 | static const char ctx_iv[] = "gnuid-aes-ctx-iv"; | ||
254 | GNUNET_CRYPTO_kdf ( | ||
255 | iv, sizeof (struct GNUNET_CRYPTO_SymmetricInitializationVector), | ||
256 | new_key_hash, sizeof (struct GNUNET_HashCode), ctx_iv, strlen (ctx_iv), | ||
257 | NULL, 0); | ||
258 | return GNUNET_OK; | ||
259 | } | ||
260 | |||
261 | 239 | ||
262 | /** | 240 | /** |
263 | * Cleanup ticket consume handle | 241 | * Cleanup ticket consume handle |
@@ -351,67 +329,32 @@ static void lookup_authz_cb (void *cls, uint32_t rd_count, | |||
351 | const struct GNUNET_GNSRECORD_Data *rd) | 329 | const struct GNUNET_GNSRECORD_Data *rd) |
352 | { | 330 | { |
353 | struct RECLAIM_TICKETS_ConsumeHandle *cth = cls; | 331 | struct RECLAIM_TICKETS_ConsumeHandle *cth = cls; |
354 | struct GNUNET_HashCode new_key_hash; | ||
355 | struct GNUNET_CRYPTO_SymmetricSessionKey enc_key; | ||
356 | struct GNUNET_CRYPTO_SymmetricInitializationVector enc_iv; | ||
357 | struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_key; | ||
358 | struct ParallelLookup *parallel_lookup; | 332 | struct ParallelLookup *parallel_lookup; |
359 | size_t size; | 333 | char *lbl; |
360 | char *buf; | ||
361 | char *attr_lbl; | ||
362 | char *lbls; | ||
363 | 334 | ||
364 | cth->lookup_request = NULL; | 335 | cth->lookup_request = NULL; |
365 | if (1 != rd_count) { | ||
366 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Number of keys %d != 1.", rd_count); | ||
367 | cth->cb (cth->cb_cls, NULL, NULL, GNUNET_SYSERR, "Number of keys %d != 1."); | ||
368 | cleanup_cth (cth); | ||
369 | return; | ||
370 | } | ||
371 | 336 | ||
372 | // Decrypt | ||
373 | ecdh_key = (struct GNUNET_CRYPTO_EcdhePublicKey *)rd->data; | ||
374 | |||
375 | buf = GNUNET_malloc (rd->data_size - | ||
376 | sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)); | ||
377 | |||
378 | // Calculate symmetric key from ecdh parameters | ||
379 | GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdsa_ecdh ( | ||
380 | &cth->identity, ecdh_key, &new_key_hash)); | ||
381 | create_sym_key_from_ecdh (&new_key_hash, &enc_key, &enc_iv); | ||
382 | size = GNUNET_CRYPTO_symmetric_decrypt ( | ||
383 | rd->data + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey), | ||
384 | rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey), &enc_key, | ||
385 | &enc_iv, buf); | ||
386 | |||
387 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
388 | "Decrypted bytes: %zd Expected bytes: %zd\n", size, | ||
389 | rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)); | ||
390 | GNUNET_STATISTICS_update ( | 337 | GNUNET_STATISTICS_update ( |
391 | stats, "reclaim_authz_lookup_time_total", | 338 | stats, "reclaim_authz_lookup_time_total", |
392 | GNUNET_TIME_absolute_get_duration (cth->lookup_start_time).rel_value_us, | 339 | GNUNET_TIME_absolute_get_duration (cth->lookup_start_time).rel_value_us, |
393 | GNUNET_YES); | 340 | GNUNET_YES); |
394 | GNUNET_STATISTICS_update (stats, "reclaim_authz_lookups_count", 1, | 341 | GNUNET_STATISTICS_update (stats, "reclaim_authz_lookups_count", 1, |
395 | GNUNET_YES); | 342 | GNUNET_YES); |
396 | lbls = GNUNET_strdup (buf); | ||
397 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Attributes found %s\n", lbls); | ||
398 | 343 | ||
399 | for (attr_lbl = strtok (lbls, ","); NULL != attr_lbl; | 344 | for (int i = 0; i < rd_count; i++) { |
400 | attr_lbl = strtok (NULL, ",")) { | 345 | lbl = GNUNET_STRINGS_data_to_string_alloc (rd[i].data, rd[i].data_size); |
401 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Looking up %s\n", attr_lbl); | 346 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Attribute ref found %s\n", lbl); |
402 | parallel_lookup = GNUNET_new (struct ParallelLookup); | 347 | parallel_lookup = GNUNET_new (struct ParallelLookup); |
403 | parallel_lookup->handle = cth; | 348 | parallel_lookup->handle = cth; |
404 | parallel_lookup->label = GNUNET_strdup (attr_lbl); | 349 | parallel_lookup->label = lbl; |
405 | parallel_lookup->lookup_start_time = GNUNET_TIME_absolute_get (); | 350 | parallel_lookup->lookup_start_time = GNUNET_TIME_absolute_get (); |
406 | parallel_lookup->lookup_request = GNUNET_GNS_lookup ( | 351 | parallel_lookup->lookup_request = GNUNET_GNS_lookup ( |
407 | gns, attr_lbl, &cth->ticket.identity, | 352 | gns, lbl, &cth->ticket.identity, GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR, |
408 | GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR, GNUNET_GNS_LO_DEFAULT, | 353 | GNUNET_GNS_LO_DEFAULT, &process_parallel_lookup_result, |
409 | &process_parallel_lookup_result, parallel_lookup); | 354 | parallel_lookup); |
410 | GNUNET_CONTAINER_DLL_insert (cth->parallel_lookups_head, | 355 | GNUNET_CONTAINER_DLL_insert (cth->parallel_lookups_head, |
411 | cth->parallel_lookups_tail, parallel_lookup); | 356 | cth->parallel_lookups_tail, parallel_lookup); |
412 | } | 357 | } |
413 | GNUNET_free (lbls); | ||
414 | GNUNET_free (buf); | ||
415 | cth->kill_task = GNUNET_SCHEDULER_add_delayed ( | 358 | cth->kill_task = GNUNET_SCHEDULER_add_delayed ( |
416 | GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 3), | 359 | GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 3), |
417 | &abort_parallel_lookups, cth); | 360 | &abort_parallel_lookups, cth); |
@@ -439,7 +382,7 @@ RECLAIM_TICKETS_consume (const struct GNUNET_CRYPTO_EcdsaPrivateKey *id, | |||
439 | label); | 382 | label); |
440 | cth->lookup_start_time = GNUNET_TIME_absolute_get (); | 383 | cth->lookup_start_time = GNUNET_TIME_absolute_get (); |
441 | cth->lookup_request = GNUNET_GNS_lookup ( | 384 | cth->lookup_request = GNUNET_GNS_lookup ( |
442 | gns, label, &cth->ticket.identity, GNUNET_GNSRECORD_TYPE_RECLAIM_AUTHZ, | 385 | gns, label, &cth->ticket.identity, GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF, |
443 | GNUNET_GNS_LO_DEFAULT, &lookup_authz_cb, cth); | 386 | GNUNET_GNS_LO_DEFAULT, &lookup_authz_cb, cth); |
444 | GNUNET_free (label); | 387 | GNUNET_free (label); |
445 | return cth; | 388 | return cth; |
@@ -500,19 +443,11 @@ static void update_ticket_refs (void *cls) | |||
500 | struct TicketIssueHandle *handle = cls; | 443 | struct TicketIssueHandle *handle = cls; |
501 | struct GNUNET_GNSRECORD_Data refs_rd[handle->ticket_ref_num]; | 444 | struct GNUNET_GNSRECORD_Data refs_rd[handle->ticket_ref_num]; |
502 | struct TicketReference *tr; | 445 | struct TicketReference *tr; |
503 | char *buf; | ||
504 | size_t buf_size; | ||
505 | 446 | ||
506 | tr = handle->ticket_refs_head; | 447 | tr = handle->ticket_refs_head; |
507 | for (int i = 0; i < handle->ticket_ref_num; i++) { | 448 | for (int i = 0; i < handle->ticket_ref_num; i++) { |
508 | buf_size = GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size (tr->attrs); | 449 | refs_rd[i].data = &tr->ticket; |
509 | buf_size += sizeof (struct GNUNET_RECLAIM_Ticket); | 450 | refs_rd[i].data_size = sizeof (struct GNUNET_RECLAIM_Ticket); |
510 | buf = GNUNET_malloc (buf_size); | ||
511 | memcpy (buf, &tr->ticket, sizeof (struct GNUNET_RECLAIM_Ticket)); | ||
512 | GNUNET_RECLAIM_ATTRIBUTE_list_serialize ( | ||
513 | tr->attrs, buf + sizeof (struct GNUNET_RECLAIM_Ticket)); | ||
514 | refs_rd[i].data = buf; | ||
515 | refs_rd[i].data_size = buf_size; | ||
516 | refs_rd[i].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us; | 451 | refs_rd[i].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us; |
517 | refs_rd[i].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_TICKETREF; | 452 | refs_rd[i].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_TICKETREF; |
518 | refs_rd[i].flags = | 453 | refs_rd[i].flags = |
@@ -523,8 +458,6 @@ static void update_ticket_refs (void *cls) | |||
523 | handle->ns_qe = GNUNET_NAMESTORE_records_store ( | 458 | handle->ns_qe = GNUNET_NAMESTORE_records_store ( |
524 | nsh, &handle->identity, GNUNET_GNS_EMPTY_LABEL_AT, handle->ticket_ref_num, | 459 | nsh, &handle->identity, GNUNET_GNS_EMPTY_LABEL_AT, handle->ticket_ref_num, |
525 | refs_rd, &store_ticket_refs_cont, handle); | 460 | refs_rd, &store_ticket_refs_cont, handle); |
526 | for (int i = 0; i < handle->ticket_ref_num; i++) | ||
527 | GNUNET_free ((char *)refs_rd[i].data); | ||
528 | } | 461 | } |
529 | 462 | ||
530 | 463 | ||
@@ -535,8 +468,7 @@ static void ticket_lookup_cb (void *cls, | |||
535 | { | 468 | { |
536 | struct TicketIssueHandle *handle = cls; | 469 | struct TicketIssueHandle *handle = cls; |
537 | struct TicketReference *tr; | 470 | struct TicketReference *tr; |
538 | const char *attr_data; | 471 | |
539 | size_t attr_data_len; | ||
540 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 472 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
541 | "Received tickets from local namestore.\n"); | 473 | "Received tickets from local namestore.\n"); |
542 | handle->ns_qe = NULL; | 474 | handle->ns_qe = NULL; |
@@ -551,10 +483,6 @@ static void ticket_lookup_cb (void *cls, | |||
551 | GNUNET_free (tr); | 483 | GNUNET_free (tr); |
552 | continue; | 484 | continue; |
553 | } | 485 | } |
554 | attr_data = rd[i].data + sizeof (struct GNUNET_RECLAIM_Ticket); | ||
555 | attr_data_len = rd[i].data_size - sizeof (struct GNUNET_RECLAIM_Ticket); | ||
556 | tr->attrs = | ||
557 | GNUNET_RECLAIM_ATTRIBUTE_list_deserialize (attr_data, attr_data_len); | ||
558 | GNUNET_CONTAINER_DLL_insert (handle->ticket_refs_head, | 486 | GNUNET_CONTAINER_DLL_insert (handle->ticket_refs_head, |
559 | handle->ticket_refs_tail, tr); | 487 | handle->ticket_refs_tail, tr); |
560 | handle->ticket_ref_num++; | 488 | handle->ticket_ref_num++; |
@@ -568,6 +496,10 @@ static void ticket_lookup_cb (void *cls, | |||
568 | GNUNET_SCHEDULER_add_now (&update_ticket_refs, handle); | 496 | GNUNET_SCHEDULER_add_now (&update_ticket_refs, handle); |
569 | } | 497 | } |
570 | 498 | ||
499 | |||
500 | /** | ||
501 | * TODO maybe we should cleanup the ATTRREFS here? | ||
502 | */ | ||
571 | static void ticket_lookup_error_cb (void *cls) | 503 | static void ticket_lookup_error_cb (void *cls) |
572 | { | 504 | { |
573 | struct TicketIssueHandle *handle = cls; | 505 | struct TicketIssueHandle *handle = cls; |
@@ -595,93 +527,36 @@ static void store_ticket_issue_cont (void *cls, int32_t success, | |||
595 | } | 527 | } |
596 | 528 | ||
597 | 529 | ||
598 | static int | 530 | static void issue_ticket (struct TicketIssueHandle *ih) |
599 | serialize_authz_record (const struct GNUNET_RECLAIM_Ticket *ticket, | ||
600 | const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs, | ||
601 | struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey, | ||
602 | char **result) | ||
603 | { | 531 | { |
604 | struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey; | ||
605 | struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le; | 532 | struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le; |
606 | struct GNUNET_CRYPTO_SymmetricSessionKey skey; | 533 | struct GNUNET_GNSRECORD_Data *attrs_record; |
607 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | ||
608 | struct GNUNET_HashCode new_key_hash; | ||
609 | ssize_t enc_size; | ||
610 | char *enc_keyinfo; | ||
611 | char *buf; | ||
612 | char *write_ptr; | ||
613 | char attrs_str_len; | ||
614 | char *label; | 534 | char *label; |
615 | 535 | size_t list_len = 0; | |
616 | GNUNET_assert (NULL != attrs->list_head); | 536 | int i; |
617 | attrs_str_len = 0; | 537 | |
618 | for (le = attrs->list_head; NULL != le; le = le->next) { | 538 | for (le = ih->attrs->list_head; NULL != le; le = le->next) |
619 | attrs_str_len += 15 + 1; // TODO propery calculate | 539 | list_len++; |
620 | } | 540 | |
621 | buf = GNUNET_malloc (attrs_str_len); | 541 | attrs_record = |
622 | write_ptr = buf; | 542 | GNUNET_malloc (list_len * sizeof (struct GNUNET_GNSRECORD_Data)); |
623 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Writing attributes\n"); | 543 | i = 0; |
624 | for (le = attrs->list_head; NULL != le; le = le->next) { | 544 | for (le = ih->attrs->list_head; NULL != le; le = le->next) { |
625 | label = | 545 | attrs_record[i].data = &le->claim->id; |
626 | GNUNET_STRINGS_data_to_string_alloc (&le->claim->id, sizeof (uint64_t)); | 546 | attrs_record[i].data_size = sizeof (le->claim->id); |
627 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Adding attribute to record: %s\n", | 547 | attrs_record[i].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us; |
628 | label); | 548 | attrs_record[i].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF; |
629 | 549 | attrs_record[i].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; | |
630 | GNUNET_memcpy (write_ptr, label, strlen (label)); | ||
631 | write_ptr[strlen (label)] = ','; | ||
632 | write_ptr += strlen (label) + 1; | ||
633 | GNUNET_free (label); | ||
634 | } | 550 | } |
635 | write_ptr--; | ||
636 | write_ptr[0] = '\0'; // replace last , with a 0-terminator | ||
637 | // ECDH keypair E = eG | ||
638 | *ecdh_privkey = GNUNET_CRYPTO_ecdhe_key_create (); | ||
639 | GNUNET_CRYPTO_ecdhe_key_get_public (*ecdh_privkey, &ecdh_pubkey); | ||
640 | enc_keyinfo = GNUNET_malloc (attrs_str_len); | ||
641 | // Derived key K = H(eB) | ||
642 | GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (*ecdh_privkey, | ||
643 | &ticket->audience, | ||
644 | &new_key_hash)); | ||
645 | create_sym_key_from_ecdh (&new_key_hash, &skey, &iv); | ||
646 | enc_size = GNUNET_CRYPTO_symmetric_encrypt (buf, attrs_str_len, &skey, &iv, | ||
647 | enc_keyinfo); | ||
648 | *result = | ||
649 | GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) + enc_size); | ||
650 | GNUNET_memcpy (*result, &ecdh_pubkey, | ||
651 | sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)); | ||
652 | GNUNET_memcpy (*result + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey), | ||
653 | enc_keyinfo, enc_size); | ||
654 | GNUNET_free (enc_keyinfo); | ||
655 | GNUNET_free (buf); | ||
656 | return sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) + enc_size; | ||
657 | } | ||
658 | |||
659 | |||
660 | static void issue_ticket (struct TicketIssueHandle *ih) | ||
661 | { | ||
662 | struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey; | ||
663 | struct GNUNET_GNSRECORD_Data code_record[1]; | ||
664 | char *authz_record_data; | ||
665 | size_t authz_record_len; | ||
666 | char *label; | ||
667 | |||
668 | // TODO rename function | ||
669 | authz_record_len = serialize_authz_record ( | ||
670 | &ih->ticket, ih->attrs, &ecdhe_privkey, &authz_record_data); | ||
671 | code_record[0].data = authz_record_data; | ||
672 | code_record[0].data_size = authz_record_len; | ||
673 | code_record[0].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us; | ||
674 | code_record[0].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_AUTHZ; | ||
675 | code_record[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; | ||
676 | 551 | ||
677 | label = | 552 | label = |
678 | GNUNET_STRINGS_data_to_string_alloc (&ih->ticket.rnd, sizeof (uint64_t)); | 553 | GNUNET_STRINGS_data_to_string_alloc (&ih->ticket.rnd, sizeof (uint64_t)); |
679 | // Publish record | 554 | // Publish record |
680 | ih->ns_qe = GNUNET_NAMESTORE_records_store ( | 555 | ih->ns_qe = GNUNET_NAMESTORE_records_store (nsh, &ih->identity, label, |
681 | nsh, &ih->identity, label, 1, code_record, &store_ticket_issue_cont, ih); | 556 | list_len, attrs_record, |
682 | GNUNET_free (ecdhe_privkey); | 557 | &store_ticket_issue_cont, ih); |
558 | GNUNET_free (attrs_record); | ||
683 | GNUNET_free (label); | 559 | GNUNET_free (label); |
684 | GNUNET_free (authz_record_data); | ||
685 | } | 560 | } |
686 | 561 | ||
687 | 562 | ||
@@ -759,8 +634,6 @@ collect_tickets_cb (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, | |||
759 | { | 634 | { |
760 | struct RECLAIM_TICKETS_Iterator *iter = cls; | 635 | struct RECLAIM_TICKETS_Iterator *iter = cls; |
761 | struct TicketReference *tr; | 636 | struct TicketReference *tr; |
762 | size_t attr_data_len; | ||
763 | const char *attr_data; | ||
764 | iter->ns_qe = NULL; | 637 | iter->ns_qe = NULL; |
765 | 638 | ||
766 | for (int i = 0; i < rd_count; i++) { | 639 | for (int i = 0; i < rd_count; i++) { |
@@ -774,10 +647,6 @@ collect_tickets_cb (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, | |||
774 | GNUNET_free (tr); | 647 | GNUNET_free (tr); |
775 | continue; | 648 | continue; |
776 | } | 649 | } |
777 | attr_data = rd[i].data + sizeof (struct GNUNET_RECLAIM_Ticket); | ||
778 | attr_data_len = rd[i].data_size - sizeof (struct GNUNET_RECLAIM_Ticket); | ||
779 | tr->attrs = | ||
780 | GNUNET_RECLAIM_ATTRIBUTE_list_deserialize (attr_data, attr_data_len); | ||
781 | GNUNET_CONTAINER_DLL_insert (iter->tickets_head, iter->tickets_tail, tr); | 650 | GNUNET_CONTAINER_DLL_insert (iter->tickets_head, iter->tickets_tail, tr); |
782 | } | 651 | } |
783 | run_ticket_iteration_round (iter); | 652 | run_ticket_iteration_round (iter); |