/** * Callback called by notify_transmit_ready; sends DNS replies * to the DNS service. * * @param cls the struct GNUNET_DNS_Handle * @param size number of bytes available in buf * @param buf where to copy the message for transmission * @return number of bytes copied to buf */ static size_t send_response (void *cls, size_t size, void *buf) { struct GNUNET_DNS_Handle *dh = cls; struct ReplyQueueEntry *qe; size_t len; dh->dns_transmit_handle = NULL; if (NULL == buf) { disconnect (dh); dh->reconnect_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &reconnect, dh); return 0; } qe = dh->rq_head; if (NULL == qe) return 0; len = ntohs (qe->msg->size); if (len > size) { dh->dns_transmit_handle = GNUNET_CLIENT_notify_transmit_ready (dh->dns_connection, len, GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_NO, &send_response, dh); return 0; } memcpy (buf, qe->msg, len); GNUNET_CONTAINER_DLL_remove (dh->rq_head, dh->rq_tail, qe); GNUNET_free (qe); if (GNUNET_NO == dh->in_receive) { dh->in_receive = GNUNET_YES; GNUNET_CLIENT_receive (dh->dns_connection, &request_handler, dh, GNUNET_TIME_UNIT_FOREVER_REL); } if (NULL != (qe = dh->rq_head)) { dh->dns_transmit_handle = GNUNET_CLIENT_notify_transmit_ready (dh->dns_connection, ntohs (qe->msg->size), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_NO, &send_response, dh); } return len; }
/** * Try to send messages from list of messages to send * * @param handle the GNS handle */ static void process_pending_messages (struct GNUNET_GNS_Handle *handle) { struct PendingMessage *p = handle->pending_head; if (NULL == handle->client) return; /* wait for reconnect */ if (NULL != handle->th) return; /* transmission request already pending */ while ((NULL != p) && (p->transmitted == GNUNET_YES)) p = p->next; if (NULL == p) return; /* no messages pending */ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to transmit %u bytes\n", (unsigned int) p->size); handle->th = GNUNET_CLIENT_notify_transmit_ready (handle->client, p->size, GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_NO, &transmit_pending, handle); GNUNET_break (NULL != handle->th); }
/** * Queues a message in send queue of the logger handle * * @param h the logger handle * @param msg the message to queue */ static void queue_message (struct GNUNET_TESTBED_LOGGER_Handle *h, struct GNUNET_MessageHeader *msg) { struct MessageQueue *mq; uint16_t type; uint16_t size; type = ntohs (msg->type); size = ntohs (msg->size); mq = GNUNET_new (struct MessageQueue); mq->msg = msg; LOG (GNUNET_ERROR_TYPE_DEBUG, "Queueing message of type %u, size %u for sending\n", type, ntohs (msg->size)); GNUNET_CONTAINER_DLL_insert_tail (h->mq_head, h->mq_tail, mq); if (NULL == h->th) { h->retry_backoff = GNUNET_TIME_STD_BACKOFF (h->retry_backoff); h->th = GNUNET_CLIENT_notify_transmit_ready (h->client, size, h->retry_backoff, GNUNET_YES, &transmit_ready_notify, h); } }
/** * Send a message. * * @param room handle for the chat room * @param message message to be sent * @param options options for the message * @param receiver use NULL to send to everyone in the room * @param sequence_number where to write the sequence id of the message */ void GNUNET_CHAT_send_message (struct GNUNET_CHAT_Room *room, const char *message, enum GNUNET_CHAT_MsgOptions options, const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *receiver, uint32_t * sequence_number) { size_t msg_size; struct GNUNET_CHAT_SendMessageContext *smc; #if DEBUG_CHAT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending a message\n"); #endif room->sequence_number++; if (NULL != sequence_number) *sequence_number = room->sequence_number; smc = GNUNET_malloc (sizeof (struct GNUNET_CHAT_SendMessageContext)); smc->chat_room = room; smc->message = GNUNET_strdup (message); smc->options = options; smc->receiver = receiver; smc->sequence_number = room->sequence_number; msg_size = strlen (message) + sizeof (struct TransmitRequestMessage); GNUNET_CLIENT_notify_transmit_ready (room->client, msg_size, GNUNET_CONSTANTS_SERVICE_TIMEOUT, GNUNET_YES, &transmit_send_request, smc); }
/** * Check the list of pending requests, send the next * one to the core. * * @param h core handle * @param ignore_currently_down transmit message even if not initialized? */ static void trigger_next_request (struct GNUNET_CORE_Handle *h, int ignore_currently_down) { uint16_t msize; if ((GNUNET_YES == h->currently_down) && (ignore_currently_down == GNUNET_NO)) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Core connection down, not processing queue\n"); return; } if (NULL != h->cth) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Request pending, not processing queue\n"); return; } if (NULL != h->control_pending_head) msize = ntohs (((struct GNUNET_MessageHeader *) &h-> control_pending_head[1])->size); else if (h->ready_peer_head != NULL) msize = h->ready_peer_head->th.msize + sizeof (struct SendMessage); else { LOG (GNUNET_ERROR_TYPE_DEBUG, "Request queue empty, not processing queue\n"); return; /* no pending message */ } h->cth = GNUNET_CLIENT_notify_transmit_ready (h->client, msize, GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_NO, &transmit_message, h); }
/** * Convenience API that combines sending a request * to the service and waiting for a response. * If either operation times out, the callback * will be called with a "NULL" response (in which * case the connection should probably be destroyed). * * @param client connection to use * @param hdr message to transmit * @param timeout when to give up (for both transmission * and for waiting for a response) * @param auto_retry if the connection to the service dies, should we * automatically re-connect and retry (within the timeout period) * or should we immediately fail in this case? Pass GNUNET_YES * if the caller does not care about temporary connection errors, * for example because the protocol is stateless * @param rn function to call with the response * @param rn_cls closure for rn * @return GNUNET_OK on success, GNUNET_SYSERR if a request * is already pending */ int GNUNET_CLIENT_transmit_and_get_response (struct GNUNET_CLIENT_Connection *client, const struct GNUNET_MessageHeader *hdr, struct GNUNET_TIME_Relative timeout, int auto_retry, GNUNET_CLIENT_MessageHandler rn, void *rn_cls) { struct TransmitGetResponseContext *tc; uint16_t msize; if (NULL != client->th) return GNUNET_SYSERR; GNUNET_assert (NULL == client->tag); msize = ntohs (hdr->size); tc = GNUNET_malloc (sizeof (struct TransmitGetResponseContext) + msize); tc->client = client; tc->hdr = (const struct GNUNET_MessageHeader *) &tc[1]; memcpy (&tc[1], hdr, msize); tc->timeout = GNUNET_TIME_relative_to_absolute (timeout); tc->rn = rn; tc->rn_cls = rn_cls; if (NULL == GNUNET_CLIENT_notify_transmit_ready (client, msize, timeout, auto_retry, &transmit_for_response, tc)) { GNUNET_break (0); GNUNET_free (tc); return GNUNET_SYSERR; } client->tag = tc; return GNUNET_OK; }
/** * Disconnect and then reconnect to the DV service. * * @param sh service handle */ static void reconnect (struct GNUNET_DV_ServiceHandle *sh) { if (NULL != sh->th) { GNUNET_CLIENT_notify_transmit_ready_cancel (sh->th); sh->th = NULL; } LOG (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from DV service at %p\n", sh->client); if (NULL != sh->client) { GNUNET_CLIENT_disconnect (sh->client); sh->client = NULL; } GNUNET_CONTAINER_multipeermap_iterate (sh->peers, &cleanup_send_cb, sh); LOG (GNUNET_ERROR_TYPE_DEBUG, "Connecting to DV service\n"); sh->client = GNUNET_CLIENT_connect ("dv", sh->cfg); if (NULL == sh->client) { GNUNET_break (0); return; } sh->th = GNUNET_CLIENT_notify_transmit_ready (sh->client, sizeof (struct GNUNET_MessageHeader), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, &transmit_start, sh); }
/** * Try to send messages from list of messages to send * * @param handle handle to DHT */ static void process_pending_messages (struct GNUNET_DHT_Handle *handle) { struct PendingMessage *head; if (NULL == handle->client) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "process_pending_messages called, but client is NULL, reconnecting\n"); do_disconnect (handle); return; } if (NULL != handle->th) return; if (NULL == (head = handle->pending_head)) return; handle->th = GNUNET_CLIENT_notify_transmit_ready (handle->client, ntohs (head->msg->size), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, &transmit_pending, handle); if (NULL != handle->th) return; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "notify_transmit_ready returned NULL, reconnecting\n"); do_disconnect (handle); }
/** * Check the list of pending requests, send the next * one to the arm. * * @param h arm handle * @param ignore_currently_down transmit message even if not initialized? */ static void trigger_next_request (struct GNUNET_ARM_Handle *h, int ignore_currently_down) { uint16_t msize; msize = sizeof (struct GNUNET_MessageHeader); if ((GNUNET_YES == h->currently_down) && (ignore_currently_down == GNUNET_NO)) { LOG (GNUNET_ERROR_TYPE_DEBUG, "ARM connection down, not processing queue\n"); return; } if (NULL != h->cth) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Request pending, not processing queue\n"); return; } if (NULL != h->control_pending_head) msize = ntohs (h->control_pending_head->msg->header.size); else if (GNUNET_NO == ignore_currently_down) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Request queue empty, not processing queue\n"); return; /* no pending message */ } h->cth = GNUNET_CLIENT_notify_transmit_ready (h->client, msize, GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_NO, &transmit_arm_message, h); }
/** * Function called to notify a client about the connection begin ready to queue * more data. "buf" will be NULL and "size" zero if the connection was closed * for writing in the meantime. * * @param cls closure * @param size number of bytes available in buf * @param buf where the callee should write the message * @return number of bytes written to buf */ static size_t transmit_ready_notify (void *cls, size_t size, void *buf) { struct GNUNET_TESTBED_LOGGER_Handle *h = cls; struct MessageQueue *mq; h->th = NULL; mq = h->mq_head; GNUNET_assert (NULL != mq); if ((0 == size) && (NULL == buf)) /* Timeout */ { LOG_DEBUG ("Message sending timed out -- retrying\n"); h->retry_backoff = GNUNET_TIME_STD_BACKOFF (h->retry_backoff); h->th = GNUNET_CLIENT_notify_transmit_ready (h->client, ntohs (mq->msg->size), h->retry_backoff, GNUNET_YES, &transmit_ready_notify, h); return 0; } h->retry_backoff = GNUNET_TIME_UNIT_ZERO; GNUNET_assert (ntohs (mq->msg->size) <= size); size = ntohs (mq->msg->size); memcpy (buf, mq->msg, size); LOG_DEBUG ("Message of type: %u and size: %u sent\n", ntohs (mq->msg->type), size); GNUNET_free (mq->msg); GNUNET_CONTAINER_DLL_remove (h->mq_head, h->mq_tail, mq); GNUNET_free (mq); h->bwrote += (size - sizeof (struct GNUNET_MessageHeader)); mq = h->mq_head; if (NULL != mq) { h->retry_backoff = GNUNET_TIME_STD_BACKOFF (h->retry_backoff); h->th = GNUNET_CLIENT_notify_transmit_ready (h->client, ntohs (mq->msg->size), h->retry_backoff, GNUNET_YES, &transmit_ready_notify, h); return size; } if (NULL != h->cb) trigger_flush_notification (h); /* Call the flush completion callback */ return size; }
/** * Send a request to the peerinfo service to start being * notified about all changes to peer information. * * @param nc our context */ static void request_notifications (struct GNUNET_PEERINFO_NotifyContext *nc) { GNUNET_assert (NULL == nc->init); nc->init = GNUNET_CLIENT_notify_transmit_ready (nc->client, sizeof (struct NotifyMessage), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, &transmit_notify_request, nc); }
/** * Start sending messages from our queue to the service. * * @param sh service handle */ static void start_transmit (struct GNUNET_DV_ServiceHandle *sh) { if (NULL != sh->th) return; if (NULL == sh->th_head) return; sh->th = GNUNET_CLIENT_notify_transmit_ready (sh->client, ntohs (sh->th_head->msg->size), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_NO, &transmit_pending, sh); }
static void ready6 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { const struct GNUNET_CONFIGURATION_Handle *cfg = cls; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "V6 ready\n"); GNUNET_assert (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE)); client = GNUNET_CLIENT_connect ("test_service6", cfg); GNUNET_assert (client != NULL); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "V6 client connected\n"); GNUNET_CLIENT_notify_transmit_ready (client, sizeof (struct GNUNET_MessageHeader), GNUNET_TIME_UNIT_SECONDS, GNUNET_NO, &build_msg, NULL); }
static void connection_client_send_impl (struct GNUNET_MQ_Handle *mq, const struct GNUNET_MessageHeader *msg, void *impl_state) { struct ClientConnectionState *state = impl_state; GNUNET_assert (NULL != state); GNUNET_assert (NULL == state->th); state->th = GNUNET_CLIENT_notify_transmit_ready (state->connection, ntohs (msg->size), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_NO, &connection_client_transmit_queued, mq); GNUNET_assert (NULL != state->th); }
static void ready6 (void *cls, int result) { const struct GNUNET_CONFIGURATION_Handle *cfg = cls; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "V6 ready\n"); GNUNET_assert (GNUNET_YES == result); client = GNUNET_CLIENT_connect ("test_service6", cfg); GNUNET_assert (client != NULL); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "V6 client connected\n"); GNUNET_CLIENT_notify_transmit_ready (client, sizeof (struct GNUNET_MessageHeader), GNUNET_TIME_UNIT_SECONDS, GNUNET_NO, &build_msg, NULL); }
/** * Disconnect from the datastore service (and free * associated resources). * * @param h handle to the datastore * @param drop set to GNUNET_YES to delete all data in datastore (!) */ void GNUNET_DATASTORE_disconnect (struct GNUNET_DATASTORE_Handle *h, int drop) { struct GNUNET_DATASTORE_QueueEntry *qe; LOG (GNUNET_ERROR_TYPE_DEBUG, "Datastore disconnect\n"); if (NULL != h->th) { GNUNET_CLIENT_notify_transmit_ready_cancel (h->th); h->th = NULL; } if (h->client != NULL) { GNUNET_CLIENT_disconnect (h->client); h->client = NULL; } if (h->reconnect_task != GNUNET_SCHEDULER_NO_TASK) { GNUNET_SCHEDULER_cancel (h->reconnect_task); h->reconnect_task = GNUNET_SCHEDULER_NO_TASK; } while (NULL != (qe = h->queue_head)) { GNUNET_assert (NULL != qe->response_proc); qe->response_proc (h, NULL); } if (GNUNET_YES == drop) { h->client = GNUNET_CLIENT_connect ("datastore", h->cfg); if (h->client != NULL) { if (NULL != GNUNET_CLIENT_notify_transmit_ready (h->client, sizeof (struct GNUNET_MessageHeader), GNUNET_TIME_UNIT_MINUTES, GNUNET_YES, &transmit_drop, h)) return; GNUNET_CLIENT_disconnect (h->client); h->client = NULL; } GNUNET_break (0); } GNUNET_STATISTICS_destroy (h->stats, GNUNET_NO); h->stats = NULL; GNUNET_free (h); }
/** * Schedule transmission of the next message from our queue. * * @param h identity handle */ static void transmit_next (struct GNUNET_IDENTITY_Handle *h) { struct GNUNET_IDENTITY_Operation *op = h->op_head; GNUNET_assert (NULL == h->th); if (NULL == op) return; if (NULL == h->client) return; h->th = GNUNET_CLIENT_notify_transmit_ready (h->client, ntohs (op->msg->size), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_NO, &send_next_message, h); }
/** * Transmit messages from the message queue to the service * (if there are any, and if we are not already trying). * * @param h handle to use */ static void do_transmit (struct GNUNET_NAMESTORE_Handle *h) { struct PendingMessage *p; if (NULL != h->th) return; if (NULL == (p = h->pending_head)) return; if (NULL == h->client) return; /* currently reconnecting */ h->th = GNUNET_CLIENT_notify_transmit_ready (h->client, p->size, GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_NO, &transmit_message_to_namestore, h); }
/** * Request that the service should shutdown. * Afterwards, the connection will automatically be * disconnected. Hence the "sock" should not * be used by the caller after this call * (calling this function frees "sock" after a while). * * @param sock the socket connected to the service * @param timeout how long to wait before giving up on transmission * @param cont continuation to call once the service is really down * @param cont_cls closure for continuation * */ static void arm_service_shutdown (struct GNUNET_CLIENT_Connection *sock, struct GNUNET_TIME_Relative timeout, GNUNET_CLIENT_ShutdownTask cont, void *cont_cls) { struct ShutdownContext *shutdown_ctx; shutdown_ctx = GNUNET_malloc (sizeof (struct ShutdownContext)); shutdown_ctx->cont = cont; shutdown_ctx->cont_cls = cont_cls; shutdown_ctx->sock = sock; shutdown_ctx->timeout = GNUNET_TIME_relative_to_absolute (timeout); GNUNET_CLIENT_notify_transmit_ready (sock, sizeof (struct GNUNET_MessageHeader), timeout, GNUNET_NO, &write_shutdown, shutdown_ctx); }
/** * Ask to send a join request. */ static int rejoin_room (struct GNUNET_CHAT_Room *chat_room) { size_t size_of_join; size_of_join = sizeof (struct JoinRequestMessage) + GNUNET_CONTAINER_meta_data_get_serialized_size (chat_room->member_info) + strlen (chat_room->room_name); if (NULL == GNUNET_CLIENT_notify_transmit_ready (chat_room->client, size_of_join, GNUNET_CONSTANTS_SERVICE_TIMEOUT, GNUNET_YES, &transmit_join_request, chat_room)) return GNUNET_SYSERR; return GNUNET_OK; }
/** * Schedule transmission of the next message from our queue. * * @param h PSYCstore handle. */ static void transmit_next (struct GNUNET_PSYCSTORE_Handle *h) { if (NULL != h->th || NULL == h->client) return; struct GNUNET_PSYCSTORE_OperationHandle *op = h->transmit_head; if (NULL == op) return; h->th = GNUNET_CLIENT_notify_transmit_ready (h->client, ntohs (op->msg->size), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_NO, &send_next_message, h); }
static void task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct sockaddr_un un; const char *unixpath = "/tmp/testsock"; size_t slen = strlen (unixpath); struct sockaddr *sap[2]; socklen_t slens[2]; memset (&un, 0, sizeof (un)); un.sun_family = AF_UNIX; memcpy (un.sun_path, unixpath, slen); un.sun_path[slen] = '\0'; #if HAVE_SOCKADDR_IN_SIN_LEN un.sun_len = (u_char) sizeof (un); #endif #if LINUX un.sun_path[0] = '\0'; #endif sap[0] = (struct sockaddr *) &un; slens[0] = sizeof (un); sap[1] = NULL; slens[1] = 0; server = GNUNET_SERVER_create (NULL, NULL, sap, slens, GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 250), GNUNET_NO); GNUNET_assert (server != NULL); handlers[0].callback_cls = cls; GNUNET_SERVER_add_handlers (server, handlers); GNUNET_SERVER_disconnect_notify (server, ¬ify_disconnect, cls); cfg = GNUNET_CONFIGURATION_create (); GNUNET_CONFIGURATION_set_value_string (cfg, "test", "UNIXPATH", unixpath); GNUNET_CONFIGURATION_set_value_string (cfg, "resolver", "HOSTNAME", "localhost"); client = GNUNET_CLIENT_connect ("test", cfg); GNUNET_assert (client != NULL); GNUNET_CLIENT_notify_transmit_ready (client, 256, GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 250), GNUNET_NO, ¬ify_ready, NULL); }
/** * Add a request to our request queue and transmit it. * * @param rr request to queue and transmit. */ static void queue_request (struct GNUNET_VPN_RedirectionRequest *rr) { struct GNUNET_VPN_Handle *vh; vh = rr->vh; GNUNET_CONTAINER_DLL_insert_tail (vh->rr_head, vh->rr_tail, rr); if ( (NULL == vh->th) && (NULL != vh->client) ) vh->th = GNUNET_CLIENT_notify_transmit_ready (vh->client, sizeof (struct RedirectToServiceRequestMessage), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_NO, &transmit_request, vh); }
/** * Connect to the VPN service and start again to transmit our requests. * * @param cls the 'struct GNUNET_VPN_Handle *' * @param tc scheduler context */ static void connect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_VPN_Handle *vh = cls; vh->rt = GNUNET_SCHEDULER_NO_TASK; vh->client = GNUNET_CLIENT_connect ("vpn", vh->cfg); GNUNET_assert (NULL != vh->client); GNUNET_assert (NULL == vh->th); if (NULL != vh->rr_head) vh->th = GNUNET_CLIENT_notify_transmit_ready (vh->client, sizeof (struct RedirectToServiceRequestMessage), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_NO, &transmit_request, vh); }
static void task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct sockaddr_in sa; struct sockaddr *sap[2]; socklen_t slens[2]; /* test that ill-configured client fails instantly */ GNUNET_assert (NULL == GNUNET_CLIENT_connect ("invalid-service", cfg)); /* test IPC between client and server */ sap[0] = (struct sockaddr *) &sa; slens[0] = sizeof (sa); sap[1] = NULL; slens[1] = 0; memset (&sa, 0, sizeof (sa)); #if HAVE_SOCKADDR_IN_SIN_LEN sa.sin_len = sizeof (sa); #endif sa.sin_family = AF_INET; sa.sin_port = htons (PORT); server = GNUNET_SERVER_create (NULL, NULL, sap, slens, GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 10000), GNUNET_NO); GNUNET_assert (server != NULL); handlers[0].callback_cls = cls; handlers[1].callback_cls = cls; GNUNET_SERVER_add_handlers (server, handlers); client = GNUNET_CLIENT_connect (MYNAME, cfg); GNUNET_assert (client != NULL); GNUNET_assert (NULL != GNUNET_CLIENT_notify_transmit_ready (client, sizeof (struct GNUNET_MessageHeader), GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,5), GNUNET_NO, &make_msg, NULL)); GNUNET_CLIENT_receive (client, &recv_bounce, cls, GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 10000)); }
static int reconnect_arm_monitor (struct GNUNET_ARM_MonitorHandle *h) { GNUNET_assert (NULL == h->monitor); h->monitor = GNUNET_CLIENT_connect ("arm", h->cfg); if (NULL == h->monitor) { LOG (GNUNET_ERROR_TYPE_DEBUG, "arm_api, GNUNET_CLIENT_connect returned NULL\n"); if (NULL != h->service_status) h->service_status (h->cls, NULL, GNUNET_ARM_SERVICE_STOPPED); return GNUNET_SYSERR; } LOG (GNUNET_ERROR_TYPE_DEBUG, "arm_api, GNUNET_CLIENT_connect returned non-NULL\n"); h->cth = GNUNET_CLIENT_notify_transmit_ready (h->monitor, sizeof (struct GNUNET_MessageHeader), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_NO, &transmit_monitoring_init_message, h); return GNUNET_OK; }
/** * Transmit the monitoring initialization message to the arm service. * * @param cls closure with the 'struct GNUNET_ARM_MonitorHandle' * @param size number of bytes available in buf * @param buf where the callee should write the message * @return number of bytes written to buf */ static size_t transmit_monitoring_init_message (void *cls, size_t size, void *buf) { struct GNUNET_ARM_MonitorHandle *h = cls; struct GNUNET_MessageHeader *msg; uint16_t msize; GNUNET_assert (NULL == h->reconnect_task); GNUNET_assert (NULL == h->init_timeout_task_id); h->cth = NULL; if (NULL == buf) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmission failed, initiating reconnect\n"); reconnect_arm_monitor_later (h); return 0; } msize = sizeof (struct GNUNET_MessageHeader); if (size < msize) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Request is too big (%u < %u), not sending it\n", size, msize); h->cth = GNUNET_CLIENT_notify_transmit_ready (h->monitor, msize, GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_NO, transmit_monitoring_init_message, h); return 0; } msg = buf; msg->size = htons (msize); msg->type = htons (GNUNET_MESSAGE_TYPE_ARM_MONITOR); LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmitting ARM monitoring init message with %u bytes to arm.\n", (unsigned int) msize); h->init_timeout_task_id = GNUNET_SCHEDULER_add_delayed ( INIT_TIMEOUT, init_timeout_task, h); GNUNET_CLIENT_receive (h->monitor, &monitor_notify_handler, h, GNUNET_TIME_UNIT_FOREVER_REL); return msize; }
static size_t transmit_initial_message (void *cls, size_t size, void *buf) { struct GNUNET_MessageHeader msg; GNUNET_assert (ok == 1); ok = 2; GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader)); msg.type = htons (MY_TYPE); msg.size = htons (sizeof (struct GNUNET_MessageHeader)); memcpy (buf, &msg, sizeof (struct GNUNET_MessageHeader)); GNUNET_assert (NULL != GNUNET_CLIENT_notify_transmit_ready (cc, sizeof (struct GNUNET_MessageHeader), TIMEOUT, GNUNET_YES, &transmit_second_message, NULL)); GNUNET_CLIENT_receive (cc, &first_reply_handler, NULL, TIMEOUT); return sizeof (struct GNUNET_MessageHeader); }
/** * Process entries in the queue (or do nothing if we are already * doing so). * * @param h handle to the datastore */ static void process_queue (struct GNUNET_DATASTORE_Handle *h) { struct GNUNET_DATASTORE_QueueEntry *qe; if (NULL == (qe = h->queue_head)) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Queue empty\n"); return; /* no entry in queue */ } if (qe->was_transmitted == GNUNET_YES) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Head request already transmitted\n"); return; /* waiting for replies */ } if (h->th != NULL) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Pending transmission request\n"); return; /* request pending */ } if (h->client == NULL) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Not connected\n"); return; /* waiting for reconnect */ } if (GNUNET_YES == h->in_receive) { /* wait for response to previous query */ return; } LOG (GNUNET_ERROR_TYPE_DEBUG, "Queueing %u byte request to DATASTORE\n", qe->message_size); h->th = GNUNET_CLIENT_notify_transmit_ready (h->client, qe->message_size, GNUNET_TIME_absolute_get_remaining (qe->timeout), GNUNET_YES, &transmit_request, h); GNUNET_assert (GNUNET_NO == h->in_receive); GNUNET_break (NULL != h->th); }
/** * Add the given reply to our transmission queue and trigger sending if needed. * * @param dh handle with the connection * @param qe reply to queue */ static void queue_reply (struct GNUNET_DNS_Handle *dh, struct ReplyQueueEntry *qe) { if (NULL == dh->dns_connection) { GNUNET_free (qe); return; } GNUNET_CONTAINER_DLL_insert_tail (dh->rq_head, dh->rq_tail, qe); if (NULL != dh->dns_transmit_handle) return; /* trigger sending */ dh->dns_transmit_handle = GNUNET_CLIENT_notify_transmit_ready (dh->dns_connection, ntohs (dh->rq_head->msg->size), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_NO, &send_response, dh); }