/** * Called with any sensor reading messages received from CADET. * * Each time the function must call #GNUNET_CADET_receive_done on the channel * in order to receive the next message. This doesn't need to be immediate: * can be delayed if some processing is done on the message. * * @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 channel. * @param message The actual message. * @return #GNUNET_OK to keep the channel open, * #GNUNET_SYSERR to close it (signal serious error). */ static int handle_sensor_reading (void *cls, struct GNUNET_CADET_Channel *channel, void **channel_ctx, const struct GNUNET_MessageHeader *message) { struct ClientPeerContext *cp = *channel_ctx; struct ClientSensorReading *reading; reading = parse_reading_message (message, sensors); if (NULL == reading) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Received an invalid sensor reading from peer `%s'.\n", GNUNET_i2s (&cp->peerid)); return GNUNET_SYSERR; } GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Received a sensor reading from peer `%s':\n" "# Sensor name: `%s'\n" "# Timestamp: %" PRIu64 "\n" "# Value size: %" PRIu64 ".\n", GNUNET_i2s (&cp->peerid), reading->sensor->name, reading->timestamp, reading->value_size); GNUNET_PEERSTORE_store (peerstore, values_subsystem, &cp->peerid, reading->sensor->name, reading->value, reading->value_size, GNUNET_TIME_UNIT_FOREVER_ABS, GNUNET_PEERSTORE_STOREOPTION_MULTIPLE, NULL, NULL); GNUNET_free (reading->value); GNUNET_free (reading); GNUNET_CADET_receive_done (channel); return GNUNET_OK; }
/** * Function to handle a ring message incoming over cadet * * @param cls closure, NULL * @param channel the channel over which the message arrived * @param channel_ctx the channel context, can be NULL * or point to the `struct Channel` * @param message the incoming message * @return #GNUNET_OK */ static int handle_cadet_ring_message (void *cls, struct GNUNET_CADET_Channel *channel, void **channel_ctx, const struct GNUNET_MessageHeader *message) { struct Channel *ch = *channel_ctx; struct Line *line = ch->line; const struct CadetPhoneRingMessage *msg; struct GNUNET_MQ_Envelope *env; struct ClientPhoneRingMessage *cring; struct CadetPhoneRingInfoPS rs; msg = (const struct CadetPhoneRingMessage *) message; rs.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CONVERSATION_RING); rs.purpose.size = htonl (sizeof (struct CadetPhoneRingInfoPS)); rs.line_port = line->line_port; rs.target_peer = my_identity; rs.expiration_time = msg->expiration_time; if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_CONVERSATION_RING, &rs.purpose, &msg->signature, &msg->caller_id)) { GNUNET_break_op (0); return GNUNET_SYSERR; } if (0 == GNUNET_TIME_absolute_get_remaining (GNUNET_TIME_absolute_ntoh (msg->expiration_time)).rel_value_us) { /* ancient call, replay? */ GNUNET_break_op (0); /* Note that our reliance on time here is awkward; better would be to use a more complex challenge-response protocol against replay attacks. Left for future work ;-). */ return GNUNET_SYSERR; } if (CS_CALLEE_INIT != ch->status) { GNUNET_break_op (0); return GNUNET_SYSERR; } GNUNET_CADET_receive_done (channel); ch->status = CS_CALLEE_RINGING; env = GNUNET_MQ_msg (cring, GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_RING); cring->cid = ch->cid; cring->caller_id = msg->caller_id; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending RING message to client. CID is %u\n", (unsigned int) ch->cid); GNUNET_MQ_send (line->mq, env); return GNUNET_OK; }
/** * Function to handle a resume message incoming over cadet * * @param cls closure, NULL * @param channel the channel over which the message arrived * @param channel_ctx the channel context, can be NULL * or point to the `struct Channel` * @param message the incoming message * @return #GNUNET_OK */ static int handle_cadet_resume_message (void *cls, struct GNUNET_CADET_Channel *channel, void **channel_ctx, const struct GNUNET_MessageHeader *message) { struct Channel *ch = *channel_ctx; struct Line *line; struct GNUNET_MQ_Envelope *env; struct ClientPhoneResumeMessage *resume; if (NULL == ch) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "RESUME message received for non-existing line, dropping channel.\n"); return GNUNET_SYSERR; } line = ch->line; GNUNET_CADET_receive_done (channel); if (GNUNET_YES != ch->suspended_remote) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "RESUME message received for non-suspended channel, dropping channel.\n"); return GNUNET_SYSERR; } switch (ch->status) { case CS_CALLEE_INIT: GNUNET_break (0); break; case CS_CALLEE_RINGING: GNUNET_break (0); break; case CS_CALLEE_CONNECTED: ch->suspended_remote = GNUNET_NO; break; case CS_CALLEE_SHUTDOWN: return GNUNET_OK; case CS_CALLER_CALLING: GNUNET_break (0); break; case CS_CALLER_CONNECTED: ch->suspended_remote = GNUNET_NO; break; case CS_CALLER_SHUTDOWN: return GNUNET_OK; } env = GNUNET_MQ_msg (resume, GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_RESUME); resume->cid = ch->cid; GNUNET_MQ_send (line->mq, env); return GNUNET_OK; }
/** * Called with any anomaly report received from a peer. * * Each time the function must call #GNUNET_CADET_receive_done on the channel * in order to receive the next message. This doesn't need to be immediate: * can be delayed if some processing is done on the message. * * @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 channel. * @param message The actual message. * @return #GNUNET_OK to keep the channel open, * #GNUNET_SYSERR to close it (signal serious error). */ static int handle_anomaly_report (void *cls, struct GNUNET_CADET_Channel *channel, void **channel_ctx, const struct GNUNET_MessageHeader *message) { struct ClientPeerContext *cp = *channel_ctx; struct GNUNET_SENSOR_crypto_pow_block *report_block; struct GNUNET_SENSOR_AnomalyReportMessage *anomaly_msg; struct GNUNET_SENSOR_SensorInfo *sensor; struct GNUNET_SENSOR_DashboardAnomalyEntry *anomaly_entry; struct GNUNET_TIME_Absolute expiry; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received an anomaly report message from peer `%s'.\n", GNUNET_i2s (&cp->peerid)); report_block = (struct GNUNET_SENSOR_crypto_pow_block *) &message[1]; if (sizeof (struct GNUNET_SENSOR_AnomalyReportMessage) != GNUNET_SENSOR_crypto_verify_pow_sign (report_block, pow_matching_bits, &cp->peerid.public_key, (void **) &anomaly_msg)) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Received invalid anomaly report from peer `%s'.\n", GNUNET_i2s (&cp->peerid)); GNUNET_break_op (0); return GNUNET_SYSERR; } sensor = GNUNET_CONTAINER_multihashmap_get (sensors, &anomaly_msg->sensorname_hash); if (NULL == sensor) { GNUNET_break_op (0); return GNUNET_SYSERR; } anomaly_entry = GNUNET_new (struct GNUNET_SENSOR_DashboardAnomalyEntry); anomaly_entry->anomalous = ntohs (anomaly_msg->anomalous); anomaly_entry->anomalous_neighbors = anomaly_msg->anomalous_neighbors; expiry = (GNUNET_YES == anomaly_entry->anomalous) ? GNUNET_TIME_UNIT_FOREVER_ABS : GNUNET_TIME_absolute_get (); GNUNET_PEERSTORE_store (peerstore, anomalies_subsystem, &cp->peerid, sensor->name, anomaly_entry, sizeof (struct GNUNET_SENSOR_DashboardAnomalyEntry), expiry, GNUNET_PEERSTORE_STOREOPTION_REPLACE, NULL, NULL); GNUNET_free (anomaly_entry); GNUNET_CADET_receive_done (channel); return GNUNET_OK; }
/** * Function is called whenever a message is received. * * @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 channel * @param message the actual message * * @return GNUNET_OK to keep the connection open, * GNUNET_SYSERR to close it (signal serious error) */ static int data_callback (void *cls, struct GNUNET_CADET_Channel *channel, void **channel_ctx, const struct GNUNET_MessageHeader *message) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Data callback! Shutting down.\n"); got_data = GNUNET_YES; if (NULL != shutdown_task) GNUNET_SCHEDULER_cancel (shutdown_task); shutdown_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &do_shutdown, NULL); GNUNET_CADET_receive_done (channel); return GNUNET_OK; }
/** * Function to handle a suspend message incoming over cadet * * @param cls closure, NULL * @param channel the channel over which the message arrived * @param channel_ctx the channel context, can be NULL * or point to the `struct Channel` * @param message the incoming message * @return #GNUNET_OK */ static int handle_cadet_suspend_message (void *cls, struct GNUNET_CADET_Channel *channel, void **channel_ctx, const struct GNUNET_MessageHeader *message) { struct Channel *ch = *channel_ctx; struct Line *line = ch->line; struct GNUNET_MQ_Envelope *env; struct ClientPhoneSuspendMessage *suspend; GNUNET_CADET_receive_done (channel); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Suspending channel CID: %u\n", ch->cid); switch (ch->status) { case CS_CALLEE_INIT: GNUNET_break_op (0); break; case CS_CALLEE_RINGING: GNUNET_break_op (0); break; case CS_CALLEE_CONNECTED: ch->suspended_remote = GNUNET_YES; break; case CS_CALLEE_SHUTDOWN: return GNUNET_OK; case CS_CALLER_CALLING: GNUNET_break_op (0); break; case CS_CALLER_CONNECTED: ch->suspended_remote = GNUNET_YES; break; case CS_CALLER_SHUTDOWN: return GNUNET_OK; } env = GNUNET_MQ_msg (suspend, GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_SUSPEND); suspend->cid = ch->cid; GNUNET_MQ_send (line->mq, env); return GNUNET_OK; }
/** * Function to handle a pickup message incoming over cadet * * @param cls closure, NULL * @param channel the channel over which the message arrived * @param channel_ctx the channel context, can be NULL * or point to the `struct Channel` * @param message the incoming message * @return #GNUNET_OK if message was OK, * #GNUNET_SYSERR if message violated the protocol */ static int handle_cadet_pickup_message (void *cls, struct GNUNET_CADET_Channel *channel, void **channel_ctx, const struct GNUNET_MessageHeader *message) { struct Channel *ch = *channel_ctx; struct Line *line = ch->line; struct GNUNET_MQ_Envelope *env; struct ClientPhonePickedupMessage *pick; GNUNET_CADET_receive_done (channel); switch (ch->status) { case CS_CALLEE_INIT: case CS_CALLEE_RINGING: case CS_CALLEE_CONNECTED: GNUNET_break_op (0); destroy_line_cadet_channels (ch); return GNUNET_SYSERR; case CS_CALLEE_SHUTDOWN: GNUNET_break_op (0); destroy_line_cadet_channels (ch); return GNUNET_SYSERR; case CS_CALLER_CALLING: ch->status = CS_CALLER_CONNECTED; break; case CS_CALLER_CONNECTED: GNUNET_break_op (0); return GNUNET_OK; case CS_CALLER_SHUTDOWN: GNUNET_break_op (0); mq_done_finish_caller_shutdown (ch); return GNUNET_SYSERR; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending PICKED UP message to client\n"); env = GNUNET_MQ_msg (pick, GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_PICKED_UP); pick->cid = ch->cid; GNUNET_MQ_send (line->mq, env); return GNUNET_OK; }
/** * Function to handle a hangup message incoming over cadet * * @param cls closure, NULL * @param channel the channel over which the message arrived * @param channel_ctx the channel context, can be NULL * or point to the `struct Channel` * @param message the incoming message * @return #GNUNET_OK */ static int handle_cadet_hangup_message (void *cls, struct GNUNET_CADET_Channel *channel, void **channel_ctx, const struct GNUNET_MessageHeader *message) { struct Channel *ch = *channel_ctx; struct Line *line = ch->line; struct GNUNET_MQ_Envelope *env; struct ClientPhoneHangupMessage *hup; enum ChannelStatus status; uint32_t cid; GNUNET_CADET_receive_done (channel); cid = ch->cid; status = ch->status; destroy_line_cadet_channels (ch); switch (status) { case CS_CALLEE_INIT: GNUNET_break_op (0); return GNUNET_OK; case CS_CALLEE_RINGING: case CS_CALLEE_CONNECTED: break; case CS_CALLEE_SHUTDOWN: return GNUNET_OK; case CS_CALLER_CALLING: case CS_CALLER_CONNECTED: break; case CS_CALLER_SHUTDOWN: return GNUNET_OK; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending HANG UP message to client\n"); env = GNUNET_MQ_msg (hup, GNUNET_MESSAGE_TYPE_CONVERSATION_CS_PHONE_HANG_UP); hup->cid = cid; GNUNET_MQ_send (line->mq, env); return GNUNET_OK; }
/** * Called with any sensor list request received. * * Each time the function must call #GNUNET_CADET_receive_done on the channel * in order to receive the next message. This doesn't need to be immediate: * can be delayed if some processing is done on the message. * * @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 channel. * @param message The actual message. * @return #GNUNET_OK to keep the channel open, * #GNUNET_SYSERR to close it (signal serious error). */ static int handle_sensor_list_req (void *cls, struct GNUNET_CADET_Channel *channel, void **channel_ctx, const struct GNUNET_MessageHeader *message) { struct ClientPeerContext *cp = *channel_ctx; struct GNUNET_MessageHeader *end_msg; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received a sensor list request from peer `%s'.\n", GNUNET_i2s (&cp->peerid)); GNUNET_CONTAINER_multihashmap_iterate (sensors, &send_sensor_brief, cp); end_msg = GNUNET_new (struct GNUNET_MessageHeader); end_msg->size = htons (sizeof (struct GNUNET_MessageHeader)); end_msg->type = htons (GNUNET_MESSAGE_TYPE_SENSOR_END); queue_msg (end_msg, cp); GNUNET_CADET_receive_done (channel); return GNUNET_OK; }
/** * Called with any request for full sensor information. * * Each time the function must call #GNUNET_CADET_receive_done on the channel * in order to receive the next message. This doesn't need to be immediate: * can be delayed if some processing is done on the message. * * @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 channel. * @param message The actual message. * @return #GNUNET_OK to keep the channel open, * #GNUNET_SYSERR to close it (signal serious error). */ static int handle_sensor_full_req (void *cls, struct GNUNET_CADET_Channel *channel, void **channel_ctx, const struct GNUNET_MessageHeader *message) { struct ClientPeerContext *cp = *channel_ctx; struct GNUNET_SENSOR_SensorBriefMessage *sbm = NULL; struct GNUNET_SENSOR_SensorFullMessage *sfm; uint16_t msg_size; uint16_t sensorname_size; msg_size = ntohs (message->size); /* parse & error check */ if (msg_size > sizeof (struct GNUNET_SENSOR_SensorBriefMessage)) { sbm = (struct GNUNET_SENSOR_SensorBriefMessage *) message; sensorname_size = ntohs (sbm->name_size); if (msg_size != sizeof (struct GNUNET_SENSOR_SensorBriefMessage) + sensorname_size) sbm = NULL; } if (NULL == sbm) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Received an invalid full sensor request from peer `%s'.\n", GNUNET_i2s (&cp->peerid)); return GNUNET_SYSERR; } /* Create and send msg with full sensor info */ sfm = create_full_sensor_msg ((char *) &sbm[1]); if (NULL == sfm) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error creating full sensor info msg for sensor `%s'.\n", (char *) &sbm[1]); return GNUNET_SYSERR; } queue_msg ((struct GNUNET_MessageHeader *) sfm, cp); GNUNET_CADET_receive_done (channel); return GNUNET_OK; }
/** * Function to handle an audio message incoming over cadet * * @param cls closure, NULL * @param channel the channel over which the message arrived * @param channel_ctx the channel context, can be NULL * or point to the `struct Channel` * @param message the incoming message * @return #GNUNET_OK */ static int handle_cadet_audio_message (void *cls, struct GNUNET_CADET_Channel *channel, void **channel_ctx, const struct GNUNET_MessageHeader *message) { struct Channel *ch = *channel_ctx; const struct CadetAudioMessage *msg; size_t msize = ntohs (message->size) - sizeof (struct CadetAudioMessage); struct GNUNET_MQ_Envelope *env; struct ClientAudioMessage *cam; msg = (const struct CadetAudioMessage *) message; GNUNET_CADET_receive_done (channel); if ( (GNUNET_YES == ch->suspended_local) || (GNUNET_YES == ch->suspended_remote) ) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received %u bytes of AUDIO data on suspended channel CID %u; dropping\n", (unsigned int) msize, ch->cid); return GNUNET_OK; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Forwarding %u bytes of AUDIO data to client CID %u\n", (unsigned int) msize, ch->cid); env = GNUNET_MQ_msg_extra (cam, msize, GNUNET_MESSAGE_TYPE_CONVERSATION_CS_AUDIO); cam->cid = ch->cid; GNUNET_memcpy (&cam[1], &msg[1], msize); GNUNET_MQ_send (ch->line->mq, env); return GNUNET_OK; }
/** * Callback for set operation results. Called for each element * that needs to be removed from the result set. * * @param cls closure with the `struct BobServiceSession` * @param element a result element, only valid if status is #GNUNET_SET_STATUS_OK * @param status what has happened with the set intersection? */ static void cb_intersection_element_removed (void *cls, const struct GNUNET_SET_Element *element, enum GNUNET_SET_Status status) { struct BobServiceSession *s = cls; struct GNUNET_SCALARPRODUCT_Element *se; switch (status) { case GNUNET_SET_STATUS_OK: /* this element has been removed from the set */ se = GNUNET_CONTAINER_multihashmap_get (s->intersected_elements, element->data); GNUNET_assert (NULL != se); LOG (GNUNET_ERROR_TYPE_DEBUG, "Removed element with key %s and value %lld\n", GNUNET_h2s (&se->key), (long long) GNUNET_ntohll (se->value)); GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (s->intersected_elements, element->data, se)); GNUNET_free (se); return; case GNUNET_SET_STATUS_DONE: s->intersection_op = NULL; GNUNET_break (NULL == s->intersection_set); GNUNET_CADET_receive_done (s->cadet->channel); LOG (GNUNET_ERROR_TYPE_DEBUG, "Finished intersection, %d items remain\n", GNUNET_CONTAINER_multihashmap_size (s->intersected_elements)); if (s->client_received_element_count == GNUNET_CONTAINER_multihashmap_size (s->intersected_elements)) { /* CADET transmission from Alice is also already done, start with our own reply */ transmit_bobs_cryptodata_message (s); } return; case GNUNET_SET_STATUS_HALF_DONE: /* unexpected for intersection */ GNUNET_break (0); return; case GNUNET_SET_STATUS_FAILURE: /* unhandled status code */ LOG (GNUNET_ERROR_TYPE_DEBUG, "Set intersection failed!\n"); s->intersection_op = NULL; if (NULL != s->intersection_set) { GNUNET_SET_destroy (s->intersection_set); s->intersection_set = NULL; } s->status = GNUNET_SCALARPRODUCT_STATUS_FAILURE; prepare_client_end_notification (s); return; default: GNUNET_break (0); return; } }
/** * Handle 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 * @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) { struct CadetIncomingSession *in = *channel_ctx; struct BobServiceSession *s; const struct EccAliceCryptodataMessage *msg; const struct GNUNET_CRYPTO_EccPoint *payload; uint32_t contained_elements; size_t msg_length; uint16_t msize; unsigned int max; unsigned int i; const struct MpiElement *b_i; gcry_mpi_point_t tmp; gcry_mpi_point_t g_i; gcry_mpi_point_t h_i; gcry_mpi_point_t g_i_b_i; gcry_mpi_point_t h_i_b_i; /* sanity checks */ if (NULL == in) { GNUNET_break_op (0); return GNUNET_SYSERR; } s = in->s; if (NULL == s) { GNUNET_break_op (0); return GNUNET_SYSERR; } /* sort our vector for the computation */ if (NULL == s->sorted_elements) { s->sorted_elements = GNUNET_malloc (GNUNET_CONTAINER_multihashmap_size (s->intersected_elements) * sizeof (struct MpiElement)); s->used_element_count = 0; GNUNET_CONTAINER_multihashmap_iterate (s->intersected_elements, ©_element_cb, s); qsort (s->sorted_elements, s->used_element_count, sizeof (struct MpiElement), &element_cmp); } /* parse message */ msize = ntohs (message->size); if (msize <= sizeof (struct EccAliceCryptodataMessage)) { GNUNET_break_op (0); return GNUNET_SYSERR; } msg = (const struct EccAliceCryptodataMessage *) message; 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); msg_length = sizeof (struct EccAliceCryptodataMessage) + contained_elements * sizeof (struct GNUNET_CRYPTO_EccPoint) * 2; if ( (msize != msg_length) || (0 == contained_elements) || (contained_elements > UINT16_MAX) || (max < contained_elements + s->cadet_received_element_count) ) { GNUNET_break_op (0); return GNUNET_SYSERR; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received %u crypto values from Alice\n", (unsigned int) contained_elements); payload = (const struct GNUNET_CRYPTO_EccPoint *) &msg[1]; for (i=0;i<contained_elements;i++) { b_i = &s->sorted_elements[i + s->cadet_received_element_count]; g_i = GNUNET_CRYPTO_ecc_bin_to_point (edc, &payload[i * 2]); g_i_b_i = GNUNET_CRYPTO_ecc_pmul_mpi (edc, g_i, b_i->value); gcry_mpi_point_release (g_i); h_i = GNUNET_CRYPTO_ecc_bin_to_point (edc, &payload[i * 2 + 1]); h_i_b_i = GNUNET_CRYPTO_ecc_pmul_mpi (edc, h_i, b_i->value); gcry_mpi_point_release (h_i); if (0 == i + s->cadet_received_element_count) { /* first iteration, nothing to add */ s->prod_g_i_b_i = g_i_b_i; s->prod_h_i_b_i = h_i_b_i; } else { /* further iterations, cummulate resulting value */ tmp = GNUNET_CRYPTO_ecc_add (edc, s->prod_g_i_b_i, g_i_b_i); gcry_mpi_point_release (s->prod_g_i_b_i); gcry_mpi_point_release (g_i_b_i); s->prod_g_i_b_i = tmp; tmp = GNUNET_CRYPTO_ecc_add (edc, s->prod_h_i_b_i, h_i_b_i); gcry_mpi_point_release (s->prod_h_i_b_i); gcry_mpi_point_release (h_i_b_i); s->prod_h_i_b_i = tmp; } } s->cadet_received_element_count += contained_elements; if ( (s->cadet_received_element_count == max) && (NULL == s->intersection_op) ) { /* intersection has finished also on our side, and we got the full set, so we can proceed with the CADET response(s) */ transmit_bobs_cryptodata_message (s); } GNUNET_CADET_receive_done (s->cadet->channel); return GNUNET_OK; }
/** * Function is called whenever a message is received. * * @param cls closure (set from GNUNET_CADET_connect, peer number) * @param channel connection to the other end * @param channel_ctx place to store local state associated with the channel * @param message the actual message * @return GNUNET_OK to keep the connection open, * GNUNET_SYSERR to close it (signal serious error) */ int data_callback (void *cls, struct GNUNET_CADET_Channel *channel, void **channel_ctx, const struct GNUNET_MessageHeader *message) { struct GNUNET_CADET_TransmitHandle **pth; long client = (long) cls; long expected_target_client; uint32_t *data; uint32_t payload; unsigned int counter; ok++; counter = get_expected_target () == client ? data_received : ack_received; GNUNET_CADET_receive_done (channel); if ((ok % 10) == 0) { if (NULL != disconnect_task) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, " reschedule timeout\n"); GNUNET_SCHEDULER_cancel (disconnect_task); disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME, &gather_stats_and_exit, (void *) __LINE__); } } switch (client) { case 0L: GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Root client got a message!\n"); GNUNET_assert (channel == ch); pth = &th; break; case 1L: case 4L: GNUNET_assert (client == peers_requested - 1); GNUNET_assert (channel == incoming_ch); pth = &incoming_th; GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Leaf client %ld got a message.\n", client); break; default: GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Client %ld not valid.\n", client); GNUNET_assert (0); } GNUNET_log (GNUNET_ERROR_TYPE_INFO, " ok: (%d/%d)\n", ok, ok_goal); data = (uint32_t *) &message[1]; payload = ntohl (*data); if (payload == counter) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, " payload as expected: %u\n", payload); } else { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, " payload %u, expected: %u\n", payload, counter); } expected_target_client = get_expected_target (); if (GNUNET_NO == initialized) { initialized = GNUNET_YES; start_time = GNUNET_TIME_absolute_get (); if (SPEED == test) { GNUNET_assert (peers_requested - 1 == client); data_job = GNUNET_SCHEDULER_add_now (&data_task, NULL); return GNUNET_OK; } } counter++; if (client == expected_target_client) /* Normally 4 */ { data_received++; GNUNET_log (GNUNET_ERROR_TYPE_INFO, " received data %u\n", data_received); if (SPEED != test || (ok_goal - 2) == ok) { /* Send ACK */ GNUNET_assert (NULL == *pth); *pth = GNUNET_CADET_notify_transmit_ready (channel, GNUNET_NO, GNUNET_TIME_UNIT_FOREVER_REL, size_payload + ack_sent, &tmt_rdy, (void *) client); return GNUNET_OK; } else { if (data_received < TOTAL_PACKETS) return GNUNET_OK; } } else /* Normally 0 */ { if (SPEED_ACK == test || SPEED == test) { ack_received++; GNUNET_log (GNUNET_ERROR_TYPE_INFO, " received ack %u\n", ack_received); /* send more data */ GNUNET_assert (NULL == *pth); *pth = GNUNET_CADET_notify_transmit_ready (channel, GNUNET_NO, GNUNET_TIME_UNIT_FOREVER_REL, size_payload + data_sent, &tmt_rdy, (void *) client); if (ack_received < TOTAL_PACKETS && SPEED != test) return GNUNET_OK; if (ok == 2 && SPEED == test) return GNUNET_OK; show_end_data(); } if (test == P2P_SIGNAL) { if (NULL != incoming_th) { GNUNET_CADET_notify_transmit_ready_cancel (incoming_th); incoming_th = NULL; } GNUNET_CADET_channel_destroy (incoming_ch); incoming_ch = NULL; } else { if (NULL != th) { GNUNET_CADET_notify_transmit_ready_cancel (th); th = NULL; } GNUNET_CADET_channel_destroy (ch); ch = NULL; } } return GNUNET_OK; }