From 7d9f187d106394b2451660294df9428eb50e82d7 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 20 Jan 2010 13:51:20 +0000 Subject: fixing core API issues --- src/core/core_api_peer_request.c | 194 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) (limited to 'src/core/core_api_peer_request.c') diff --git a/src/core/core_api_peer_request.c b/src/core/core_api_peer_request.c index e873a5a9d..58837c773 100644 --- a/src/core/core_api_peer_request.c +++ b/src/core/core_api_peer_request.c @@ -28,7 +28,201 @@ #include "core.h" +/** + * Handle for a request to the core to connect or disconnect + * from a particular peer. Can be used to cancel the request + * (before the 'cont'inuation is called). + */ +struct GNUNET_CORE_PeerRequestHandle +{ + + /** + * Our connection to the service. + */ + struct GNUNET_CLIENT_Connection *client; + + /** + * Scheduler. + */ + struct GNUNET_SCHEDULER_Handle *sched; + + /** + * Function to call once done. + */ + GNUNET_SCHEDULER_Task cont; + + /** + * Closure for 'cont'. + */ + void *cont_cls; + + /** + * Identity of the peer to connect/disconnect. + */ + struct GNUNET_PeerIdentity peer; + + /** + * Message type to use. + */ + uint16_t type; +}; + + +/** + * Transmit the request to the core service. + * + * @param cls our 'struct GNUNET_CORE_PeerRequestHandle' + * @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 +send_request (void *cls, + size_t size, + void *buf) +{ + struct GNUNET_CORE_PeerRequestHandle * prh = cls; + struct ConnectMessage msg; + + if (buf == NULL) + { + GNUNET_SCHEDULER_add_continuation (prh->sched, + prh->cont, + prh->cont_cls, + GNUNET_SCHEDULER_REASON_TIMEOUT); + GNUNET_CLIENT_disconnect (prh->client); + GNUNET_free (prh); + return 0; + } + GNUNET_assert (size >= sizeof (struct ConnectMessage)); + msg.header.type = htons (prh->type); + msg.header.size = htons (sizeof (struct ConnectMessage)); + msg.reserved = htonl (0); + msg.peer = prh->peer; + memcpy (buf, &msg, sizeof (msg)); + GNUNET_SCHEDULER_add_continuation (prh->sched, + prh->cont, + prh->cont_cls, + GNUNET_SCHEDULER_REASON_PREREQ_DONE); + GNUNET_CLIENT_disconnect (prh->client); + GNUNET_free (prh); + return sizeof (msg); +} + +/** + * Request that the core should try to connect to a particular peer. + * Once the request has been transmitted to the core, the continuation + * function will be called. Note that this does NOT mean that a + * connection was successfully established -- it only means that the + * core will now try. Successful establishment of the connection + * will be signalled to the 'connects' callback argument of + * 'GNUNET_CORE_connect' only. If the core service does not respond + * to our connection attempt within the given time frame, 'cont' will + * be called with the TIMEOUT reason code. + * + * @param sched scheduler to use + * @param cfg configuration to use + * @param timeout how long to try to talk to core + * @param cont function to call once the request has been completed (or timed out) + * @param cont_cls closure for cont + * @return NULL on error (cont will not be called), otherwise handle for cancellation + */ +struct GNUNET_CORE_PeerRequestHandle * +GNUNET_CORE_peer_request_connect (struct GNUNET_SCHEDULER_Handle *sched, + const struct GNUNET_CONFIGURATION_Handle *cfg, + struct GNUNET_TIME_Relative timeout, + const struct GNUNET_PeerIdentity * peer, + GNUNET_SCHEDULER_Task cont, + void *cont_cls) +{ + struct GNUNET_CORE_PeerRequestHandle *ret; + struct GNUNET_CLIENT_Connection *client; + + client = GNUNET_CLIENT_connect (sched, "core", cfg); + if (client == NULL) + return NULL; + ret = GNUNET_malloc (sizeof (struct GNUNET_CORE_PeerRequestHandle)); + ret->client = client; + ret->sched = sched; + ret->cont = cont; + ret->cont_cls = cont_cls; + ret->peer = *peer; + ret->type = GNUNET_MESSAGE_TYPE_CORE_REQUEST_CONNECT; + GNUNET_CLIENT_notify_transmit_ready (client, + sizeof (struct ConnectMessage), + timeout, + GNUNET_YES, + &send_request, + ret); + return ret; +} + + +/** + * Request that the core should try to disconnect from a particular + * peer. Once the request has been transmitted to the core, the + * continuation function will be called. Note that this does NOT mean + * that a connection was successfully cut -- it only means that the + * core will now try. Typically this will work pretty much + * immediately, but it is at least in theory also possible that a + * reconnect is also triggered rather quickly. Successful creation + * and destruction of connections will be signalled to the 'connects' + * and 'disconnects' callback arguments of 'GNUNET_CORE_connect' only. + * If the core service does not respond to our connection attempt + * within the given time frame, 'cont' will be called with the TIMEOUT + * reason code. + * + * @param sched scheduler to use + * @param cfg configuration to use + * @param timeout how long to try to talk to core + * @param cont function to call once the request has been completed (or timed out) + * @param cont_cls closure for cont + * @return NULL on error (cont will not be called), otherwise handle for cancellation + */ +struct GNUNET_CORE_PeerRequestHandle * +GNUNET_CORE_peer_request_disconnect (struct GNUNET_SCHEDULER_Handle *sched, + const struct GNUNET_CONFIGURATION_Handle *cfg, + struct GNUNET_TIME_Relative timeout, + const struct GNUNET_PeerIdentity * peer, + GNUNET_SCHEDULER_Task cont, + void *cont_cls) +{ + struct GNUNET_CORE_PeerRequestHandle *ret; + struct GNUNET_CLIENT_Connection *client; + + client = GNUNET_CLIENT_connect (sched, "core", cfg); + if (client == NULL) + return NULL; + ret = GNUNET_malloc (sizeof (struct GNUNET_CORE_PeerRequestHandle)); + ret->client = client; + ret->sched = sched; + ret->cont = cont; + ret->cont_cls = cont_cls; + ret->peer = *peer; + ret->type = GNUNET_MESSAGE_TYPE_CORE_REQUEST_DISCONNECT; + GNUNET_CLIENT_notify_transmit_ready (client, + sizeof (struct ConnectMessage), + timeout, + GNUNET_YES, + &send_request, + ret); + return ret; +} + + +/** + * Cancel a pending request to connect or disconnect from/to a particular + * peer. Must not be called after the 'cont' function was invoked. + * + * @param req request handle that was returned for the original request + */ +void +GNUNET_CORE_peer_request_cancel (struct GNUNET_CORE_PeerRequestHandle *req) +{ + GNUNET_CLIENT_disconnect (req->client); + GNUNET_free (req); +} /* end of core_api_peer_request.c */ -- cgit v1.2.3