X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Ftransport%2Ftransport_api.c;h=8d08f82d9d3f516796604a662dcc9b977b3992af;hb=b547897ce3fe3ae2a129afb36bf26eadfb695eef;hp=c2e2061f89139673d78325c26098ee523bd05e9a;hpb=f1696b714e33c293f4243be27ccfa6fd2f305518;p=oweals%2Fgnunet.git diff --git a/src/transport/transport_api.c b/src/transport/transport_api.c index c2e2061f8..8d08f82d9 100644 --- a/src/transport/transport_api.c +++ b/src/transport/transport_api.c @@ -43,6 +43,12 @@ */ #define OFFER_HELLO_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30) +/** + * After how long do we give automatically retry an unsuccessful + * CONNECT request? + */ +#define CONNECT_RETRY_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 750) + /** * How long should ARM wait when starting up the * transport service before reporting back? @@ -74,7 +80,6 @@ struct NeighbourList */ struct GNUNET_TRANSPORT_TransmitHandle *transmit_handle; - /** * Identity of this neighbour. */ @@ -92,7 +97,7 @@ struct NeighbourList uint64_t last_sent; /** - * Global quota for outbound traffic to the neighbour in bytes/ms. + * Quota for outbound traffic to the neighbour in bytes/ms. */ uint32_t quota_out; @@ -198,7 +203,7 @@ struct GNUNET_TRANSPORT_TransmitHandle * Function to call when notify_size bytes are available * for transmission. */ - GNUNET_NETWORK_TransmitReadyNotify notify; + GNUNET_CONNECTION_TransmitReadyNotify notify; /** * Closure for notify. @@ -224,6 +229,11 @@ struct GNUNET_TRANSPORT_TransmitHandle */ size_t notify_size; + /** + * How important is this message? + */ + unsigned int priority; + }; @@ -268,7 +278,7 @@ struct GNUNET_TRANSPORT_Handle /** * Handle to our registration with the client for notification. */ - struct GNUNET_NETWORK_TransmitHandle *network_handle; + struct GNUNET_CONNECTION_TransmitHandle *network_handle; /** * Linked list of transmit handles that are waiting for the @@ -303,7 +313,7 @@ struct GNUNET_TRANSPORT_Handle /** * My configuration. */ - struct GNUNET_CONFIGURATION_Handle *cfg; + const struct GNUNET_CONFIGURATION_Handle *cfg; /** * Linked list of the current neighbours of this peer. @@ -368,7 +378,7 @@ transport_notify_ready (void *cls, size_t size, void *buf) if (buf == NULL) { #if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Could not transmit to transport service, cancelling pending requests\n"); #endif th = h->connect_ready_head; @@ -380,8 +390,15 @@ transport_notify_ready (void *cls, size_t size, void *buf) GNUNET_assert (n->transmit_handle == th); n->transmit_handle = NULL; } + if (th->notify_delay_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (h->sched, + th->notify_delay_task); + th->notify_delay_task = GNUNET_SCHEDULER_NO_TASK; + } GNUNET_assert (0 == th->notify (th->notify_cls, 0, NULL)); GNUNET_free (th); + if (h->connect_ready_head != NULL) schedule_transmission (h); /* FIXME: is this ok? */ return 0; } #if DEBUG_TRANSPORT @@ -395,13 +412,11 @@ transport_notify_ready (void *cls, size_t size, void *buf) do { th = h->connect_ready_head; - if (th->notify_delay_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK) + if (th->notify_delay_task != GNUNET_SCHEDULER_NO_TASK) { - /* remove existing time out task (only applies if - this is not the first iteration of the loop) */ GNUNET_SCHEDULER_cancel (h->sched, th->notify_delay_task); - th->notify_delay_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK; + th->notify_delay_task = GNUNET_SCHEDULER_NO_TASK; } GNUNET_assert (th->notify_size <= size); if (th->next != NULL) @@ -449,13 +464,13 @@ schedule_transmission (struct GNUNET_TRANSPORT_Handle *h) th = h->connect_ready_head; if (th == NULL) return; /* no request pending */ - if (th->notify_delay_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK) + if (th->notify_delay_task != GNUNET_SCHEDULER_NO_TASK) { /* remove existing time out task, will be integrated with transmit_ready notification! */ GNUNET_SCHEDULER_cancel (h->sched, th->notify_delay_task); - th->notify_delay_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK; + th->notify_delay_task = GNUNET_SCHEDULER_NO_TASK; } h->transmission_scheduled = GNUNET_YES; h->network_handle = GNUNET_CLIENT_notify_transmit_ready (h->client, @@ -519,10 +534,10 @@ remove_from_any_list (struct GNUNET_TRANSPORT_TransmitHandle *th) struct GNUNET_TRANSPORT_Handle *h; h = th->handle; - if (th->notify_delay_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK) + if (th->notify_delay_task != GNUNET_SCHEDULER_NO_TASK) { GNUNET_SCHEDULER_cancel (h->sched, th->notify_delay_task); - th->notify_delay_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK; + th->notify_delay_task = GNUNET_SCHEDULER_NO_TASK; } if (th->prev == NULL) { @@ -540,6 +555,18 @@ remove_from_any_list (struct GNUNET_TRANSPORT_TransmitHandle *th) } +/** + * Schedule a request to connect to the given + * neighbour (and if successful, add the specified + * handle to the wait list). + * + * @param th handle for a request to transmit once we + * have connected + */ +static void +try_connect (struct GNUNET_TRANSPORT_TransmitHandle *th); + + /** * Called when our transmit request timed out before any transport * reported success connecting to the desired peer or before the @@ -547,11 +574,11 @@ remove_from_any_list (struct GNUNET_TRANSPORT_TransmitHandle *th) * TransmitHandle. */ static void -transmit_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +peer_transmit_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_TRANSPORT_TransmitHandle *th = cls; - th->notify_delay_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK; + th->notify_delay_task = GNUNET_SCHEDULER_NO_TASK; if (th->neighbour != NULL) th->neighbour->transmit_handle = NULL; #if DEBUG_TRANSPORT @@ -583,7 +610,7 @@ schedule_control_transmit (struct GNUNET_TRANSPORT_Handle *h, size_t size, int at_head, struct GNUNET_TIME_Relative timeout, - GNUNET_NETWORK_TransmitReadyNotify notify, + GNUNET_CONNECTION_TransmitReadyNotify notify, void *notify_cls) { struct GNUNET_TRANSPORT_TransmitHandle *th; @@ -598,9 +625,9 @@ schedule_control_transmit (struct GNUNET_TRANSPORT_Handle *h, = GNUNET_SCHEDULER_add_delayed (h->sched, GNUNET_NO, GNUNET_SCHEDULER_PRIORITY_KEEP, - GNUNET_SCHEDULER_NO_PREREQUISITE_TASK, + GNUNET_SCHEDULER_NO_TASK, timeout, - &transmit_timeout, th); + &peer_transmit_timeout, th); if (at_head) { th->next = h->connect_ready_head; @@ -763,6 +790,27 @@ hello_wait_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) struct HelloWaitList *pos; struct HelloWaitList *prev; + hwl->task = GNUNET_SCHEDULER_NO_TASK; + if (GNUNET_TIME_absolute_get_remaining (hwl->timeout).value > 0) + { +#if DEBUG_TRANSPORT + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + _("First attempt to obtain `%s' from transport service failed, will try again for %llums.\n"), + "HELLO", + GNUNET_TIME_absolute_get_remaining (hwl->timeout).value); +#endif + hwl->task = GNUNET_SCHEDULER_add_delayed (hwl->handle->sched, + GNUNET_YES, + GNUNET_SCHEDULER_PRIORITY_KEEP, + GNUNET_SCHEDULER_NO_TASK, + GNUNET_TIME_absolute_get_remaining (hwl->timeout), + &hello_wait_timeout, hwl); + return; + } + /* signal timeout */ + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("Timeout trying to obtain `%s' from transport service.\n"), + "HELLO"); prev = NULL; pos = hwl->handle->hwl_head; while (pos != hwl) @@ -775,10 +823,6 @@ hello_wait_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) hwl->handle->hwl_head = hwl->next; else prev->next = hwl->next; - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _("Timeout trying to obtain `%s' from transport service.\n"), - "HELLO"); - /* signal timeout */ if (hwl->rec != NULL) hwl->rec (hwl->rec_cls, GNUNET_TIME_UNIT_ZERO, NULL, NULL); GNUNET_free (hwl); @@ -818,7 +862,7 @@ GNUNET_TRANSPORT_get_hello (struct GNUNET_TRANSPORT_Handle *handle, hwl->task = GNUNET_SCHEDULER_add_delayed (handle->sched, GNUNET_YES, GNUNET_SCHEDULER_PRIORITY_KEEP, - GNUNET_SCHEDULER_NO_PREREQUISITE_TASK, + GNUNET_SCHEDULER_NO_TASK, timeout, &hello_wait_timeout, hwl); return; @@ -910,7 +954,7 @@ send_start (void *cls, size_t size, void *buf) if (buf == NULL) { #if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Timeout while trying to transmit `%s' request.\n", "START"); #endif @@ -940,7 +984,7 @@ request_connect (void *cls, size_t size, void *buf) struct TryConnectMessage *tcm; struct GNUNET_TRANSPORT_Handle *h; - GNUNET_assert (th->notify_delay_task == GNUNET_SCHEDULER_NO_PREREQUISITE_TASK); + GNUNET_assert (th->notify_delay_task == GNUNET_SCHEDULER_NO_TASK); h = th->handle; if (buf == NULL) { @@ -950,6 +994,11 @@ request_connect (void *cls, size_t size, void *buf) "TRY_CONNECT", GNUNET_i2s(&th->target)); #endif + if (th->notify_delay_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (h->sched, th->notify_delay_task); + th->notify_delay_task = GNUNET_SCHEDULER_NO_TASK; + } th->notify (th->notify_cls, 0, NULL); GNUNET_free (th); return 0; @@ -969,9 +1018,10 @@ request_connect (void *cls, size_t size, void *buf) = GNUNET_SCHEDULER_add_delayed (h->sched, GNUNET_NO, GNUNET_SCHEDULER_PRIORITY_KEEP, - GNUNET_SCHEDULER_NO_PREREQUISITE_TASK, - GNUNET_TIME_absolute_get_remaining - (th->timeout), &transmit_timeout, th); + GNUNET_SCHEDULER_NO_TASK, + GNUNET_TIME_absolute_get_remaining + (th->timeout), + &peer_transmit_timeout, th); insert_transmit_handle (&h->connect_wait_head, th); return sizeof (struct TryConnectMessage); } @@ -988,7 +1038,7 @@ request_connect (void *cls, size_t size, void *buf) static void try_connect (struct GNUNET_TRANSPORT_TransmitHandle *th) { - GNUNET_assert (th->notify_delay_task == GNUNET_SCHEDULER_NO_PREREQUISITE_TASK); + GNUNET_assert (th->notify_delay_task == GNUNET_SCHEDULER_NO_TASK); schedule_control_transmit (th->handle, sizeof (struct TryConnectMessage), GNUNET_NO, @@ -998,7 +1048,30 @@ try_connect (struct GNUNET_TRANSPORT_TransmitHandle *th) /** - * Remove neighbour from our list + * Task for delayed attempts to reconnect to a peer. + * + * @param cls must be a transmit handle that determines the peer + * to which we will try to connect + * @param tc scheduler information about why we were triggered (not used) + */ +static void +try_connect_task (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct GNUNET_TRANSPORT_TransmitHandle *th = cls; + + th->notify_delay_task = GNUNET_SCHEDULER_NO_TASK; + try_connect (th); +} + + +/** + * Remove neighbour from our list. Will automatically + * trigger a re-connect attempt if we have messages pending + * for this peer. + * + * @param h our state + * @param peer the peer to remove */ static void remove_neighbour (struct GNUNET_TRANSPORT_Handle *h, @@ -1008,10 +1081,17 @@ remove_neighbour (struct GNUNET_TRANSPORT_Handle *h, struct NeighbourList *pos; struct GNUNET_TRANSPORT_TransmitHandle *th; +#if DEBUG_TRANSPORT + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Removing neighbour `%s' from list of connected peers.\n", + GNUNET_i2s (peer)); +#endif prev = NULL; pos = h->neighbours; while ((pos != NULL) && - (0 != memcmp (peer, &pos->id, sizeof (struct GNUNET_PeerIdentity)))) + (0 != memcmp (peer, + &pos->id, + sizeof (struct GNUNET_PeerIdentity)))) { prev = pos; pos = pos->next; @@ -1030,7 +1110,29 @@ remove_neighbour (struct GNUNET_TRANSPORT_Handle *h, pos->transmit_handle = NULL; th->neighbour = NULL; remove_from_any_list (th); - try_connect (th); + if (GNUNET_TIME_absolute_get_remaining (th->timeout).value <= CONNECT_RETRY_TIMEOUT.value) + { + /* signal error */ + GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == th->notify_delay_task); + peer_transmit_timeout (th, NULL); + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Connection with `%4s' failed, will keep trying for %llu ms to deliver message\n"), + GNUNET_i2s (peer), + GNUNET_TIME_absolute_get_remaining (th->timeout).value); + /* try again in a bit */ + GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == th->notify_delay_task); + th->notify_delay_task + = GNUNET_SCHEDULER_add_delayed (h->sched, + GNUNET_NO, + GNUNET_SCHEDULER_PRIORITY_KEEP, + GNUNET_SCHEDULER_NO_TASK, + CONNECT_RETRY_TIMEOUT, + &try_connect_task, + th); + } } if (h->nc_cb != NULL) h->nd_cb (h->cls, peer); @@ -1048,6 +1150,9 @@ reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) struct GNUNET_TRANSPORT_TransmitHandle *pos; struct NeighbourList *n; + fprintf (stderr, + "Trying to reconnect to transport!\n"); + /* Forget about all neighbours that we used to be connected to */ while (NULL != (n = h->neighbours)) @@ -1056,7 +1161,7 @@ reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting to transport service.\n"); #endif GNUNET_assert (h->client == NULL); - h->reconnect_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK; + h->reconnect_task = GNUNET_SCHEDULER_NO_TASK; h->client = GNUNET_CLIENT_connect (h->sched, "transport", h->cfg); GNUNET_assert (h->client != NULL); /* make sure we don't send "START" twice, @@ -1081,7 +1186,8 @@ reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) schedule_control_transmit (h, sizeof (struct GNUNET_MessageHeader), GNUNET_YES, - GNUNET_TIME_UNIT_FOREVER_REL, &send_start, NULL); + GNUNET_TIME_UNIT_FOREVER_REL, + &send_start, NULL); GNUNET_CLIENT_receive (h->client, &demultiplexer, h, GNUNET_TIME_UNIT_FOREVER_REL); } @@ -1100,12 +1206,12 @@ schedule_reconnect (struct GNUNET_TRANSPORT_Handle *h) h->reconnect_delay.value); #endif GNUNET_assert (h->client == NULL); - GNUNET_assert (h->reconnect_task == GNUNET_SCHEDULER_NO_PREREQUISITE_TASK); + GNUNET_assert (h->reconnect_task == GNUNET_SCHEDULER_NO_TASK); h->reconnect_task = GNUNET_SCHEDULER_add_delayed (h->sched, GNUNET_NO, GNUNET_SCHEDULER_PRIORITY_DEFAULT, - GNUNET_SCHEDULER_NO_PREREQUISITE_TASK, + GNUNET_SCHEDULER_NO_TASK, h->reconnect_delay, &reconnect, h); h->reconnect_delay = GNUNET_TIME_UNIT_SECONDS; } @@ -1128,7 +1234,7 @@ transmit_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_TRANSPORT_TransmitHandle *th = cls; - th->notify_delay_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK; + th->notify_delay_task = GNUNET_SCHEDULER_NO_TASK; schedule_request (th); } @@ -1163,10 +1269,10 @@ schedule_request (struct GNUNET_TRANSPORT_TransmitHandle *th) h = th->handle; n = th->neighbour; - if (th->notify_delay_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK) + if (th->notify_delay_task != GNUNET_SCHEDULER_NO_TASK) { GNUNET_SCHEDULER_cancel (h->sched, th->notify_delay_task); - th->notify_delay_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK; + th->notify_delay_task = GNUNET_SCHEDULER_NO_TASK; } /* check outgoing quota */ duration = GNUNET_TIME_absolute_get_duration (n->last_quota_update); @@ -1209,7 +1315,7 @@ schedule_request (struct GNUNET_TRANSPORT_TransmitHandle *th) = GNUNET_SCHEDULER_add_delayed (h->sched, GNUNET_NO, GNUNET_SCHEDULER_PRIORITY_KEEP, - GNUNET_SCHEDULER_NO_PREREQUISITE_TASK, + GNUNET_SCHEDULER_NO_TASK, duration, &transmit_ready, th); return; } @@ -1231,9 +1337,9 @@ schedule_request (struct GNUNET_TRANSPORT_TransmitHandle *th) = GNUNET_SCHEDULER_add_delayed (h->sched, GNUNET_NO, GNUNET_SCHEDULER_PRIORITY_KEEP, - GNUNET_SCHEDULER_NO_PREREQUISITE_TASK, + GNUNET_SCHEDULER_NO_TASK, GNUNET_TIME_absolute_get_remaining - (th->timeout), &transmit_timeout, th); + (th->timeout), &peer_transmit_timeout, th); return; } n->transmit_ok = GNUNET_NO; @@ -1303,10 +1409,10 @@ add_neighbour (struct GNUNET_TRANSPORT_Handle *h, "Found pending request for `%4s' will trigger it now.\n", GNUNET_i2s (&pos->target)); #endif - if (pos->notify_delay_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK) + if (pos->notify_delay_task != GNUNET_SCHEDULER_NO_TASK) { GNUNET_SCHEDULER_cancel (h->sched, pos->notify_delay_task); - pos->notify_delay_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK; + pos->notify_delay_task = GNUNET_SCHEDULER_NO_TASK; } schedule_request (pos); } @@ -1341,7 +1447,7 @@ add_neighbour (struct GNUNET_TRANSPORT_Handle *h, */ struct GNUNET_TRANSPORT_Handle * GNUNET_TRANSPORT_connect (struct GNUNET_SCHEDULER_Handle *sched, - struct GNUNET_CONFIGURATION_Handle *cfg, + const struct GNUNET_CONFIGURATION_Handle *cfg, void *cls, GNUNET_TRANSPORT_ReceiveCallback rec, GNUNET_TRANSPORT_NotifyConnect nc, @@ -1395,21 +1501,23 @@ GNUNET_TRANSPORT_disconnect (struct GNUNET_TRANSPORT_Handle *handle) struct GNUNET_CLIENT_Connection *client; #if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transport disconnect called!\n"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Transport disconnect called!\n"); #endif while (NULL != (th = handle->connect_ready_head)) { handle->connect_ready_head = th->next; + GNUNET_assert (th->notify_delay_task == GNUNET_SCHEDULER_NO_TASK); th->notify (th->notify_cls, 0, NULL); GNUNET_free (th); } while (NULL != (th = handle->connect_wait_head)) { handle->connect_wait_head = th->next; - if (th->notify_delay_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK) + if (th->notify_delay_task != GNUNET_SCHEDULER_NO_TASK) { GNUNET_SCHEDULER_cancel (handle->sched, th->notify_delay_task); - th->notify_delay_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK; + th->notify_delay_task = GNUNET_SCHEDULER_NO_TASK; } th->notify (th->notify_cls, 0, NULL); GNUNET_free (th); @@ -1430,10 +1538,10 @@ GNUNET_TRANSPORT_disconnect (struct GNUNET_TRANSPORT_Handle *handle) hwl->rec (hwl->rec_cls, GNUNET_TIME_UNIT_ZERO, NULL, NULL); GNUNET_free (hwl); } - if (handle->reconnect_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK) + if (handle->reconnect_task != GNUNET_SCHEDULER_NO_TASK) { GNUNET_SCHEDULER_cancel (handle->sched, handle->reconnect_task); - handle->reconnect_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK; + handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK; } GNUNET_free_non_null (handle->my_hello); handle->my_hello = NULL; @@ -1470,7 +1578,6 @@ demultiplexer (void *cls, const struct GNUNET_MessageHeader *msg) const struct SendOkMessage *okm; struct HelloWaitList *hwl; struct NeighbourList *n; - struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey; struct GNUNET_PeerIdentity me; struct GNUNET_TRANSPORT_TransmitHandle *th; uint16_t size; @@ -1485,19 +1592,19 @@ demultiplexer (void *cls, const struct GNUNET_MessageHeader *msg) #endif if (h->network_handle != NULL) { - GNUNET_NETWORK_notify_transmit_ready_cancel (h->network_handle); + GNUNET_CONNECTION_notify_transmit_ready_cancel (h->network_handle); h->network_handle = NULL; h->transmission_scheduled = GNUNET_NO; th = h->connect_ready_head; /* add timeout again, we cancelled the transmit_ready task! */ - GNUNET_assert (th->notify_delay_task == GNUNET_SCHEDULER_NO_PREREQUISITE_TASK); + GNUNET_assert (th->notify_delay_task == GNUNET_SCHEDULER_NO_TASK); th->notify_delay_task = GNUNET_SCHEDULER_add_delayed (h->sched, GNUNET_NO, GNUNET_SCHEDULER_PRIORITY_KEEP, - GNUNET_SCHEDULER_NO_PREREQUISITE_TASK, + GNUNET_SCHEDULER_NO_TASK, GNUNET_TIME_absolute_get_remaining(th->timeout), - &transmit_timeout, + &peer_transmit_timeout, th); } GNUNET_CLIENT_disconnect (h->client); @@ -1519,16 +1626,12 @@ demultiplexer (void *cls, const struct GNUNET_MessageHeader *msg) { case GNUNET_MESSAGE_TYPE_HELLO: if (GNUNET_OK != - GNUNET_HELLO_get_key ((const struct GNUNET_HELLO_Message *) msg, - &pkey)) + GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *) msg, + &me)) { GNUNET_break (0); break; } - GNUNET_CRYPTO_hash (&pkey, - sizeof (struct - GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), - &me.hashPubKey); #if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Receiving (my own) `%s' message, I am `%4s'.\n", @@ -1602,12 +1705,13 @@ demultiplexer (void *cls, const struct GNUNET_MessageHeader *msg) { #if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Processing pending message\n"); + "Processing pending message for `%4s'\n", + GNUNET_i2s(&n->id)); #endif GNUNET_SCHEDULER_cancel (h->sched, n->transmit_handle->notify_delay_task); n->transmit_handle->notify_delay_task = - GNUNET_SCHEDULER_NO_PREREQUISITE_TASK; + GNUNET_SCHEDULER_NO_TASK; GNUNET_assert (GNUNET_YES == n->received_ack); schedule_request (n->transmit_handle); } @@ -1683,7 +1787,7 @@ demultiplexer (void *cls, const struct GNUNET_MessageHeader *msg) struct ClientTransmitWrapper { - GNUNET_NETWORK_TransmitReadyNotify notify; + GNUNET_CONNECTION_TransmitReadyNotify notify; void *notify_cls; struct GNUNET_TRANSPORT_TransmitHandle *th; }; @@ -1737,7 +1841,7 @@ client_notify_wrapper (void *cls, size_t size, void *buf) ret += sizeof (struct OutboundMessage); obm->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SEND); obm->header.size = htons (ret); - obm->reserved = htonl (0); + obm->priority = htonl (ctw->th->priority); obm->peer = ctw->th->target; GNUNET_free (ctw); return ret; @@ -1754,6 +1858,7 @@ client_notify_wrapper (void *cls, size_t size, void *buf) * @param handle connection to transport service * @param target who should receive the message * @param size how big is the message we want to transmit? + * @param priority how important is the message? * @param timeout after how long should we give up (and call * notify with buf NULL and size 0)? * @param notify function to call when we are ready to @@ -1768,8 +1873,9 @@ GNUNET_TRANSPORT_notify_transmit_ready (struct GNUNET_TRANSPORT_Handle *handle, const struct GNUNET_PeerIdentity *target, size_t size, + unsigned int priority, struct GNUNET_TIME_Relative timeout, - GNUNET_NETWORK_TransmitReadyNotify + GNUNET_CONNECTION_TransmitReadyNotify notify, void *notify_cls) { struct GNUNET_TRANSPORT_TransmitHandle *pos; @@ -1789,18 +1895,22 @@ GNUNET_TRANSPORT_notify_transmit_ready (struct GNUNET_TRANSPORT_Handle size, GNUNET_i2s (target)); #endif n = find_neighbour (handle, target); + if ( (n != NULL) && + (n->transmit_handle != NULL) ) + return NULL; /* already have a request pending for this peer! */ ctw = GNUNET_malloc (sizeof (struct ClientTransmitWrapper)); th = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_TransmitHandle)); ctw->notify = notify; ctw->notify_cls = notify_cls; ctw->th = th; th->handle = handle; + th->neighbour = n; th->target = *target; th->notify = &client_notify_wrapper; th->notify_cls = ctw; - th->notify_size = size + sizeof (struct OutboundMessage); th->timeout = GNUNET_TIME_relative_to_absolute (timeout); - th->neighbour = n; + th->notify_size = size + sizeof (struct OutboundMessage); + th->priority = priority; if (NULL == n) { pos = handle->connect_wait_head; @@ -1836,8 +1946,8 @@ GNUNET_TRANSPORT_notify_transmit_ready (struct GNUNET_TRANSPORT_Handle = GNUNET_SCHEDULER_add_delayed (handle->sched, GNUNET_NO, GNUNET_SCHEDULER_PRIORITY_KEEP, - GNUNET_SCHEDULER_NO_PREREQUISITE_TASK, - timeout, &transmit_timeout, th); + GNUNET_SCHEDULER_NO_TASK, + timeout, &peer_transmit_timeout, th); return th; } @@ -1852,8 +1962,7 @@ GNUNET_TRANSPORT_notify_transmit_ready (struct GNUNET_TRANSPORT_Handle /** - * Cancel the specified transmission-ready - * notification. + * Cancel the specified transmission-ready notification. */ void GNUNET_TRANSPORT_notify_transmit_ready_cancel (struct @@ -1873,11 +1982,12 @@ GNUNET_TRANSPORT_notify_transmit_ready_cancel (struct h = th->handle; if ((h->connect_ready_head == NULL) && (h->network_handle != NULL)) { - GNUNET_NETWORK_notify_transmit_ready_cancel (h->network_handle); + GNUNET_CONNECTION_notify_transmit_ready_cancel (h->network_handle); h->network_handle = NULL; h->transmission_scheduled = GNUNET_NO; } GNUNET_free (th->notify_cls); + GNUNET_assert (th->notify_delay_task == GNUNET_SCHEDULER_NO_TASK); GNUNET_free (th); }