X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fscalarproduct%2Fgnunet-service-scalarproduct_bob.c;h=0c38cb42693d226375b70a74c2469c12f19b886b;hb=000d13da5f9a0aec36b261169f71c0c90a4129ab;hp=79a0e961a5a1d4886425a8f2b89af5e4f1a83eb9;hpb=e8cf81fdb3fdaef59b49da8f6e952a3225ab326e;p=oweals%2Fgnunet.git diff --git a/src/scalarproduct/gnunet-service-scalarproduct_bob.c b/src/scalarproduct/gnunet-service-scalarproduct_bob.c index 79a0e961a..0c38cb426 100644 --- a/src/scalarproduct/gnunet-service-scalarproduct_bob.c +++ b/src/scalarproduct/gnunet-service-scalarproduct_bob.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2013, 2014 GNUnet e.V. + Copyright (C) 2013, 2014, 2016 GNUnet e.V. GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -58,12 +58,6 @@ struct MpiElement }; -/** - * An incoming session from CADET. - */ -struct CadetIncomingSession; - - /** * A scalarproduct session which tracks an offer for a * multiplication service by a local client. @@ -79,7 +73,7 @@ struct BobServiceSession /** * The client this request is related to. */ - struct GNUNET_SERVER_Client *client; + struct GNUNET_SERVICE_Client *client; /** * Client message queue. @@ -103,6 +97,11 @@ struct BobServiceSession */ struct GNUNET_SET_OperationHandle *intersection_op; + /** + * CADET port we are listening on. + */ + struct GNUNET_CADET_Port *port; + /** * a(Alice) */ @@ -182,20 +181,6 @@ struct BobServiceSession */ int in_destroy; -}; - - -/** - * An incoming session from CADET. - */ -struct CadetIncomingSession -{ - - /** - * Associated client session, or NULL. - */ - struct BobServiceSession *s; - /** * The CADET channel. */ @@ -206,11 +191,6 @@ struct CadetIncomingSession */ struct GNUNET_PeerIdentity peer; - /** - * (hopefully) unique transaction ID - */ - struct GNUNET_HashCode session_id; - /** * Public key of the remote service. */ @@ -221,21 +201,10 @@ struct CadetIncomingSession */ struct GNUNET_MQ_Handle *cadet_mq; - /** - * Has this CADET session been added to the map yet? - * #GNUNET_YES if so, in which case @e session_id is - * the key. - */ - int in_map; - - /** - * Are we already in #destroy_cadet_session()? - */ - int in_destroy; - }; + /** * GNUnet configuration handle */ @@ -256,52 +225,12 @@ static struct GNUNET_CRYPTO_PaillierPrivateKey my_privkey; */ static gcry_mpi_t my_offset; -/** - * Map of `struct BobServiceSession`, by session keys. - */ -static struct GNUNET_CONTAINER_MultiHashMap *client_sessions; - -/** - * Map of `struct CadetIncomingSession`, by session keys. - */ -static struct GNUNET_CONTAINER_MultiHashMap *cadet_sessions; - /** * Handle to the CADET service. */ static struct GNUNET_CADET_Handle *my_cadet; - -/** - * Finds a not terminated client session in the respective map based on - * session key. - * - * @param key the session key we want to search for - * @return the matching session, or NULL for none - */ -static struct BobServiceSession * -find_matching_client_session (const struct GNUNET_HashCode *key) -{ - return GNUNET_CONTAINER_multihashmap_get (client_sessions, - key); -} - - -/** - * Finds a CADET session in the respective map based on session key. - * - * @param key the session key we want to search for - * @return the matching session, or NULL for none - */ -static struct CadetIncomingSession * -find_matching_cadet_session (const struct GNUNET_HashCode *key) -{ - return GNUNET_CONTAINER_multihashmap_get (cadet_sessions, - key); -} - - /** * Callback used to free the elements in the map. * @@ -321,15 +250,6 @@ free_element_cb (void *cls, } -/** - * Destroy session state, we are done with it. - * - * @param session the session to free elements from - */ -static void -destroy_cadet_session (struct CadetIncomingSession *s); - - /** * Destroy session state, we are done with it. * @@ -338,31 +258,18 @@ destroy_cadet_session (struct CadetIncomingSession *s); static void destroy_service_session (struct BobServiceSession *s) { - struct CadetIncomingSession *in; unsigned int i; if (GNUNET_YES == s->in_destroy) return; s->in_destroy = GNUNET_YES; - if (NULL != (in = s->cadet)) - { - s->cadet = NULL; - destroy_cadet_session (in); - } - if (NULL != s->client_mq) - { - GNUNET_MQ_destroy (s->client_mq); - s->client_mq = NULL; - } if (NULL != s->client) { - GNUNET_SERVER_client_disconnect (s->client); + struct GNUNET_SERVICE_Client *c = s->client; + s->client = NULL; + GNUNET_SERVICE_client_drop (c); } - GNUNET_assert (GNUNET_YES == - GNUNET_CONTAINER_multihashmap_remove (client_sessions, - &s->session_id, - s)); if (NULL != s->intersected_elements) { GNUNET_CONTAINER_multihashmap_iterate (s->intersected_elements, @@ -403,47 +310,17 @@ destroy_service_session (struct BobServiceSession *s) GNUNET_free (s->r_prime); s->r_prime = NULL; } - GNUNET_free (s); -} - - -/** - * Destroy incoming CADET session state, we are done with it. - * - * @param in the session to free elements from - */ -static void -destroy_cadet_session (struct CadetIncomingSession *in) -{ - struct BobServiceSession *s; - - if (GNUNET_YES == in->in_destroy) - return; - in->in_destroy = GNUNET_YES; - if (NULL != (s = in->s)) - { - in->s = NULL; - destroy_service_session (s); - } - if (GNUNET_YES == in->in_map) - { - GNUNET_assert (GNUNET_YES == - GNUNET_CONTAINER_multihashmap_remove (cadet_sessions, - &in->session_id, - in)); - in->in_map = GNUNET_NO; - } - if (NULL != in->cadet_mq) + if (NULL != s->port) { - GNUNET_MQ_destroy (in->cadet_mq); - in->cadet_mq = NULL; + GNUNET_CADET_close_port (s->port); + s->port = NULL; } - if (NULL != in->channel) + if (NULL != s->channel) { - GNUNET_CADET_channel_destroy (in->channel); - in->channel = NULL; + GNUNET_CADET_channel_destroy (s->channel); + s->channel = NULL; } - GNUNET_free (in); + GNUNET_free (s); } @@ -460,6 +337,8 @@ prepare_client_end_notification (struct BobServiceSession *session) struct ClientResponseMessage *msg; struct GNUNET_MQ_Envelope *e; + if (NULL == session->client_mq) + return; /* no client left to be notified */ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending session-end notification with status %d to client for session %s\n", session->status, @@ -480,38 +359,26 @@ prepare_client_end_notification (struct BobServiceSession *session) * * It must NOT call #GNUNET_CADET_channel_destroy() on the channel. * - * @param cls closure (set from #GNUNET_CADET_connect()) + * @param cls the `struct BobServiceSession` * @param channel connection to the other end (henceforth invalid) - * @param channel_ctx place where local state associated - * with the channel is stored */ static void cb_channel_destruction (void *cls, - const struct GNUNET_CADET_Channel *channel, - void *channel_ctx) + const struct GNUNET_CADET_Channel *channel) { - struct CadetIncomingSession *in = channel_ctx; - struct BobServiceSession *s; + struct BobServiceSession *s = cls; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer disconnected, terminating session %s with peer %s\n", - GNUNET_h2s (&in->session_id), - GNUNET_i2s (&in->peer)); - if (NULL != in->cadet_mq) - { - GNUNET_MQ_destroy (in->cadet_mq); - in->cadet_mq = NULL; - } - in->channel = NULL; - if (NULL != (s = in->s)) + GNUNET_h2s (&s->session_id), + GNUNET_i2s (&s->peer)); + if (GNUNET_SCALARPRODUCT_STATUS_ACTIVE == s->status) { - if (GNUNET_SCALARPRODUCT_STATUS_ACTIVE == s->status) - { - s->status = GNUNET_SCALARPRODUCT_STATUS_FAILURE; - prepare_client_end_notification (s); - } + s->status = GNUNET_SCALARPRODUCT_STATUS_FAILURE; + prepare_client_end_notification (s); } - destroy_cadet_session (in); + s->channel = NULL; + destroy_service_session (s); } @@ -568,10 +435,10 @@ transmit_bobs_cryptodata_message_multipart (struct BobServiceSession *s) for (i = s->cadet_transmitted_element_count, j = 0; i < s->cadet_transmitted_element_count + todo_count; i++) { //r[i][p] and r[i][q] - memcpy (&payload[j++], + GNUNET_memcpy (&payload[j++], &s->r[i], sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); - memcpy (&payload[j++], + GNUNET_memcpy (&payload[j++], &s->r_prime[i], sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); } @@ -580,7 +447,7 @@ transmit_bobs_cryptodata_message_multipart (struct BobServiceSession *s) GNUNET_MQ_notify_sent (e, &bob_cadet_done_cb, s); - GNUNET_MQ_send (s->cadet->cadet_mq, + GNUNET_MQ_send (s->cadet_mq, e); } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, @@ -625,22 +492,22 @@ transmit_bobs_cryptodata_message (struct BobServiceSession *s) (unsigned int) s->used_element_count); payload = (struct GNUNET_CRYPTO_PaillierCiphertext *) &msg[1]; - memcpy (&payload[0], - &s->s, - sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); - memcpy (&payload[1], - &s->s_prime, - sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); + GNUNET_memcpy (&payload[0], + &s->s, + sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); + GNUNET_memcpy (&payload[1], + &s->s_prime, + sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); payload = &payload[2]; // convert k[][] for (i = 0; i < s->cadet_transmitted_element_count; i++) { //k[i][p] and k[i][q] - memcpy (&payload[i * 2], + GNUNET_memcpy (&payload[i * 2], &s->r[i], sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); - memcpy (&payload[i * 2 + 1], + GNUNET_memcpy (&payload[i * 2 + 1], &s->r_prime[i], sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)); } @@ -648,7 +515,7 @@ transmit_bobs_cryptodata_message (struct BobServiceSession *s) GNUNET_MQ_notify_sent (e, &bob_cadet_done_cb, s); - GNUNET_MQ_send (s->cadet->cadet_mq, + GNUNET_MQ_send (s->cadet_mq, e); transmit_bobs_cryptodata_message_multipart (s); } @@ -747,14 +614,14 @@ compute_service_response (struct BobServiceSession *session) gcry_mpi_sub (tmp, my_offset, rand[p[i]]); gcry_mpi_sub (tmp, tmp, b[p[i]].value); GNUNET_assert (2 == - GNUNET_CRYPTO_paillier_encrypt (&session->cadet->remote_pubkey, + GNUNET_CRYPTO_paillier_encrypt (&session->remote_pubkey, tmp, 2, &r[i])); // E(S - r_pi - b_pi) * E(S + a_pi) == E(2*S + a - r - b) if (GNUNET_OK != - GNUNET_CRYPTO_paillier_hom_add (&session->cadet->remote_pubkey, + GNUNET_CRYPTO_paillier_hom_add (&session->remote_pubkey, &r[i], &a[p[i]], &r[i])) @@ -770,14 +637,14 @@ compute_service_response (struct BobServiceSession *session) // E(S - r_qi) gcry_mpi_sub (tmp, my_offset, rand[q[i]]); GNUNET_assert (2 == - GNUNET_CRYPTO_paillier_encrypt (&session->cadet->remote_pubkey, + GNUNET_CRYPTO_paillier_encrypt (&session->remote_pubkey, tmp, 2, &r_prime[i])); // E(S - r_qi) * E(S + a_qi) == E(2*S + a_qi - r_qi) if (GNUNET_OK != - GNUNET_CRYPTO_paillier_hom_add (&session->cadet->remote_pubkey, + GNUNET_CRYPTO_paillier_hom_add (&session->remote_pubkey, &r_prime[i], &a[q[i]], &r_prime[i])) @@ -791,7 +658,7 @@ compute_service_response (struct BobServiceSession *session) // Calculate S' = E(SUM( r_i^2 )) tmp = compute_square_sum (rand, count); GNUNET_assert (1 == - GNUNET_CRYPTO_paillier_encrypt (&session->cadet->remote_pubkey, + GNUNET_CRYPTO_paillier_encrypt (&session->remote_pubkey, tmp, 1, &session->s_prime)); @@ -802,7 +669,7 @@ compute_service_response (struct BobServiceSession *session) gcry_mpi_add (rand[i], rand[i], b[i].value); tmp = compute_square_sum (rand, count); GNUNET_assert (1 == - GNUNET_CRYPTO_paillier_encrypt (&session->cadet->remote_pubkey, + GNUNET_CRYPTO_paillier_encrypt (&session->remote_pubkey, tmp, 1, &session->s)); @@ -914,8 +781,8 @@ transmit_cryptographic_reply (struct BobServiceSession *s) if (GNUNET_OK != compute_service_response (s)) { - channel = s->cadet->channel; - s->cadet->channel = NULL; + channel = s->channel; + s->channel = NULL; GNUNET_CADET_channel_destroy (channel); return; } @@ -924,49 +791,25 @@ transmit_cryptographic_reply (struct BobServiceSession *s) /** - * Handle a multipart-chunk of a request from another service to + * Check a multipart-chunk of a request from another service to * calculate a scalarproduct with us. * - * @param cls closure (set from #GNUNET_CADET_connect) - * @param channel connection to the other end - * @param channel_ctx place to store local state associated with the @a channel - * @param message the actual message + * @param cls the `struct BobServiceSession *` + * @param msg the actual message * @return #GNUNET_OK to keep the connection open, * #GNUNET_SYSERR to close it (signal serious error) */ static int -handle_alices_cryptodata_message (void *cls, - struct GNUNET_CADET_Channel *channel, - void **channel_ctx, - const struct GNUNET_MessageHeader *message) +check_alices_cryptodata_message (void *cls, + const struct AliceCryptodataMessage *msg) { - struct CadetIncomingSession *in = *channel_ctx; - struct BobServiceSession *s; - const struct AliceCryptodataMessage *msg; - const struct GNUNET_CRYPTO_PaillierCiphertext *payload; + struct BobServiceSession *s = cls; uint32_t contained_elements; size_t msg_length; uint16_t msize; unsigned int max; - if (NULL == in) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - s = in->s; - if (NULL == s) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - msize = ntohs (message->size); - if (msize <= sizeof (struct AliceCryptodataMessage)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - msg = (const struct AliceCryptodataMessage *) message; + msize = ntohs (msg->header.size); contained_elements = ntohl (msg->contained_element_count); /* Our intersection may still be ongoing, but this is nevertheless an upper bound on the required array size */ @@ -981,17 +824,41 @@ handle_alices_cryptodata_message (void *cls, GNUNET_break_op (0); return GNUNET_SYSERR; } + return GNUNET_OK; +} + + +/** + * Handle a multipart-chunk of a request from another service to + * calculate a scalarproduct with us. + * + * @param cls the `struct BobServiceSession *` + * @param msg the actual message + */ +static void +handle_alices_cryptodata_message (void *cls, + const struct AliceCryptodataMessage *msg) +{ + struct BobServiceSession *s = cls; + const struct GNUNET_CRYPTO_PaillierCiphertext *payload; + uint32_t contained_elements; + unsigned int max; + + contained_elements = ntohl (msg->contained_element_count); + /* Our intersection may still be ongoing, but this is nevertheless + an upper bound on the required array size */ + max = GNUNET_CONTAINER_multihashmap_size (s->intersected_elements); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received %u crypto values from Alice\n", (unsigned int) contained_elements); payload = (const struct GNUNET_CRYPTO_PaillierCiphertext *) &msg[1]; if (NULL == s->e_a) - s->e_a = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) * - max); - memcpy (&s->e_a[s->cadet_received_element_count], - payload, - sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) * contained_elements); + s->e_a = GNUNET_new_array (max, + struct GNUNET_CRYPTO_PaillierCiphertext); + GNUNET_memcpy (&s->e_a[s->cadet_received_element_count], + payload, + sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) * contained_elements); s->cadet_received_element_count += contained_elements; if ( (s->cadet_received_element_count == max) && @@ -1002,8 +869,7 @@ handle_alices_cryptodata_message (void *cls, CADET response(s) */ transmit_cryptographic_reply (s); } - GNUNET_CADET_receive_done (s->cadet->channel); - return GNUNET_OK; + GNUNET_CADET_receive_done (s->channel); } @@ -1013,11 +879,13 @@ handle_alices_cryptodata_message (void *cls, * * @param cls closure with the `struct BobServiceSession` * @param element a result element, only valid if status is #GNUNET_SET_STATUS_OK + * @param current_size current set size * @param status what has happened with the set intersection? */ static void cb_intersection_element_removed (void *cls, const struct GNUNET_SET_Element *element, + uint64_t current_size, enum GNUNET_SET_Status status) { struct BobServiceSession *s = cls; @@ -1043,7 +911,7 @@ cb_intersection_element_removed (void *cls, case GNUNET_SET_STATUS_DONE: s->intersection_op = NULL; GNUNET_break (NULL == s->intersection_set); - GNUNET_CADET_receive_done (s->cadet->channel); + GNUNET_CADET_receive_done (s->channel); LOG (GNUNET_ERROR_TYPE_DEBUG, "Finished intersection, %d items remain\n", GNUNET_CONTAINER_multihashmap_size (s->intersected_elements)); @@ -1094,10 +962,11 @@ start_intersection (struct BobServiceSession *s) (unsigned int) s->total); s->intersection_op - = GNUNET_SET_prepare (&s->cadet->peer, + = GNUNET_SET_prepare (&s->peer, &s->session_id, NULL, GNUNET_SET_RESULT_REMOVED, + (struct GNUNET_SET_Option[]) {{ 0 }}, &cb_intersection_element_removed, s); if (GNUNET_OK != @@ -1117,55 +986,19 @@ start_intersection (struct BobServiceSession *s) /** * Handle a request from Alice to calculate a scalarproduct with us (Bob). * - * @param cls closure (set from #GNUNET_CADET_connect) - * @param channel connection to the other end - * @param channel_ctx place to store the `struct CadetIncomingSession *` - * @param message the actual message - * @return #GNUNET_OK to keep the connection open, - * #GNUNET_SYSERR to close it (signal serious error) + * @param cls the `struct BobServiceSession *` + * @param msg the actual message */ -static int +static void handle_alices_computation_request (void *cls, - struct GNUNET_CADET_Channel *channel, - void **channel_ctx, - const struct GNUNET_MessageHeader *message) + const struct ServiceRequestMessage *msg) { - struct CadetIncomingSession *in = *channel_ctx; - struct BobServiceSession *s; - const struct ServiceRequestMessage *msg; + struct BobServiceSession *s = cls; - msg = (const struct ServiceRequestMessage *) message; - if (GNUNET_YES == in->in_map) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - if (NULL != find_matching_cadet_session (&msg->session_id)) - { - /* not unique, got one like this already */ - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - in->session_id = msg->session_id; - in->remote_pubkey = msg->public_key; - GNUNET_assert (GNUNET_YES == - GNUNET_CONTAINER_multihashmap_put (cadet_sessions, - &in->session_id, - in, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); - s = find_matching_client_session (&in->session_id); - if (NULL == s) - { - /* no client waiting for this request, wait for client */ - return GNUNET_OK; - } - GNUNET_assert (NULL == s->cadet); - /* pair them up */ - in->s = s; - s->cadet = in; + s->session_id = msg->session_id; // ?? + s->remote_pubkey = msg->public_key; if (s->client_received_element_count == s->total) start_intersection (s); - return GNUNET_OK; } @@ -1174,76 +1007,47 @@ handle_alices_computation_request (void *cls, * preliminary initialization, more happens after we get Alice's first * message. * - * @param cls closure + * @param cls closure with the `struct BobServiceSession` * @param channel new handle to the channel * @param initiator peer that started the channel - * @param port unused - * @param options unused * @return session associated with the channel */ static void * cb_channel_incoming (void *cls, struct GNUNET_CADET_Channel *channel, - const struct GNUNET_PeerIdentity *initiator, - uint32_t port, - enum GNUNET_CADET_ChannelOption options) + const struct GNUNET_PeerIdentity *initiator) { - struct CadetIncomingSession *in; + struct BobServiceSession *s = cls; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New incoming channel from peer %s.\n", GNUNET_i2s (initiator)); - in = GNUNET_new (struct CadetIncomingSession); - in->peer = *initiator; - in->channel = channel; - in->cadet_mq = GNUNET_CADET_mq_create (in->channel); - return in; + GNUNET_CADET_close_port (s->port); + s->port = NULL; + s->channel = channel; + s->peer = *initiator; + s->cadet_mq = GNUNET_CADET_get_mq (s->channel); + return s; } /** - * We're receiving additional set data. Add it to our - * set and if we are done, initiate the transaction. + * We're receiving additional set data. Check it is well-formed. * - * @param cls closure - * @param client identification of the client - * @param message the actual message + * @param cls identification of the client + * @param msg the actual message + * @return #GNUNET_OK if @a msg is well-formed */ -static void -GSS_handle_bob_client_message_multipart (void *cls, - struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader *message) +static int +check_bob_client_message_multipart (void *cls, + const struct ComputationBobCryptodataMultipartMessage *msg) { - const struct ComputationBobCryptodataMultipartMessage * msg; - struct BobServiceSession *s; + struct BobServiceSession *s = cls; uint32_t contained_count; - const struct GNUNET_SCALARPRODUCT_Element *elements; - uint32_t i; uint16_t msize; - struct GNUNET_SET_Element set_elem; - struct GNUNET_SCALARPRODUCT_Element *elem; - s = GNUNET_SERVER_client_get_user_context (client, - struct BobServiceSession); - if (NULL == s) - { - /* session needs to already exist */ - GNUNET_break (0); - GNUNET_SERVER_receive_done (client, - GNUNET_SYSERR); - return; - } - msize = ntohs (message->size); - if (msize < sizeof (struct ComputationBobCryptodataMultipartMessage)) - { - GNUNET_break (0); - GNUNET_SERVER_receive_done (client, - GNUNET_SYSERR); - return; - } - msg = (const struct ComputationBobCryptodataMultipartMessage *) message; + msize = ntohs (msg->header.size); contained_count = ntohl (msg->element_count_contained); - if ( (msize != (sizeof (struct ComputationBobCryptodataMultipartMessage) + contained_count * sizeof (struct GNUNET_SCALARPRODUCT_Element))) || (0 == contained_count) || @@ -1251,18 +1055,38 @@ GSS_handle_bob_client_message_multipart (void *cls, (s->total == s->client_received_element_count) || (s->total < s->client_received_element_count + contained_count) ) { - GNUNET_break_op (0); - GNUNET_SERVER_receive_done (client, - GNUNET_SYSERR); - return; + GNUNET_break (0); + return GNUNET_SYSERR; } + return GNUNET_OK; +} + + +/** + * We're receiving additional set data. Add it to our + * set and if we are done, initiate the transaction. + * + * @param cls identification of the client + * @param msg the actual message + */ +static void +handle_bob_client_message_multipart (void *cls, + const struct ComputationBobCryptodataMultipartMessage *msg) +{ + struct BobServiceSession *s = cls; + uint32_t contained_count; + const struct GNUNET_SCALARPRODUCT_Element *elements; + struct GNUNET_SET_Element set_elem; + struct GNUNET_SCALARPRODUCT_Element *elem; + + contained_count = ntohl (msg->element_count_contained); elements = (const struct GNUNET_SCALARPRODUCT_Element *) &msg[1]; - for (i = 0; i < contained_count; i++) + for (uint32_t i = 0; i < contained_count; i++) { elem = GNUNET_new (struct GNUNET_SCALARPRODUCT_Element); - memcpy (elem, - &elements[i], - sizeof (struct GNUNET_SCALARPRODUCT_Element)); + GNUNET_memcpy (elem, + &elements[i], + sizeof (struct GNUNET_SCALARPRODUCT_Element)); if (GNUNET_SYSERR == GNUNET_CONTAINER_multihashmap_put (s->intersected_elements, &elem->key, @@ -1281,14 +1105,13 @@ GSS_handle_bob_client_message_multipart (void *cls, NULL, NULL); } s->client_received_element_count += contained_count; - GNUNET_SERVER_receive_done (client, - GNUNET_OK); + GNUNET_SERVICE_client_continue (s->client); if (s->total != s->client_received_element_count) { /* more to come */ return; } - if (NULL == s->cadet) + if (NULL == s->channel) { /* no Alice waiting for this request, wait for Alice */ return; @@ -1298,50 +1121,28 @@ GSS_handle_bob_client_message_multipart (void *cls, /** - * Handler for Bob's a client request message. Bob is in the response - * role, keep the values + session and waiting for a matching session - * or process a waiting request from Alice. + * Handler for Bob's a client request message. Check @a msg is + * well-formed. * - * @param cls closure - * @param client identification of the client - * @param message the actual message + * @param cls identification of the client + * @param msg the actual message + * @return #GNUNET_OK if @a msg is well-formed */ -static void -GSS_handle_bob_client_message (void *cls, - struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader *message) +static int +check_bob_client_message (void *cls, + const struct BobComputationMessage *msg) { - const struct BobComputationMessage *msg; - struct BobServiceSession *s; - struct CadetIncomingSession *in; + struct BobServiceSession *s = cls; uint32_t contained_count; uint32_t total_count; - const struct GNUNET_SCALARPRODUCT_Element *elements; - uint32_t i; - struct GNUNET_SET_Element set_elem; - struct GNUNET_SCALARPRODUCT_Element *elem; uint16_t msize; - s = GNUNET_SERVER_client_get_user_context (client, - struct BobServiceSession); - if (NULL != s) + if (GNUNET_SCALARPRODUCT_STATUS_INIT != s->status) { - /* only one concurrent session per client connection allowed, - simplifies logic a lot... */ GNUNET_break (0); - GNUNET_SERVER_receive_done (client, - GNUNET_SYSERR); - return; - } - msize = ntohs (message->size); - if (msize < sizeof (struct BobComputationMessage)) - { - GNUNET_break (0); - GNUNET_SERVER_receive_done (client, - GNUNET_SYSERR); - return; + return GNUNET_SYSERR; } - msg = (const struct BobComputationMessage *) message; + msize = ntohs (msg->header.size); total_count = ntohl (msg->element_count_total); contained_count = ntohl (msg->element_count_contained); if ( (0 == total_count) || @@ -1351,41 +1152,62 @@ GSS_handle_bob_client_message (void *cls, contained_count * sizeof (struct GNUNET_SCALARPRODUCT_Element))) ) { GNUNET_break_op (0); - GNUNET_SERVER_receive_done (client, - GNUNET_SYSERR); - return; - } - if (NULL != find_matching_client_session (&msg->session_key)) - { - GNUNET_break (0); - GNUNET_SERVER_receive_done (client, - GNUNET_SYSERR); - return; + return GNUNET_SYSERR; } + return GNUNET_OK; +} + + +/** + * Handler for Bob's a client request message. Bob is in the response + * role, keep the values + session and waiting for a matching session + * or process a waiting request from Alice. + * + * @param cls identification of the client + * @param msg the actual message + */ +static void +handle_bob_client_message (void *cls, + const struct BobComputationMessage *msg) +{ + struct BobServiceSession *s = cls; + struct GNUNET_MQ_MessageHandler cadet_handlers[] = { + GNUNET_MQ_hd_fixed_size (alices_computation_request, + GNUNET_MESSAGE_TYPE_SCALARPRODUCT_SESSION_INITIALIZATION, + struct ServiceRequestMessage, + NULL), + GNUNET_MQ_hd_var_size (alices_cryptodata_message, + GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ALICE_CRYPTODATA, + struct AliceCryptodataMessage, + NULL), + GNUNET_MQ_handler_end () + }; + uint32_t contained_count; + uint32_t total_count; + const struct GNUNET_SCALARPRODUCT_Element *elements; + struct GNUNET_SET_Element set_elem; + struct GNUNET_SCALARPRODUCT_Element *elem; + + total_count = ntohl (msg->element_count_total); + contained_count = ntohl (msg->element_count_contained); - s = GNUNET_new (struct BobServiceSession); s->status = GNUNET_SCALARPRODUCT_STATUS_ACTIVE; - s->client = client; - s->client_mq = GNUNET_MQ_queue_for_server_client (client); s->total = total_count; s->client_received_element_count = contained_count; s->session_id = msg->session_key; - GNUNET_break (GNUNET_YES == - GNUNET_CONTAINER_multihashmap_put (client_sessions, - &s->session_id, - s, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); elements = (const struct GNUNET_SCALARPRODUCT_Element *) &msg[1]; - s->intersected_elements = GNUNET_CONTAINER_multihashmap_create (s->total, - GNUNET_YES); - s->intersection_set = GNUNET_SET_create (cfg, - GNUNET_SET_OPERATION_INTERSECTION); - for (i = 0; i < contained_count; i++) + s->intersected_elements + = GNUNET_CONTAINER_multihashmap_create (s->total, + GNUNET_YES); + s->intersection_set + = GNUNET_SET_create (cfg, + GNUNET_SET_OPERATION_INTERSECTION); + for (uint32_t i = 0; i < contained_count; i++) { if (0 == GNUNET_ntohll (elements[i].value)) continue; elem = GNUNET_new (struct GNUNET_SCALARPRODUCT_Element); - memcpy (elem, + GNUNET_memcpy (elem, &elements[i], sizeof (struct GNUNET_SCALARPRODUCT_Element)); if (GNUNET_SYSERR == @@ -1406,26 +1228,21 @@ GSS_handle_bob_client_message (void *cls, NULL, NULL); s->used_element_count++; } - GNUNET_SERVER_client_set_user_context (client, - s); - GNUNET_SERVER_receive_done (client, - GNUNET_YES); - if (s->total != s->client_received_element_count) + GNUNET_SERVICE_client_continue (s->client); + /* We're ready, open the port */ + s->port = GNUNET_CADET_open_port (my_cadet, + &msg->session_key, + &cb_channel_incoming, + s, + NULL, + &cb_channel_destruction, + cadet_handlers); + if (NULL == s->port) { - /* multipart msg */ - return; - } - in = find_matching_cadet_session (&s->session_id); - if (NULL == in) - { - /* nothing yet, wait for Alice */ + GNUNET_break (0); + GNUNET_SERVICE_client_drop (s->client); return; } - GNUNET_assert (NULL == in->s); - /* pair them up */ - in->s = s; - s->cadet = in; - start_intersection (s); } @@ -1445,10 +1262,30 @@ shutdown_task (void *cls) GNUNET_CADET_disconnect (my_cadet); my_cadet = NULL; } - GNUNET_CONTAINER_multihashmap_destroy (client_sessions); - client_sessions = NULL; - GNUNET_CONTAINER_multihashmap_destroy (cadet_sessions); - cadet_sessions = NULL; +} + + +/** + * A client connected. + * + * Setup the associated data structure. + * + * @param cls closure, NULL + * @param client identification of the client + * @param mq message queue to communicate with @a client + * @return our `struct BobServiceSession` + */ +static void * +client_connect_cb (void *cls, + struct GNUNET_SERVICE_Client *client, + struct GNUNET_MQ_Handle *mq) +{ + struct BobServiceSession *s; + + s = GNUNET_new (struct BobServiceSession); + s->client = client; + s->client_mq = mq; + return s; } @@ -1460,21 +1297,17 @@ shutdown_task (void *cls) * * @param cls closure, NULL * @param client identification of the client + * @param app_cls our `struct BobServiceSession` */ static void -handle_client_disconnect (void *cls, - struct GNUNET_SERVER_Client *client) +client_disconnect_cb (void *cls, + struct GNUNET_SERVICE_Client *client, + void *app_cls) { - struct BobServiceSession *s; + struct BobServiceSession *s = app_cls; - if (NULL == client) - return; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client disconnected from us.\n"); - s = GNUNET_SERVER_client_get_user_context (client, - struct BobServiceSession); - if (NULL == s) - return; s->client = NULL; destroy_service_session (s); } @@ -1484,37 +1317,14 @@ handle_client_disconnect (void *cls, * Initialization of the program and message handlers * * @param cls closure - * @param server the initialized server * @param c configuration to use + * @param service the initialized service */ static void run (void *cls, - struct GNUNET_SERVER_Handle *server, - const struct GNUNET_CONFIGURATION_Handle *c) + const struct GNUNET_CONFIGURATION_Handle *c, + struct GNUNET_SERVICE_Handle *service) { - static const struct GNUNET_SERVER_MessageHandler server_handlers[] = { - { &GSS_handle_bob_client_message, NULL, - GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_TO_BOB, - 0}, - { &GSS_handle_bob_client_message_multipart, NULL, - GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_MUTLIPART_BOB, - 0}, - { NULL, NULL, 0, 0} - }; - static const struct GNUNET_CADET_MessageHandler cadet_handlers[] = { - { &handle_alices_computation_request, - GNUNET_MESSAGE_TYPE_SCALARPRODUCT_SESSION_INITIALIZATION, - sizeof (struct ServiceRequestMessage) }, - { &handle_alices_cryptodata_message, - GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ALICE_CRYPTODATA, - 0}, - { NULL, 0, 0} - }; - static const uint32_t ports[] = { - GNUNET_APPLICATION_TYPE_SCALARPRODUCT, - 0 - }; - cfg = c; /* offset has to be sufficiently small to allow computation of: @@ -1526,20 +1336,9 @@ run (void *cls, GNUNET_CRYPTO_paillier_create (&my_pubkey, &my_privkey); - GNUNET_SERVER_add_handlers (server, - server_handlers); - GNUNET_SERVER_disconnect_notify (server, - &handle_client_disconnect, - NULL); - client_sessions = GNUNET_CONTAINER_multihashmap_create (128, - GNUNET_YES); - cadet_sessions = GNUNET_CONTAINER_multihashmap_create (128, - GNUNET_YES); - my_cadet = GNUNET_CADET_connect (cfg, NULL, - &cb_channel_incoming, - &cb_channel_destruction, - cadet_handlers, - ports); + my_cadet = GNUNET_CADET_connect (cfg); + GNUNET_SCHEDULER_add_shutdown (&shutdown_task, + NULL); if (NULL == my_cadet) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -1547,27 +1346,28 @@ run (void *cls, GNUNET_SCHEDULER_shutdown (); return; } - GNUNET_SCHEDULER_add_shutdown (&shutdown_task, - NULL); } /** - * The main function for the scalarproduct service. - * - * @param argc number of arguments from the command line - * @param argv command line arguments - * @return 0 ok, 1 on error + * Define "main" method using service macro. */ -int -main (int argc, - char *const *argv) -{ - return (GNUNET_OK == - GNUNET_SERVICE_run (argc, argv, - "scalarproduct-bob", - GNUNET_SERVICE_OPTION_NONE, - &run, NULL)) ? 0 : 1; -} +GNUNET_SERVICE_MAIN +("scalarproduct-bob", + GNUNET_SERVICE_OPTION_NONE, + &run, + &client_connect_cb, + &client_disconnect_cb, + NULL, + GNUNET_MQ_hd_var_size (bob_client_message, + GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_TO_BOB, + struct BobComputationMessage, + NULL), +GNUNET_MQ_hd_var_size (bob_client_message_multipart, + GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_MULTIPART_BOB, + struct ComputationBobCryptodataMultipartMessage, + NULL), + GNUNET_MQ_handler_end ()); + /* end of gnunet-service-scalarproduct_bob.c */