/** * @brief Get the channel of a peer. If not existing, create. * * @param peer the peer id * @return the #GNUNET_CADET_Channel used to send data to @a peer */ struct GNUNET_CADET_Channel * get_channel (const struct GNUNET_PeerIdentity *peer) { struct PeerContext *peer_ctx; struct GNUNET_HashCode port; peer_ctx = get_peer_ctx (peer); if (NULL == peer_ctx->send_channel) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Trying to establish channel to peer %s\n", GNUNET_i2s (peer)); GNUNET_CRYPTO_hash (GNUNET_APPLICATION_PORT_RPS, strlen (GNUNET_APPLICATION_PORT_RPS), &port); peer_ctx->send_channel = GNUNET_CADET_channel_create (cadet_handle, peer_ctx->send_channel_flags, /* context */ peer, &port, GNUNET_CADET_OPTION_RELIABLE); } GNUNET_assert (NULL != peer_ctx->send_channel); return peer_ctx->send_channel; }
/** * Connect to other client and send data * * @param cls Closue (unused). * @param tc TaskContext. */ static void do_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_PeerIdentity id; if (NULL != tc && 0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason)) return; GNUNET_TESTING_peer_get_identity (me, &id); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CONNECT BY PORT\n"); ch = GNUNET_CADET_channel_create (cadet_peer_1, NULL, &id, 1, GNUNET_CADET_OPTION_DEFAULT); mth = GNUNET_CADET_notify_transmit_ready (ch, GNUNET_NO, GNUNET_TIME_UNIT_FOREVER_REL, sizeof (struct GNUNET_MessageHeader), &do_send, NULL); }
/** * Function to handle call request from the client * * @param cls the `struct Line` the message is about * @param msg the message from the client */ static void handle_client_call_message (void *cls, const struct ClientCallMessage *msg) { struct Line *line = cls; struct Channel *ch; struct GNUNET_MQ_Envelope *e; struct CadetPhoneRingMessage *ring; struct CadetPhoneRingInfoPS rs; line->line_port = msg->line_port; 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 = msg->target; rs.expiration_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_relative_to_absolute (RING_TIMEOUT)); ch = GNUNET_new (struct Channel); ch->line = line; GNUNET_CONTAINER_DLL_insert (line->channel_head, line->channel_tail, ch); ch->status = CS_CALLER_CALLING; ch->channel = GNUNET_CADET_channel_create (cadet, ch, &msg->target, &msg->line_port, GNUNET_CADET_OPTION_RELIABLE); ch->mq = GNUNET_CADET_mq_create (ch->channel); e = GNUNET_MQ_msg (ring, GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_RING); GNUNET_CRYPTO_ecdsa_key_get_public (&msg->caller_id, &ring->caller_id); ring->expiration_time = rs.expiration_time; GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdsa_sign (&msg->caller_id, &rs.purpose, &ring->signature)); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending RING message via CADET\n"); GNUNET_MQ_send (ch->mq, e); GNUNET_SERVICE_client_continue (line->client); }
/** * START THE TESTCASE ITSELF, AS WE ARE CONNECTED TO THE CADET SERVICES. * * Testcase continues when the root receives confirmation of connected peers, * on callback function ch. * * @param cls Closure (unused). */ static void do_test (void *cls) { enum GNUNET_CADET_ChannelOption flags; test_task = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "do_test\n"); if (NULL != disconnect_task) { GNUNET_SCHEDULER_cancel (disconnect_task); disconnect_task = NULL; } flags = GNUNET_CADET_OPTION_DEFAULT; if (SPEED_REL == test) { test = SPEED; flags |= GNUNET_CADET_OPTION_RELIABLE; } ch = GNUNET_CADET_channel_create (h1, NULL, p_id[1], &port, flags); disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME, &gather_stats_and_exit, (void *) __LINE__); if (KEEPALIVE == test) return; /* Don't send any data. */ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending data initializer...\n"); data_received = 0; data_sent = 0; ack_received = 0; ack_sent = 0; th = GNUNET_CADET_notify_transmit_ready (ch, GNUNET_NO, GNUNET_TIME_UNIT_FOREVER_REL, size_payload + 1000, &tmt_rdy, (void *) 0L); }