diff --git a/brandt.c b/brandt.c index d71e7c9..dda81ac 100644 --- a/brandt.c +++ b/brandt.c @@ -59,44 +59,62 @@ start_auction (void *arg) struct BRANDT_Auction * -BRANDT_new (BRANDT_CbBroadcast broadcast, - BRANDT_CbResult result, - void *auction_closure, - void **auction_data, - size_t *auction_data_len, +BRANDT_new (BRANDT_CbBroadcast broadcast, + BRANDT_CbResult result, + void *auction_closure, + void **auction_data, + size_t *auction_data_len, struct GNUNET_TIME_Absolute time_start, struct GNUNET_TIME_Relative time_round, - uint16_t num_prices, - uint16_t m, - int outcome_public) + void *description, + uint32_t description_len, + uint16_t num_prices, + uint16_t m, + int outcome_public) { - struct BRANDT_Auction *ret; + struct BRANDT_Auction *ret = GNUNET_new (struct BRANDT_Auction); + struct BRANDT_DescrP *desc = GNUNET_new (struct BRANDT_DescrP); + struct GNUNET_TIME_Relative until_start; + struct GNUNET_HashContext *hc = GNUNET_CRYPTO_hash_context_start (); - ret = GNUNET_new (struct BRANDT_Auction); + desc->time_start = GNUNET_TIME_absolute_hton (time_start); + desc->time_round = GNUNET_TIME_relative_hton (time_round); + desc->description_len = htonl (description_len); + desc->k = htons (num_prices); + desc->m = htons (m); + desc->outcome_public = htons (outcome_public); + GNUNET_CRYPTO_hash_context_read (hc, + &desc->time_start, + sizeof (*desc) - sizeof (desc->hash)); + GNUNET_CRYPTO_hash_context_read (hc, + description, + description_len); + GNUNET_CRYPTO_hash_context_finish (hc, &desc->hash); ret->time_start = time_start; ret->time_round = time_round; - ret->k = num_prices; ret->m = m; ret->outcome_public = outcome_public; + ret->cur_round = msg_join; + ret->round_progress = gcry_mpi_new (256); /* we are the seller */ ret->seller_mode = 1; - /* interface with application */ + /* callback interface with application */ ret->closure = auction_closure; ret->bcast = broadcast; ret->result = result; - ret->cur_round = msg_join; - ret->round_progress = gcry_mpi_new (256); - + until_start = GNUNET_TIME_absolute_get_remaining (time_start); /* \todo: store returned task somewhere to cancel it on shutdown */ - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining (time_start), - &start_auction, - ret); + ret->task = GNUNET_SCHEDULER_add_delayed (until_start, + &start_auction, + ret); + *auction_data_len = sizeof (struct BRANDT_DescrP); + *auction_data = desc; return ret; } @@ -109,53 +127,59 @@ BRANDT_join (BRANDT_CbBroadcast broadcast, const void *auction_data, size_t auction_data_len) { - struct BRANDT_Auction *ret; - struct BRANDT_DescrP *desc = (struct BRANDT_DescrP *)auction_data; + struct BRANDT_Auction *ret = GNUNET_new (struct BRANDT_Auction); + struct BRANDT_DescrP *desc = (struct BRANDT_DescrP *)auction_data; - ret = GNUNET_new (struct BRANDT_Auction); - - ret->time_start = GNUNET_TIME_absolute_ntoh(desc->time_start); - ret->time_round = GNUNET_TIME_relative_ntoh(desc->time_round); - - ret->k = ntohs(desc->k); - ret->m = ntohs(desc->m); - ret->outcome_public = ntohs(desc->outcome_public); + ret->time_start = GNUNET_TIME_absolute_ntoh (desc->time_start); + ret->time_round = GNUNET_TIME_relative_ntoh (desc->time_round); + ret->k = ntohs (desc->k); + ret->m = ntohs (desc->m); + ret->outcome_public = ntohs (desc->outcome_public); + ret->cur_round = msg_join; + ret->round_progress = gcry_mpi_new (256); /* we are the seller */ ret->seller_mode = 0; - /* interface with application */ + /* callback interface with application */ ret->closure = auction_closure; ret->bcast = broadcast; ret->ucast = unicast; ret->result = result; - ret->cur_round = msg_join; - ret->round_progress = gcry_mpi_new (256); - return ret; } +void +BRANDT_destroy (struct BRANDT_Auction *auction) +{ + GNUNET_SCHEDULER_cancel (auction->task); +} + + static void -advance_round (struct BRANDT_Auction *auction, enum auction_type atype, enum outcome_type outcome) +advance_round (struct BRANDT_Auction *ad, + enum auction_type atype, + enum outcome_type outcome) { unsigned char *buf; - size_t buflen; + size_t buflen; /* if we got the current round message from all participants, advance to * next round */ - for (uint16_t i = 0; i < auction->n; i++) - if (!gcry_mpi_test_bit (auction->round_progress, i)) + for (uint16_t i = 0; i < ad->n; i++) + if (!gcry_mpi_test_bit (ad->round_progress, i)) return; - gcry_mpi_clear_highbit (auction->round_progress, 0); - if (msg_last == ++(auction->cur_round)) + gcry_mpi_clear_highbit (ad->round_progress, 0); + if (msg_last == ++(ad->cur_round)) { + /** \todo: finish */ } - if (!handler_out[atype][outcome][auction->cur_round] || - !(buf = handler_out[atype][outcome][auction->cur_round](auction, &buflen))) + if (!handler_out[atype][outcome][ad->cur_round] || + !(buf = handler_out[atype][outcome][ad->cur_round](ad, &buflen))) { /** \todo */ weprintf ("wow fail out"); @@ -165,10 +189,10 @@ advance_round (struct BRANDT_Auction *auction, enum auction_type atype, enum out /** \todo: add msgtype header in the handler_out functions */ /* last message only sent to seller, others are broadcasted */ - if (msg_decrypt == auction->cur_round) - auction->ucast (auction->closure, buf, buflen); + if (msg_decrypt == ad->cur_round) + ad->ucast (ad->closure, buf, buflen); else - auction->bcast (auction->closure, buf, buflen); + ad->bcast (ad->closure, buf, buflen); } @@ -178,10 +202,10 @@ BRANDT_got_message (struct BRANDT_Auction *auction, const unsigned char *msg, size_t msg_len) { - uint16_t mtype = *(uint16_t *)msg; - enum auction_type atype; - enum outcome_type outcome; - enum rounds round = auction->cur_round; + uint16_t mtype = *(uint16_t *)msg; + enum auction_type atype; + enum outcome_type outcome; + enum rounds round = auction->cur_round; atype = auction->m > 0 ? auction_mPlusFirstPrice : auction_firstPrice; outcome = auction->outcome_public ? outcome_public : outcome_private; @@ -207,5 +231,6 @@ BRANDT_got_message (struct BRANDT_Auction *auction, } gcry_mpi_set_bit (auction->round_progress, sender); + /** \todo: seller_mode and new task for round timing */ advance_round (auction, atype, outcome); } diff --git a/brandt.h b/brandt.h index 318da4f..108e082 100644 --- a/brandt.h +++ b/brandt.h @@ -153,21 +153,27 @@ BRANDT_join (BRANDT_CbBroadcast broadcast, * black-box pointer, do NOT dereference/change it or the data it points to! */ struct BRANDT_Auction * -BRANDT_new (BRANDT_CbBroadcast broadcast, - BRANDT_CbResult result, - void *auction_closure, - void **auction_data, - size_t *auction_data_len, +BRANDT_new (BRANDT_CbBroadcast broadcast, + BRANDT_CbResult result, + void *auction_closure, + void **auction_data, + size_t *auction_data_len, struct GNUNET_TIME_Absolute time_start, struct GNUNET_TIME_Relative time_round, - uint16_t num_prices, - uint16_t m, - int outcome_public); + void *description, + uint32_t description_len, + uint16_t num_prices, + uint16_t m, + int outcome_public); -/** \todo */ +/** + * Clean up this auction on shutdown. + * + * @param[in] auction The pointer returned by BRANDT_join() or BRANDT_new(). + * \todo: implement (de)serialization */ void -BRANDT_free (); +BRANDT_destroy (struct BRANDT_Auction *auction); /** diff --git a/internals.h b/internals.h index acb4845..fa2ea87 100644 --- a/internals.h +++ b/internals.h @@ -55,12 +55,20 @@ enum outcome_type { GNUNET_NETWORK_STRUCT_BEGIN /** - * This struct describes an auction and has to be followed by #description_len - * bytes of arbitrary data where the description of the item to be sold is - * stored. All fields are stored in network byte order. + * This struct describes an auction and is always linked to a description buffer + * of #description_len bytes of arbitrary data where the description of the item + * to be sold is stored. This buffer should also contain information linking the + * auction to the payment system (which exact prices do the k possibilities + * refer to, payment system seller identity, …). All fields are stored in + * network byte order. * - * \todo: align to a multiple of 64bit */ + * \todo: align to a multiple of 64bit + * \todo: versionsnummer */ struct BRANDT_DescrP { + /** Hash code over the remaining elements of this struct followed by the + * description buffer of #description_len bytes */ + struct GNUNET_HashCode hash GNUNET_PACKED; + /** Starting time of the auction. Bidders have to join the auction via * BRANDT_join until this time */ struct GNUNET_TIME_AbsoluteNBO time_start; @@ -68,9 +76,12 @@ struct BRANDT_DescrP { /** The maximum duration the participants have to complete each round. */ struct GNUNET_TIME_RelativeNBO time_round; - /** The length of the description in bytes directly following this struct */ + /** The length of the description in bytes */ uint32_t description_len GNUNET_PACKED; + /** reserved for future use */ + uint32_t reserved1 GNUNET_PACKED; + /** The amount of possible prices */ uint16_t k GNUNET_PACKED; @@ -81,6 +92,9 @@ struct BRANDT_DescrP { /** Outcome type. 0 means private outcome, everything else means public * outcome. */ uint16_t outcome_public GNUNET_PACKED; + + /** reserved for future use */ + uint16_t reserved2 GNUNET_PACKED; }; GNUNET_NETWORK_STRUCT_END @@ -102,6 +116,9 @@ struct BRANDT_Auction { * outcome. */ uint16_t outcome_public; + /** Link to the next delayed task (auction start trigger, round trigger) */ + struct GNUNET_SCHEDULER_Task *task; + void *closure; /** auction closure given by the user */ BRANDT_CbBroadcast bcast; /** broadcast callback */