X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fcore%2Fcore_api.c;h=f8c7c0aa6ef79a231e1d5454bb897117db764cc8;hb=723b9f11ab20aa6b2fa88840e2f5e52ae72d0b6c;hp=58ac3cc0e02458af2964a090677cb9bed605d437;hpb=20dd3d96cb1dbd4deb19321728a62d89c88aa9cc;p=oweals%2Fgnunet.git diff --git a/src/core/core_api.c b/src/core/core_api.c index 58ac3cc0e..f8c7c0aa6 100644 --- a/src/core/core_api.c +++ b/src/core/core_api.c @@ -58,18 +58,12 @@ struct GNUNET_CORE_Handle /** * Function to call whenever we're notified about a peer connecting. */ - GNUNET_CORE_ClientEventHandler connects; + GNUNET_CORE_ConnectEventHandler connects; /** * Function to call whenever we're notified about a peer disconnecting. */ - GNUNET_CORE_ClientEventHandler disconnects; - - /** - * Function to call whenever we're asked to generate traffic - * (data provided to be transmitted back to the service). - */ - GNUNET_CORE_BufferFillCallback bfc; + GNUNET_CORE_DisconnectEventHandler disconnects; /** * Function to call whenever we receive an inbound message. @@ -87,9 +81,9 @@ struct GNUNET_CORE_Handle const struct GNUNET_CORE_MessageHandler *handlers; /** - * Our connection to the service. + * Our connection to the service for notifications. */ - struct GNUNET_CLIENT_Connection *client; + struct GNUNET_CLIENT_Connection *client_notifications; /** * Handle for our current transmission request. @@ -191,17 +185,6 @@ struct GNUNET_CORE_TransmitHandle */ void *get_message_cls; - /** - * If this entry is for a configuration request, pointer - * to the information callback; otherwise NULL. - */ - GNUNET_CORE_PeerConfigurationInfoCallback info; - - /** - * Closure for info. - */ - void *info_cls; - /** * If this entry is for a transmission request, pointer * to the notify callback; otherwise NULL. @@ -242,6 +225,10 @@ struct GNUNET_CORE_TransmitHandle }; +static void +reconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); + + /** * Function called when we are ready to transmit our * "START" message (or when this operation timed out). @@ -263,15 +250,22 @@ static size_t transmit_start (void *cls, size_t size, void *buf); static void reconnect (struct GNUNET_CORE_Handle *h) { - GNUNET_CLIENT_disconnect (h->client); + if (h->client_notifications != NULL) + GNUNET_CLIENT_disconnect (h->client_notifications, GNUNET_NO); h->currently_down = GNUNET_YES; - h->client = GNUNET_CLIENT_connect (h->sched, "core", h->cfg); - h->th = GNUNET_CLIENT_notify_transmit_ready (h->client, - sizeof (struct InitMessage) + - sizeof (uint16_t) * h->hcnt, - GNUNET_TIME_UNIT_SECONDS, - GNUNET_NO, - &transmit_start, h); + h->client_notifications = GNUNET_CLIENT_connect (h->sched, "core", h->cfg); + if (h->client_notifications == NULL) + h->reconnect_task = GNUNET_SCHEDULER_add_delayed (h->sched, + GNUNET_TIME_UNIT_SECONDS, + &reconnect_task, + h); + else + h->th = GNUNET_CLIENT_notify_transmit_ready (h->client_notifications, + sizeof (struct InitMessage) + + sizeof (uint16_t) * h->hcnt, + GNUNET_TIME_UNIT_SECONDS, + GNUNET_NO, + &transmit_start, h); } @@ -287,11 +281,8 @@ timeout_request (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_CORE_TransmitHandle *th = cls; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Transmission request timed out.\n"); th->timeout_task = GNUNET_SCHEDULER_NO_TASK; GNUNET_assert (0 == th->get_message (th->get_message_cls, 0, NULL)); - GNUNET_CORE_notify_transmit_ready_cancel (th); } @@ -347,14 +338,24 @@ static void trigger_next_request (struct GNUNET_CORE_Handle *h) { struct GNUNET_CORE_TransmitHandle *th; + if (h->currently_down) - return; /* connection temporarily down */ + { +#if DEBUG_CORE + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "In trigger_next_request, connection currently down...\n"); +#endif + return; /* connection temporarily down */ + } if (NULL == (th = h->pending_head)) return; /* no requests pending */ GNUNET_assert (NULL == h->th); - GNUNET_SCHEDULER_cancel (h->sched, th->timeout_task); - th->timeout_task = GNUNET_SCHEDULER_NO_TASK; - h->th = GNUNET_CLIENT_notify_transmit_ready (h->client, + if (GNUNET_SCHEDULER_NO_TASK != th->timeout_task) + { + GNUNET_SCHEDULER_cancel (h->sched, th->timeout_task); + th->timeout_task = GNUNET_SCHEDULER_NO_TASK; + } + h->th = GNUNET_CLIENT_notify_transmit_ready (h->client_notifications, th->msize, GNUNET_TIME_absolute_get_remaining (th->timeout), @@ -365,104 +366,22 @@ trigger_next_request (struct GNUNET_CORE_Handle *h) /** - * cls is a pointer to a 32 bit number followed by that - * amount of data. If possible, copy to buf and return - * number of bytes copied. Always free the buffer. - */ -static size_t -copy_and_free (void *cls, size_t size, void *buf) -{ - struct GNUNET_CORE_Handle *h = cls; - char *cbuf = h->solicit_buffer; - uint32_t have; - - h->solicit_transmit_req = NULL; - h->solicit_buffer = NULL; - memcpy (&have, cbuf, sizeof (uint32_t)); - if (have > size) - { - /* timeout / error case */ - GNUNET_free (cbuf); - return 0; - } - memcpy (buf, cbuf + sizeof (uint32_t), have); - GNUNET_free (cbuf); - return have; -} - - -/** - * Call bfc callback to solicit traffic for the given peer. - * - * @param h our handle to the core service - * @param peer peer for which traffic is solicited - * @param amount number of bytes that are being solicited - */ -static void -solicit_traffic (struct GNUNET_CORE_Handle *h, - const struct GNUNET_PeerIdentity *peer, uint32_t amount) -{ - char buf[amount]; - size_t have; - char *cbuf; - - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Core solicited %u bytes of traffic for `%s'!\n", - amount, - GNUNET_i2s (peer)); - if (NULL != h->solicit_transmit_req) - { - /* more than one solicitation pending */ - GNUNET_break (0); - return; - } - have = h->bfc (h->cls, peer, buf, amount); - if (have == 0) - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Can not help with traffic solicitation for `%s'!\n", - GNUNET_i2s (peer)); - return; - } - GNUNET_assert (have >= sizeof (struct GNUNET_MessageHeader)); - cbuf = GNUNET_malloc (have + sizeof (uint32_t)); - memcpy (cbuf, &have, sizeof (uint32_t)); - memcpy (cbuf + sizeof (uint32_t), buf, have); - h->solicit_buffer = cbuf; - h->solicit_transmit_req - = GNUNET_CORE_notify_transmit_ready (h, - 0, - GNUNET_TIME_UNIT_SECONDS, - peer, have, ©_and_free, h); - if (h->solicit_transmit_req == NULL) - { - /* this should not happen */ - GNUNET_break (0); - GNUNET_free (cbuf); - h->solicit_buffer = NULL; - } -} - - -/** - * Handler for most messages received from the core. + * Handler for notification messages received from the core. * * @param cls our "struct GNUNET_CORE_Handle" * @param msg the message received from the core service */ static void -main_handler (void *cls, const struct GNUNET_MessageHeader *msg) +main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg) { struct GNUNET_CORE_Handle *h = cls; unsigned int hpos; const struct ConnectNotifyMessage *cnm; + const struct DisconnectNotifyMessage *dnm; const struct NotifyTrafficMessage *ntm; - const struct ConfigurationInfoMessage *cim; - const struct SolicitTrafficMessage *stm; const struct GNUNET_MessageHeader *em; uint16_t msize; uint16_t et; - uint32_t ss; const struct GNUNET_CORE_MessageHandler *mh; if (msg == NULL) @@ -494,7 +413,9 @@ main_handler (void *cls, const struct GNUNET_MessageHeader *msg) } cnm = (const struct ConnectNotifyMessage *) msg; h->connects (h->cls, - &cnm->peer); + &cnm->peer, + GNUNET_TIME_relative_ntoh (cnm->latency), + ntohl (cnm->distance)); break; case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT: if (NULL == h->disconnects) @@ -502,14 +423,14 @@ main_handler (void *cls, const struct GNUNET_MessageHeader *msg) GNUNET_break (0); break; } - if (msize != sizeof (struct ConnectNotifyMessage)) + if (msize != sizeof (struct DisconnectNotifyMessage)) { GNUNET_break (0); break; } - cnm = (const struct ConnectNotifyMessage *) msg; + dnm = (const struct DisconnectNotifyMessage *) msg; h->disconnects (h->cls, - &cnm->peer); + &dnm->peer); break; case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND: if (msize < @@ -545,7 +466,9 @@ main_handler (void *cls, const struct GNUNET_MessageHeader *msg) continue; } if (GNUNET_OK != - h->handlers[hpos].callback (h->cls, &ntm->peer, em)) + h->handlers[hpos].callback (h->cls, &ntm->peer, em, + GNUNET_TIME_relative_ntoh (ntm->latency), + ntohl (ntm->distance))) { /* error in processing, disconnect ! */ reconnect (h); @@ -553,7 +476,9 @@ main_handler (void *cls, const struct GNUNET_MessageHeader *msg) } } if (NULL != h->inbound_notify) - h->inbound_notify (h->cls, &ntm->peer, em); + h->inbound_notify (h->cls, &ntm->peer, em, + GNUNET_TIME_relative_ntoh (ntm->latency), + ntohl (ntm->distance)); break; case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND: if (msize < @@ -576,62 +501,19 @@ main_handler (void *cls, const struct GNUNET_MessageHeader *msg) GNUNET_break (0); break; } - h->outbound_notify (h->cls, &ntm->peer, em); - break; - case GNUNET_MESSAGE_TYPE_CORE_CONFIGURATION_INFO: - if (msize != sizeof (struct ConfigurationInfoMessage)) - { - GNUNET_break (0); - break; - } - if (NULL == h->submitted) - break; - cim = (const struct ConfigurationInfoMessage *) msg; - - /* process configuration data */ - if (h->submitted->info != NULL) - h->submitted->info (h->submitted->info_cls, - &h->submitted->peer, - ntohl (cim->bpm_in), - ntohl (cim->bpm_out), - GNUNET_TIME_relative_ntoh (cim->latency), - (int) ntohl (cim->reserved_amount), - cim->preference); - /* done, clean up! */ - GNUNET_CORE_notify_transmit_ready_cancel (h->submitted); // HUH? - trigger_next_request (h); - break; - case GNUNET_MESSAGE_TYPE_CORE_SOLICIT_TRAFFIC: - if (msize != sizeof (struct SolicitTrafficMessage)) - { - GNUNET_break (0); - break; - } - stm = (const struct SolicitTrafficMessage *) msg; - if (NULL == h->bfc) - { - GNUNET_break (0); - break; - } - ss = ntohl (stm->solicit_size); - if ((ss > GNUNET_SERVER_MAX_MESSAGE_SIZE) || - (ss + sizeof (struct SendMessage) > GNUNET_SERVER_MAX_MESSAGE_SIZE)) - { - GNUNET_break (0); - break; - } - solicit_traffic (h, &stm->peer, ss); + h->outbound_notify (h->cls, &ntm->peer, em, + GNUNET_TIME_relative_ntoh (ntm->latency), + ntohl (ntm->distance)); break; default: GNUNET_break (0); break; } - GNUNET_CLIENT_receive (h->client, - &main_handler, h, GNUNET_TIME_UNIT_FOREVER_REL); + GNUNET_CLIENT_receive (h->client_notifications, + &main_notify_handler, h, GNUNET_TIME_UNIT_FOREVER_REL); } - /** * Function called when we are ready to transmit our * "START" message (or when this operation timed out). @@ -665,10 +547,12 @@ init_reply_handler (void *cls, const struct GNUNET_MessageHeader *msg) (ntohs (msg->size) != sizeof (struct InitReplyMessage)) || (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_CORE_INIT_REPLY)) { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ - ("Error connecting to core service (failed to receive `%s' message).\n"), - "INIT_REPLY"); + ("Error connecting to core service (failed to receive `%s' message, got message of type %u and size %u).\n"), + "INIT_REPLY", + (msg == NULL) ? -1 : ntohs (msg->type), + (msg == NULL) ? -1 : ntohs (msg->size)); GNUNET_break (msg == NULL); transmit_start (h, 0, NULL); return; @@ -677,21 +561,16 @@ init_reply_handler (void *cls, const struct GNUNET_MessageHeader *msg) /* start our message processing loop */ #if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _ - ("Successfully connected to core service, starting processing loop.\n")); + "Successfully connected to core service, starting processing loop.\n"); #endif h->currently_down = GNUNET_NO; trigger_next_request (h); - GNUNET_CLIENT_receive (h->client, - &main_handler, h, GNUNET_TIME_UNIT_FOREVER_REL); + GNUNET_CLIENT_receive (h->client_notifications, + &main_notify_handler, h, GNUNET_TIME_UNIT_FOREVER_REL); if (NULL != (init = h->init)) { /* mark so we don't call init on reconnect */ h->init = NULL; -#if DEBUG_CORE - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - _("Successfully connected to core service.\n")); -#endif GNUNET_CRYPTO_hash (&m->publicKey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), @@ -766,8 +645,6 @@ transmit_start (void *cls, size_t size, void *buf) opt |= GNUNET_CORE_OPTION_SEND_CONNECT; if (h->disconnects != NULL) opt |= GNUNET_CORE_OPTION_SEND_DISCONNECT; - if (h->bfc != NULL) - opt |= GNUNET_CORE_OPTION_SEND_BFC; if (h->inbound_notify != NULL) { if (h->inbound_hdr_only) @@ -786,7 +663,7 @@ transmit_start (void *cls, size_t size, void *buf) ts = (uint16_t *) & init[1]; for (hpos = 0; hpos < h->hcnt; hpos++) ts[hpos] = htons (h->handlers[hpos].type); - GNUNET_CLIENT_receive (h->client, + GNUNET_CLIENT_receive (h->client_notifications, &init_reply_handler, h, GNUNET_TIME_absolute_get_remaining @@ -807,7 +684,6 @@ transmit_start (void *cls, size_t size, void *buf) * connected to the core service; note that timeout is only meaningful if init is not NULL * @param connects function to call on peer connect, can be NULL * @param disconnects function to call on peer disconnect / timeout, can be NULL - * @param bfc function to call to fill up spare bandwidth, can be NULL * @param inbound_notify function to call for all inbound messages, can be NULL * @param inbound_hdr_only set to GNUNET_YES if inbound_notify will only read the * GNUNET_MessageHeader and hence we do not need to give it the full message; @@ -826,9 +702,8 @@ GNUNET_CORE_connect (struct GNUNET_SCHEDULER_Handle *sched, struct GNUNET_TIME_Relative timeout, void *cls, GNUNET_CORE_StartupCallback init, - GNUNET_CORE_ClientEventHandler connects, - GNUNET_CORE_ClientEventHandler disconnects, - GNUNET_CORE_BufferFillCallback bfc, + GNUNET_CORE_ConnectEventHandler connects, + GNUNET_CORE_DisconnectEventHandler disconnects, GNUNET_CORE_MessageCallback inbound_notify, int inbound_hdr_only, GNUNET_CORE_MessageCallback outbound_notify, @@ -844,14 +719,13 @@ GNUNET_CORE_connect (struct GNUNET_SCHEDULER_Handle *sched, h->init = init; h->connects = connects; h->disconnects = disconnects; - h->bfc = bfc; h->inbound_notify = inbound_notify; h->outbound_notify = outbound_notify; h->inbound_hdr_only = inbound_hdr_only; h->outbound_hdr_only = outbound_hdr_only; h->handlers = handlers; - h->client = GNUNET_CLIENT_connect (sched, "core", cfg); - if (h->client == NULL) + h->client_notifications = GNUNET_CLIENT_connect (sched, "core", cfg); + if (h->client_notifications == NULL) { GNUNET_free (h); return NULL; @@ -869,7 +743,7 @@ GNUNET_CORE_connect (struct GNUNET_SCHEDULER_Handle *sched, timeout.value); #endif h->th = - GNUNET_CLIENT_notify_transmit_ready (h->client, + GNUNET_CLIENT_notify_transmit_ready (h->client_notifications, sizeof (struct InitMessage) + sizeof (uint16_t) * h->hcnt, timeout, GNUNET_YES, @@ -892,114 +766,13 @@ GNUNET_CORE_disconnect (struct GNUNET_CORE_Handle *handle) GNUNET_CORE_notify_transmit_ready_cancel (handle->solicit_transmit_req); if (handle->reconnect_task != GNUNET_SCHEDULER_NO_TASK) GNUNET_SCHEDULER_cancel (handle->sched, handle->reconnect_task); - GNUNET_CLIENT_disconnect (handle->client); + if (handle->client_notifications != NULL) + GNUNET_CLIENT_disconnect (handle->client_notifications, GNUNET_NO); GNUNET_free_non_null (handle->solicit_buffer); GNUNET_free (handle); } -/** - * Build the configure message. - */ -static size_t -produce_configure_message (void *cls, size_t size, void *buf) -{ - struct GNUNET_CORE_TransmitHandle *th = cls; - struct GNUNET_CORE_Handle *ch = th->ch; - - if (buf == NULL) - { - /* communicate handle timeout/error! */ - if (th->info != NULL) - th->info (th->info_cls, NULL, 0, 0, GNUNET_TIME_UNIT_ZERO, 0, 0.0); - if (th->timeout_task != GNUNET_SCHEDULER_NO_TASK) - GNUNET_CORE_notify_transmit_ready_cancel (th); - if (ch->submitted == th) - ch->submitted = NULL; - trigger_next_request (ch); - return 0; - } - GNUNET_assert (size >= sizeof (struct RequestConfigureMessage)); - memcpy (buf, &th[1], sizeof (struct RequestConfigureMessage)); - if (th->prev == NULL) - ch->pending_head = th->next; - else - th->prev->next = th->next; - if (th->next == NULL) - ch->pending_tail = th->prev; - else - th->next->prev = th->prev; - return sizeof (struct RequestConfigureMessage); -} - - -/** - * Obtain statistics and/or change preferences for the given peer. - * - * @param handle connection to core to use - * @param peer identifies the peer - * @param timeout after how long should we give up (and call "info" with NULL - * for "peer" to signal an error)? - * @param bpm_out set to the current bandwidth limit (sending) for this peer, - * caller should set "bpm_out" to "-1" to avoid changing - * the current value; otherwise "bpm_out" will be lowered to - * the specified value; passing a pointer to "0" can be used to force - * us to disconnect from the peer; "bpm_out" might not increase - * as specified since the upper bound is generally - * determined by the other peer! - * @param amount reserve N bytes for receiving, negative - * amounts can be used to undo a (recent) reservation; - * @param preference increase incoming traffic share preference by this amount; - * in the absence of "amount" reservations, we use this - * preference value to assign proportional bandwidth shares - * to all connected peers - * @param info function to call with the resulting configuration information - * @param info_cls closure for info - */ -void -GNUNET_CORE_peer_configure (struct GNUNET_CORE_Handle *handle, - const struct GNUNET_PeerIdentity *peer, - struct GNUNET_TIME_Relative timeout, - unsigned int bpm_out, - int amount, - unsigned long long preference, - GNUNET_CORE_PeerConfigurationInfoCallback info, - void *info_cls) -{ - struct RequestConfigureMessage *rcm; - struct GNUNET_CORE_TransmitHandle *th; - - th = GNUNET_malloc (sizeof (struct GNUNET_CORE_TransmitHandle) + - sizeof (struct RequestConfigureMessage)); - /* append to list */ - th->prev = handle->pending_tail; - if (handle->pending_tail == NULL) - handle->pending_head = th; - else - handle->pending_tail->next = th; - th->ch = handle; - th->get_message = &produce_configure_message; - th->get_message_cls = th; - th->info = info; - th->info_cls = info_cls; - th->timeout = GNUNET_TIME_relative_to_absolute (timeout); - th->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->sched, - timeout, - &timeout_request, th); - th->msize = sizeof (struct RequestConfigureMessage); - rcm = (struct RequestConfigureMessage *) &th[1]; - rcm->header.size = htons (sizeof (struct RequestConfigureMessage)); - rcm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_REQUEST_CONFIGURE); - rcm->reserved = htonl (0); - rcm->limit_outbound_bpm = htonl (bpm_out); - rcm->reserve_inbound = htonl (amount); - rcm->preference_change = GNUNET_htonll(preference); - rcm->peer = *peer; - if (handle->pending_head == th) - trigger_next_request (handle); -} - - /** * Build the message requesting data transmission. */ @@ -1023,8 +796,7 @@ produce_send (void *cls, size_t size, void *buf) GNUNET_i2s(&th->peer)); #endif GNUNET_assert (0 == th->notify (th->notify_cls, 0, NULL)); - if (th->timeout_task != GNUNET_SCHEDULER_NO_TASK) - GNUNET_CORE_notify_transmit_ready_cancel (th); + GNUNET_CORE_notify_transmit_ready_cancel (th); trigger_next_request (h); return 0; } @@ -1047,12 +819,22 @@ produce_send (void *cls, size_t size, void *buf) dt = notify (notify_cls, size - sizeof (struct SendMessage), &sm[1]); if (0 == dt) { +#if DEBUG_CORE + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Size of clients message to peer %s is 0!\n", + GNUNET_i2s(&th->peer)); +#endif /* client decided to send nothing! */ return 0; } GNUNET_assert (dt >= sizeof (struct GNUNET_MessageHeader)); + if (dt + sizeof (struct SendMessage) >= GNUNET_SERVER_MAX_MESSAGE_SIZE) + { + GNUNET_break (0); + return 0; + } sm->header.size = htons (dt + sizeof (struct SendMessage)); - GNUNET_assert (dt + sizeof (struct SendMessage) < size); + GNUNET_assert (dt + sizeof (struct SendMessage) <= size); return dt + sizeof (struct SendMessage); }