From 4c630a158187a48ba585167b0ede49bd524d6f8d Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 20 Dec 2014 14:54:49 +0000 Subject: -use separate message types for TRY_CONNECT and TRY_DISCONNECT --- src/include/gnunet_mq_lib.h | 16 +- src/include/gnunet_protocols.h | 7 + src/include/gnunet_transport_service.h | 25 ++- src/transport/gnunet-service-transport_clients.c | 117 ++++++------ src/transport/gnunet-transport.c | 57 +++--- src/transport/transport.h | 31 +++- src/transport/transport_api.c | 215 +++++++++++++++++------ 7 files changed, 317 insertions(+), 151 deletions(-) (limited to 'src') diff --git a/src/include/gnunet_mq_lib.h b/src/include/gnunet_mq_lib.h index ca09e7196..412fde4e7 100644 --- a/src/include/gnunet_mq_lib.h +++ b/src/include/gnunet_mq_lib.h @@ -120,7 +120,9 @@ GNUNET_MQ_extract_nested_mh_ (const struct GNUNET_MessageHeader *mh, * @param nested_mh the message to append to the message after base_size */ struct GNUNET_MQ_Envelope * -GNUNET_MQ_msg_nested_mh_ (struct GNUNET_MessageHeader **mhp, uint16_t base_size, uint16_t type, +GNUNET_MQ_msg_nested_mh_ (struct GNUNET_MessageHeader **mhp, + uint16_t base_size, + uint16_t type, const struct GNUNET_MessageHeader *nested_mh); @@ -199,7 +201,8 @@ typedef void * @param impl_state state of the implementation */ typedef void -(*GNUNET_MQ_DestroyImpl) (struct GNUNET_MQ_Handle *mq, void *impl_state); +(*GNUNET_MQ_DestroyImpl) (struct GNUNET_MQ_Handle *mq, + void *impl_state); /** @@ -209,7 +212,8 @@ typedef void * @param impl_state state specific to the implementation */ typedef void -(*GNUNET_MQ_CancelImpl) (struct GNUNET_MQ_Handle *mq, void *impl_state); +(*GNUNET_MQ_CancelImpl) (struct GNUNET_MQ_Handle *mq, + void *impl_state); /** @@ -328,7 +332,8 @@ GNUNET_MQ_assoc_add (struct GNUNET_MQ_Handle *mq, void *assoc_data); * @return the associated data */ void * -GNUNET_MQ_assoc_get (struct GNUNET_MQ_Handle *mq, uint32_t request_id); +GNUNET_MQ_assoc_get (struct GNUNET_MQ_Handle *mq, + uint32_t request_id); /** @@ -339,7 +344,8 @@ GNUNET_MQ_assoc_get (struct GNUNET_MQ_Handle *mq, uint32_t request_id); * @return the associated data */ void * -GNUNET_MQ_assoc_remove (struct GNUNET_MQ_Handle *mq, uint32_t request_id); +GNUNET_MQ_assoc_remove (struct GNUNET_MQ_Handle *mq, + uint32_t request_id); /** diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index 62f0331d1..5e7b357a6 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h @@ -1359,6 +1359,13 @@ extern "C" */ #define GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PLUGIN_SYNC 390 +/** + * Message for transport service from a client asking that a + * connection with another peer be torn down. + */ +#define GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_DISCONNECT 391 + + /******************************************************************************* * FS-PUBLISH-HELPER IPC Messages ******************************************************************************/ diff --git a/src/include/gnunet_transport_service.h b/src/include/gnunet_transport_service.h index cfa5fdbe0..79fd88f44 100644 --- a/src/include/gnunet_transport_service.h +++ b/src/include/gnunet_transport_service.h @@ -208,6 +208,23 @@ void GNUNET_TRANSPORT_try_connect_cancel (struct GNUNET_TRANSPORT_TryConnectHandle *tch); +/** + * Opaque handle for a transmission-ready request. + */ +struct GNUNET_TRANSPORT_TryDisconnectHandle; + +/** + * Function to call with result of the try connect request. + * + * @param cls closure + * @param result #GNUNET_OK if message was transmitted to transport service + * #GNUNET_SYSERR if message was not transmitted to transport service + */ +typedef void +(*GNUNET_TRANSPORT_TryDisconnectCallback) (void *cls, + int result); + + /** * Ask the transport service to disconnect from the given peer. * @@ -219,10 +236,10 @@ GNUNET_TRANSPORT_try_connect_cancel (struct GNUNET_TRANSPORT_TryConnectHandle *t * @return a `struct GNUNET_TRANSPORT_TryConnectHandle` handle or * NULL on failure (@a cb will not be called) */ -struct GNUNET_TRANSPORT_TryConnectHandle * +struct GNUNET_TRANSPORT_TryDisconnectHandle * GNUNET_TRANSPORT_try_disconnect (struct GNUNET_TRANSPORT_Handle *handle, const struct GNUNET_PeerIdentity *target, - GNUNET_TRANSPORT_TryConnectCallback cb, + GNUNET_TRANSPORT_TryDisconnectCallback cb, void *cb_cls); @@ -230,10 +247,10 @@ GNUNET_TRANSPORT_try_disconnect (struct GNUNET_TRANSPORT_Handle *handle, * Cancel the request to transport to disconnect. * Callback will not be called anymore. * - * @param tch handle for operation to cancel + * @param tdh handle for operation to cancel */ void -GNUNET_TRANSPORT_try_disconnect_cancel (struct GNUNET_TRANSPORT_TryConnectHandle *tch); +GNUNET_TRANSPORT_try_disconnect_cancel (struct GNUNET_TRANSPORT_TryDisconnectHandle *tdh); /* ************************* Sending *************************** */ diff --git a/src/transport/gnunet-service-transport_clients.c b/src/transport/gnunet-service-transport_clients.c index 310121268..77374ff19 100644 --- a/src/transport/gnunet-service-transport_clients.c +++ b/src/transport/gnunet-service-transport_clients.c @@ -790,8 +790,8 @@ clients_handle_send (void *cls, stcc->client = client; GNUNET_SERVER_client_keep (client); GST_manipulation_send (&obm->peer, obmm, msize, - GNUNET_TIME_relative_ntoh (obm->timeout), - &handle_send_transmit_continuation, stcc); + GNUNET_TIME_relative_ntoh (obm->timeout), + &handle_send_transmit_continuation, stcc); } @@ -837,63 +837,71 @@ clients_handle_request_connect (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { - const struct TransportRequestConnectMessage *trcm = - (const struct TransportRequestConnectMessage *) message; - - if (GNUNET_YES == ntohl (trcm->connect)) + const struct TransportRequestConnectMessage *trcm; + + trcm = (const struct TransportRequestConnectMessage *) message; + GNUNET_break (0 == ntohl (trcm->reserved)); + GNUNET_STATISTICS_update (GST_stats, + gettext_noop + ("# REQUEST CONNECT messages received"), 1, + GNUNET_NO); + if (0 == memcmp (&trcm->peer, + &GST_my_identity, + sizeof (struct GNUNET_PeerIdentity))) { - GNUNET_STATISTICS_update (GST_stats, - gettext_noop - ("# REQUEST CONNECT messages received"), 1, - GNUNET_NO); - - if (0 == memcmp (&trcm->peer, &GST_my_identity, - sizeof (struct GNUNET_PeerIdentity))) - { - GNUNET_break_op (0); - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Received a request connect message myself `%s'\n", - GNUNET_i2s (&trcm->peer)); - } - else - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - _("Received a request connect message for peer `%s'\n"), - GNUNET_i2s (&trcm->peer)); - - (void) GST_blacklist_test_allowed (&trcm->peer, NULL, &try_connect_if_allowed, - NULL); - } + GNUNET_break (0); + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Received a request connect message myself `%s'\n", + GNUNET_i2s (&trcm->peer)); + GNUNET_SERVER_receive_done (client, GNUNET_OK); + return; } - else if (GNUNET_NO == ntohl (trcm->connect)) - { - GNUNET_STATISTICS_update (GST_stats, - gettext_noop - ("# REQUEST DISCONNECT messages received"), 1, - GNUNET_NO); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Received a request connect message for peer `%s'\n"), + GNUNET_i2s (&trcm->peer)); + (void) GST_blacklist_test_allowed (&trcm->peer, + NULL, + &try_connect_if_allowed, + NULL); + GNUNET_SERVER_receive_done (client, GNUNET_OK); +} - if (0 == memcmp (&trcm->peer, &GST_my_identity, - sizeof (struct GNUNET_PeerIdentity))) - { - GNUNET_break_op (0); - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Received a request disconnect message myself `%s'\n", - GNUNET_i2s (&trcm->peer)); - } - else - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - _("Received a request disconnect message for peer `%s'\n"), - GNUNET_i2s (&trcm->peer)); - (void) GST_neighbours_force_disconnect (&trcm->peer); - } - } - else + +/** + * Handle request disconnect message + * + * @param cls closure (always NULL) + * @param client identification of the client + * @param message the actual message + */ +static void +clients_handle_request_disconnect (void *cls, + struct GNUNET_SERVER_Client *client, + const struct GNUNET_MessageHeader *message) +{ + const struct TransportRequestDisconnectMessage *trdm; + + trdm = (const struct TransportRequestDisconnectMessage *) message; + GNUNET_break (0 == ntohl (trdm->reserved)); + GNUNET_STATISTICS_update (GST_stats, + gettext_noop + ("# REQUEST DISCONNECT messages received"), 1, + GNUNET_NO); + if (0 == memcmp (&trdm->peer, + &GST_my_identity, + sizeof (struct GNUNET_PeerIdentity))) { - GNUNET_break_op (0); - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + GNUNET_break (0); + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Received a request disconnect message myself `%s'\n", + GNUNET_i2s (&trdm->peer)); + GNUNET_SERVER_receive_done (client, GNUNET_OK); return; } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Received a request disconnect message for peer `%s'\n"), + GNUNET_i2s (&trdm->peer)); + (void) GST_neighbours_force_disconnect (&trdm->peer); GNUNET_SERVER_receive_done (client, GNUNET_OK); } @@ -1515,6 +1523,9 @@ GST_clients_start (struct GNUNET_SERVER_Handle *server) {&clients_handle_request_connect, NULL, GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_CONNECT, sizeof (struct TransportRequestConnectMessage)}, + {&clients_handle_request_disconnect, NULL, + GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_DISCONNECT, + sizeof (struct TransportRequestDisconnectMessage)}, {&clients_handle_address_to_string, NULL, GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_TO_STRING, 0}, {&clients_handle_monitor_peers, NULL, diff --git a/src/transport/gnunet-transport.c b/src/transport/gnunet-transport.c index 7adbf4c32..cd74abde7 100644 --- a/src/transport/gnunet-transport.c +++ b/src/transport/gnunet-transport.c @@ -281,10 +281,15 @@ static struct GNUNET_TRANSPORT_Handle *handle; static struct GNUNET_CONFIGURATION_Handle *cfg; /** - * Try_connect handle + * Try connect handle */ struct GNUNET_TRANSPORT_TryConnectHandle *tc_handle; +/** + * Try disconnect handle + */ +struct GNUNET_TRANSPORT_TryDisconnectHandle *td_handle; + /** * Option -s. */ @@ -1772,11 +1777,9 @@ try_connect_cb (void *cls, { static int retries = 0; + tc_handle = NULL; if (GNUNET_OK == result) - { - tc_handle = NULL; return; - } retries++; if (retries < 10) { @@ -1784,18 +1787,15 @@ try_connect_cb (void *cls, &pid, &try_connect_cb, NULL); - } - else - { - FPRINTF (stderr, - "%s", - _("Failed to send connect request to transport service\n")); - if (GNUNET_SCHEDULER_NO_TASK != end) - GNUNET_SCHEDULER_cancel (end); - ret = 1; - end = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); return; } + FPRINTF (stderr, + "%s", + _("Failed to send connect request to transport service\n")); + if (GNUNET_SCHEDULER_NO_TASK != end) + GNUNET_SCHEDULER_cancel (end); + ret = 1; + end = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); } @@ -1812,27 +1812,25 @@ try_disconnect_cb (void *cls, const int result) { static int retries = 0; + + td_handle = NULL; if (GNUNET_OK == result) - { - tc_handle = NULL; return; - } retries++; if (retries < 10) - tc_handle = GNUNET_TRANSPORT_try_disconnect (handle, + { + td_handle = GNUNET_TRANSPORT_try_disconnect (handle, &pid, &try_disconnect_cb, NULL); - else - { - FPRINTF (stderr, "%s", - _("Failed to send disconnect request to transport service\n")); - if (GNUNET_SCHEDULER_NO_TASK != end) - GNUNET_SCHEDULER_cancel (end); - ret = 1; - end = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); return; } + FPRINTF (stderr, "%s", + _("Failed to send disconnect request to transport service\n")); + if (GNUNET_SCHEDULER_NO_TASK != end) + GNUNET_SCHEDULER_cancel (end); + ret = 1; + end = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); } @@ -1933,9 +1931,10 @@ testservice_task (void *cls, ret = 1; return; } - tc_handle = GNUNET_TRANSPORT_try_disconnect (handle, &pid, try_disconnect_cb, - NULL); - if (NULL == tc_handle) + td_handle = GNUNET_TRANSPORT_try_disconnect (handle, &pid, + &try_disconnect_cb, + NULL); + if (NULL == td_handle) { FPRINTF (stderr, "%s", _("Failed to send request to transport service\n")); diff --git a/src/transport/transport.h b/src/transport/transport.h index 01d1b1722..af6e16ece 100644 --- a/src/transport/transport.h +++ b/src/transport/transport.h @@ -163,6 +163,7 @@ struct DisconnectInfoMessage }; + /** * Message type for sending a request connect message * to the transport service. Must be done before transport @@ -172,14 +173,14 @@ struct DisconnectInfoMessage struct TransportRequestConnectMessage { /** - * Message header + * Message header with type #GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_CONNECT */ struct GNUNET_MessageHeader header; /** - * Connect (#GNUNET_YES) or connect (#GNUNET_NO). + * Reserved (0). */ - uint32_t connect; + uint32_t reserved GNUNET_PACKED; /** * Identity of the peer we would like to connect to. @@ -187,6 +188,30 @@ struct TransportRequestConnectMessage struct GNUNET_PeerIdentity peer; }; + +/** + * Message type for sending a request connection to + * a peer to be torn down. + */ +struct TransportRequestDisconnectMessage +{ + /** + * Message header with type #GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_DISCONNECT + */ + struct GNUNET_MessageHeader header; + + /** + * Reserved (0). + */ + uint32_t reserved GNUNET_PACKED; + + /** + * Identity of the peer we would like to connect to. + */ + struct GNUNET_PeerIdentity peer; +}; + + /** * Message used to set a particular bandwidth quota. Sent TO the * service to set an incoming quota, sent FROM the service to update diff --git a/src/transport/transport_api.c b/src/transport/transport_api.c index 3c57a83a0..4e8d2c8ea 100644 --- a/src/transport/transport_api.c +++ b/src/transport/transport_api.c @@ -65,13 +65,13 @@ struct GNUNET_TRANSPORT_TransmitHandle struct Neighbour *neighbour; /** - * Function to call when notify_size bytes are available + * Function to call when @e notify_size bytes are available * for transmission. */ GNUNET_TRANSPORT_TransmitReadyNotify notify; /** - * Closure for notify. + * Closure for @e notify. */ void *notify_cls; @@ -95,7 +95,7 @@ struct GNUNET_TRANSPORT_TransmitHandle /** - * Entry in hash table of all of our current neighbours. + * Entry in hash table of all of our current (connected) neighbours. */ struct Neighbour { @@ -120,11 +120,11 @@ struct Neighbour struct GNUNET_BANDWIDTH_Tracker out_tracker; /** - * Entry in our readyness heap (which is sorted by 'next_ready' + * Entry in our readyness heap (which is sorted by @e next_ready * value). NULL if there is no pending transmission request for - * this neighbour or if we're waiting for 'is_ready' to become - * true AFTER the 'out_tracker' suggested that this peer's quota - * has been satisfied (so once 'is_ready' goes to GNUNET_YES, + * this neighbour or if we're waiting for @e is_ready to become + * true AFTER the @e out_tracker suggested that this peer's quota + * has been satisfied (so once @e is_ready goes to #GNUNET_YES, * we should immediately go back into the heap). */ struct GNUNET_CONTAINER_HeapNode *hn; @@ -180,8 +180,9 @@ struct GNUNET_TRANSPORT_GetHelloHandle }; + /** - * Linked list for all try-connect requests + * Entry in linked list for a try-connect request. */ struct GNUNET_TRANSPORT_TryConnectHandle { @@ -196,22 +197,22 @@ struct GNUNET_TRANSPORT_TryConnectHandle struct GNUNET_TRANSPORT_TryConnectHandle *next; /** - * + * Peer we should try to connect to. */ struct GNUNET_PeerIdentity pid; /** - * + * Transport service handle this request is part of. */ struct GNUNET_TRANSPORT_Handle *th; /** - * + * Message transmission request to communicate to service. */ struct GNUNET_TRANSPORT_TransmitHandle *tth; /** - * + * Function to call upon completion (of request transmission). */ GNUNET_TRANSPORT_TryConnectCallback cb; @@ -220,16 +221,54 @@ struct GNUNET_TRANSPORT_TryConnectHandle */ void *cb_cls; +}; + + +/** + * Entry in linked list for all try-disconnect requests + */ +struct GNUNET_TRANSPORT_TryDisconnectHandle +{ + /** + * For the DLL. + */ + struct GNUNET_TRANSPORT_TryDisconnectHandle *prev; + /** - * + * For the DLL. + */ + struct GNUNET_TRANSPORT_TryDisconnectHandle *next; + + /** + * Peer we should try to connect to. */ - int connect; + struct GNUNET_PeerIdentity pid; + + /** + * Transport service handle this request is part of. + */ + struct GNUNET_TRANSPORT_Handle *th; + + /** + * Message transmission request to communicate to service. + */ + struct GNUNET_TRANSPORT_TransmitHandle *tth; + + /** + * Function to call upon completion (of request transmission). + */ + GNUNET_TRANSPORT_TryDisconnectCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; }; /** - * Linked list for all try-connect requests + * Entry in linked list for all offer-HELLO requests. */ struct GNUNET_TRANSPORT_OfferHelloHandle { @@ -244,17 +283,17 @@ struct GNUNET_TRANSPORT_OfferHelloHandle struct GNUNET_TRANSPORT_OfferHelloHandle *next; /** - * + * Transport service handle we use for transmission. */ struct GNUNET_TRANSPORT_Handle *th; /** - * + * Transmission handle for this request. */ struct GNUNET_TRANSPORT_TransmitHandle *tth; /** - * + * Function to call once we are done. */ GNUNET_SCHEDULER_Task cont; @@ -264,7 +303,7 @@ struct GNUNET_TRANSPORT_OfferHelloHandle void *cls; /** - * + * The HELLO message to be transmitted. */ struct GNUNET_MessageHeader *msg; }; @@ -348,6 +387,16 @@ struct GNUNET_TRANSPORT_Handle */ struct GNUNET_TRANSPORT_TryConnectHandle *tc_tail; + /** + * Linked list of pending try disconnect requests head + */ + struct GNUNET_TRANSPORT_TryDisconnectHandle *td_head; + + /** + * Linked list of pending try connect requests tail + */ + struct GNUNET_TRANSPORT_TryDisconnectHandle *td_tail; + /** * Linked list of pending offer HELLO requests head */ @@ -1163,29 +1212,33 @@ cancel_control_transmit (struct GNUNET_TRANSPORT_Handle *th, /** - * Send REQUEST_CONNECT message to the service. + * Send #GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_CONNECT message to the + * service. * - * @param cls the `struct GNUNET_PeerIdentity` + * @param cls the `struct GNUNET_TRANSPORT_TryConnectHandle` * @param size number of bytes available in @a buf * @param buf where to copy the message * @return number of bytes copied to @a buf */ static size_t -send_try_connect (void *cls, size_t size, void *buf) +send_try_connect (void *cls, + size_t size, + void *buf) { struct GNUNET_TRANSPORT_TryConnectHandle *tch = cls; struct TransportRequestConnectMessage msg; + tch->tth = NULL; if (NULL == buf) { - if (NULL != tch->cb) - tch->cb (tch->cb_cls, GNUNET_SYSERR); - GNUNET_CONTAINER_DLL_remove (tch->th->tc_head, tch->th->tc_tail, tch); LOG (GNUNET_ERROR_TYPE_DEBUG, "Discarding `%s' request to `%4s' due to error in transport service connection.\n", "REQUEST_CONNECT", GNUNET_i2s (&tch->pid)); - GNUNET_free (tch); + if (NULL != tch->cb) + tch->cb (tch->cb_cls, + GNUNET_SYSERR); + GNUNET_TRANSPORT_try_connect_cancel (tch); return 0; } LOG (GNUNET_ERROR_TYPE_DEBUG, @@ -1195,13 +1248,12 @@ send_try_connect (void *cls, size_t size, void *buf) GNUNET_assert (size >= sizeof (struct TransportRequestConnectMessage)); msg.header.size = htons (sizeof (struct TransportRequestConnectMessage)); msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_CONNECT); - msg.connect = htonl (tch->connect); + msg.reserved = htonl (0); msg.peer = tch->pid; memcpy (buf, &msg, sizeof (msg)); if (NULL != tch->cb) tch->cb (tch->cb_cls, GNUNET_OK); - GNUNET_CONTAINER_DLL_remove (tch->th->tc_head, tch->th->tc_tail, tch); - GNUNET_free (tch); + GNUNET_TRANSPORT_try_connect_cancel (tch); return sizeof (struct TransportRequestConnectMessage); } @@ -1233,7 +1285,6 @@ GNUNET_TRANSPORT_try_connect (struct GNUNET_TRANSPORT_Handle *handle, tch->pid = *(target); tch->cb = cb; tch->cb_cls = cb_cls; - tch->connect = GNUNET_YES; tch->tth = schedule_control_transmit (handle, sizeof (struct TransportRequestConnectMessage), &send_try_connect, tch); @@ -1254,15 +1305,64 @@ void GNUNET_TRANSPORT_try_connect_cancel (struct GNUNET_TRANSPORT_TryConnectHandle *tch) { struct GNUNET_TRANSPORT_Handle *th; - GNUNET_assert (GNUNET_YES == tch->connect); th = tch->th; - cancel_control_transmit (th, tch->tth); - GNUNET_CONTAINER_DLL_remove (th->tc_head, th->tc_tail, tch); + if (NULL != tch->tth) + cancel_control_transmit (th, tch->tth); + GNUNET_CONTAINER_DLL_remove (th->tc_head, + th->tc_tail, + tch); GNUNET_free (tch); } +/** + * Send #GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_DISCONNECT message to the + * service. + * + * @param cls the `struct GNUNET_TRANSPORT_TryDisconnectHandle` + * @param size number of bytes available in @a buf + * @param buf where to copy the message + * @return number of bytes copied to @a buf + */ +static size_t +send_try_disconnect (void *cls, + size_t size, + void *buf) +{ + struct GNUNET_TRANSPORT_TryDisconnectHandle *tdh = cls; + struct TransportRequestConnectMessage msg; + + tdh->th = NULL; + if (NULL == buf) + { + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Discarding `%s' request to `%4s' due to error in transport service connection.\n", + "REQUEST_DISCONNECT", + GNUNET_i2s (&tdh->pid)); + if (NULL != tdh->cb) + tdh->cb (tdh->cb_cls, + GNUNET_SYSERR); + GNUNET_TRANSPORT_try_disconnect_cancel (tdh); + return 0; + } + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Transmitting `%s' request with respect to `%4s'.\n", + "REQUEST_DISCONNECT", + GNUNET_i2s (&tdh->pid)); + GNUNET_assert (size >= sizeof (struct TransportRequestDisconnectMessage)); + msg.header.size = htons (sizeof (struct TransportRequestDisconnectMessage)); + msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_DISCONNECT); + msg.reserved = htonl (0); + msg.peer = tdh->pid; + memcpy (buf, &msg, sizeof (msg)); + if (NULL != tdh->cb) + tdh->cb (tdh->cb_cls, GNUNET_OK); + GNUNET_TRANSPORT_try_disconnect_cancel (tdh); + return sizeof (struct TransportRequestDisconnectMessage); +} + + /** * Ask the transport service to shutdown a connection to * the given peer. @@ -1272,32 +1372,31 @@ GNUNET_TRANSPORT_try_connect_cancel (struct GNUNET_TRANSPORT_TryConnectHandle *t * @param cb callback to be called when request was transmitted to transport * service * @param cb_cls closure for the callback @a cb - * @return a `struct GNUNET_TRANSPORT_TryConnectHandle` handle or + * @return a `struct GNUNET_TRANSPORT_TryDisconnectHandle` handle or * NULL on failure (cb will not be called) */ -struct GNUNET_TRANSPORT_TryConnectHandle * +struct GNUNET_TRANSPORT_TryDisconnectHandle * GNUNET_TRANSPORT_try_disconnect (struct GNUNET_TRANSPORT_Handle *handle, const struct GNUNET_PeerIdentity *target, - GNUNET_TRANSPORT_TryConnectCallback cb, + GNUNET_TRANSPORT_TryDisconnectCallback cb, void *cb_cls) { - struct GNUNET_TRANSPORT_TryConnectHandle *tch; + struct GNUNET_TRANSPORT_TryDisconnectHandle *tdh; if (NULL == handle->client) return NULL; - tch = GNUNET_new (struct GNUNET_TRANSPORT_TryConnectHandle); - tch->th = handle; - tch->pid = *(target); - tch->cb = cb; - tch->cb_cls = cb_cls; - tch->connect = GNUNET_NO; - tch->tth = schedule_control_transmit (handle, - sizeof (struct TransportRequestConnectMessage), - &send_try_connect, tch); - GNUNET_CONTAINER_DLL_insert (handle->tc_head, - handle->tc_tail, - tch); - return tch; + tdh = GNUNET_new (struct GNUNET_TRANSPORT_TryDisconnectHandle); + tdh->th = handle; + tdh->pid = *(target); + tdh->cb = cb; + tdh->cb_cls = cb_cls; + tdh->tth = schedule_control_transmit (handle, + sizeof (struct TransportRequestDisconnectMessage), + &send_try_disconnect, tdh); + GNUNET_CONTAINER_DLL_insert (handle->td_head, + handle->td_tail, + tdh); + return tdh; } @@ -1305,18 +1404,20 @@ GNUNET_TRANSPORT_try_disconnect (struct GNUNET_TRANSPORT_Handle *handle, * Cancel the request to transport to try a disconnect * Callback will not be called * - * @param tch the handle to cancel + * @param tdh the handle to cancel */ void -GNUNET_TRANSPORT_try_disconnect_cancel (struct GNUNET_TRANSPORT_TryConnectHandle *tch) +GNUNET_TRANSPORT_try_disconnect_cancel (struct GNUNET_TRANSPORT_TryDisconnectHandle *tdh) { struct GNUNET_TRANSPORT_Handle *th; - GNUNET_assert (GNUNET_NO == tch->connect); - th = tch->th; - cancel_control_transmit (th, tch->tth); - GNUNET_CONTAINER_DLL_remove (th->tc_head, th->tc_tail, tch); - GNUNET_free (tch); + th = tdh->th; + if (NULL != tdh->tth) + cancel_control_transmit (th, tdh->tth); + GNUNET_CONTAINER_DLL_remove (th->td_head, + th->td_tail, + tdh); + GNUNET_free (tdh); } -- cgit v1.2.3