- better tracking of which config changes actually need to cause process restarts by ARM.
- have way to specify dependencies between services (to manage ARM restarts better)
* CORE:
- - code currently notifies clients about "encrypted" connections being up well before
- we get the encrypted PONG; sometimes this may be OK (for topology killing
- unwanted connnections), but of course not in general. I suspect we want
- to signal on PONG and have topology hook directly into transport to
- kill plaintext connections before they have a chance to become encrypted
- (may require minor hack in transport API)
+ - test case (test_core_api) hangs for a while (some timeout task not killed somewhere?)
- [./core/gnunet-service-core.c:469]: (style) struct or union member 'Neighbour::message_queue_size' is never used
- [./core/test_core_api_start_only.c:50]: (style) struct or union member 'PeerContext::id' is never used
* UPNP [Milan]
Urgent items (before announcing ng.gnunet.org):
+* CORE:
+ - test currently fails spectacularly
+ - request disconnect not implemented (needs better transport API)
* topology
- - considers peers 'connected' well before they actually are
- (since core notifies about it too early?);
- (forced) disconnect does not work (also CORE API issue)
- needs testing (not sure the current testcase does much...)
* hostlist
- test fails (looks like it works, but that's because of a bad
connectivity notification; somehow core is unable to send
messages successfully via transport)
-* CORE:
- - core notifies about connects "too early" (when we have not yet
- succeeded with the full key exchange) [see also: BUGS]
* FS (basic anonymous FS only)
- implement FS service (P2P operations)
+ how to send queries (soliciting is not there in core; do we
[=> eliminate for need to tell ARM about service starts most of the time!]
* HELLO:
- need function to test "equivalency" of HELLOs; use in topology!
+* CORE:
+ - outbound message monitoring not supported
* Module features to implement:
- advanced FS API parts
+ namespaces: fundamental namespace API
* transmitted to the client.
*/
#define GNUNET_CORE_OPTION_NOTHING 0
-#define GNUNET_CORE_OPTION_SEND_CONNECT 1
-#define GNUNET_CORE_OPTION_SEND_DISCONNECT 2
-#define GNUNET_CORE_OPTION_SEND_FULL_INBOUND 4
-#define GNUNET_CORE_OPTION_SEND_HDR_INBOUND 8
-#define GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND 16
-#define GNUNET_CORE_OPTION_SEND_HDR_OUTBOUND 32
+#define GNUNET_CORE_OPTION_SEND_PRE_CONNECT 1
+#define GNUNET_CORE_OPTION_SEND_CONNECT 2
+#define GNUNET_CORE_OPTION_SEND_DISCONNECT 4
+#define GNUNET_CORE_OPTION_SEND_FULL_INBOUND 8
+#define GNUNET_CORE_OPTION_SEND_HDR_INBOUND 16
+#define GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND 32
+#define GNUNET_CORE_OPTION_SEND_HDR_OUTBOUND 64
/**
};
+/**
+ * Client asking core to transmit a particular message to a particular
+ * target. There is no response from the core to this type of request
+ * (however, if an actual connection is created or destroyed, be it
+ * because of this type request or not, the core generally needs to
+ * notify the clients).
+ */
+struct ConnectMessage
+{
+ /**
+ * Header with type GNUNET_MESSAGE_TYPE_REQUEST_CONNECT or
+ * GNUNET_MESSAGE_TYPE_REQUEST_DISCONNECT.
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * For alignment.
+ */
+ uint32_t reserved GNUNET_PACKED;
+
+ /**
+ * Identity of the other peer.
+ */
+ struct GNUNET_PeerIdentity peer;
+
+};
+
/* end of core.h */
*/
GNUNET_CORE_StartupCallback init;
+ /**
+ * Function to call whenever we're notified about a peer connecting
+ * (pre-connects, no session key exchange yet).
+ */
+ GNUNET_CORE_ClientEventHandler pre_connects;
+
/**
* Function to call whenever we're notified about a peer connecting.
*/
#endif
switch (ntohs (msg->type))
{
+ case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_PRE_CONNECT:
+ if (NULL == h->pre_connects)
+ {
+ GNUNET_break (0);
+ break;
+ }
+ if (msize != sizeof (struct ConnectNotifyMessage))
+ {
+ GNUNET_break (0);
+ break;
+ }
+ cnm = (const struct ConnectNotifyMessage *) msg;
+ h->pre_connects (h->cls,
+ &cnm->peer);
+ break;
case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT:
if (NULL == h->connects)
{
init->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_INIT);
init->header.size = htons (msize);
opt = GNUNET_CORE_OPTION_NOTHING;
+ if (h->pre_connects != NULL)
+ opt |= GNUNET_CORE_OPTION_SEND_PRE_CONNECT;
if (h->connects != NULL)
opt |= GNUNET_CORE_OPTION_SEND_CONNECT;
if (h->disconnects != NULL)
* @param cls closure for the various callbacks that follow (including handlers in the handlers array)
* @param init callback to call on timeout or once we have successfully
* connected to the core service; note that timeout is only meaningful if init is not NULL
+ * @param pre_connects function to call on peer pre-connect (no session key yet), can be 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 inbound_notify function to call for all inbound messages, can be NULL
struct GNUNET_TIME_Relative timeout,
void *cls,
GNUNET_CORE_StartupCallback init,
+ GNUNET_CORE_ClientEventHandler pre_connects,
GNUNET_CORE_ClientEventHandler connects,
GNUNET_CORE_ClientEventHandler disconnects,
GNUNET_CORE_MessageCallback inbound_notify,
h->cfg = cfg;
h->cls = cls;
h->init = init;
+ h->pre_connects = pre_connects;
h->connects = connects;
h->disconnects = disconnects;
h->inbound_notify = inbound_notify;
#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 */
* @brief high-level P2P messaging
* @author Christian Grothoff
*
+ * TODO:
+ * - not all GNUNET_CORE_OPTION_SEND_* flags are fully supported yet
+ * (i.e. no SEND_XXX_OUTBOUND).
+ * - 'REQUEST_DISCONNECT' is not implemented (transport API is lacking!)
+ *
* Considerations for later:
* - check that hostkey used by transport (for HELLOs) is the
* same as the hostkey that we are using!
* Send a message to all of our current clients.
*/
static void
-send_to_all_clients (const struct GNUNET_MessageHeader *msg, int can_drop)
+send_to_all_clients (const struct GNUNET_MessageHeader *msg,
+ int can_drop,
+ int options)
{
struct Client *c;
c = clients;
while (c != NULL)
{
- send_to_client (c, msg, can_drop);
+ if (0 != (c->options & options))
+ send_to_client (c, msg, can_drop);
c = c->next;
}
}
}
+/**
+ * Handle CORE_REQUEST_CONNECT request.
+ *
+ * @param cls unused
+ * @param client the client issuing the request
+ * @param message the "struct ConnectMessage"
+ */
+static void
+handle_client_request_connect (void *cls,
+ struct GNUNET_SERVER_Client *client,
+ const struct GNUNET_MessageHeader *message)
+{
+ const struct ConnectMessage *cm = (const struct ConnectMessage*) message;
+ struct Neighbour *n;
+
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ n = find_neighbour (&cm->peer);
+ if (n != NULL)
+ return; /* already connected, or at least trying */
+#if DEBUG_CORE
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Core received `%s' request for `%4s', will try to establish connection\n",
+ "REQUEST_CONNECT",
+ GNUNET_i2s (&cm->peer));
+#endif
+ /* ask transport to connect to the peer */
+ /* FIXME: timeout zero OK? need for cancellation? */
+ GNUNET_TRANSPORT_notify_transmit_ready (transport,
+ &cm->peer,
+ 0, 0,
+ GNUNET_TIME_UNIT_ZERO,
+ NULL,
+ NULL);
+}
+
+
+/**
+ * Handle CORE_REQUEST_DISCONNECT request.
+ *
+ * @param cls unused
+ * @param client the client issuing the request
+ * @param message the "struct ConnectMessage"
+ */
+static void
+handle_client_request_disconnect (void *cls,
+ struct GNUNET_SERVER_Client *client,
+ const struct GNUNET_MessageHeader *message)
+{
+ const struct ConnectMessage *cm = (const struct ConnectMessage*) message;
+ struct Neighbour *n;
+
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ n = find_neighbour (&cm->peer);
+ if (n == NULL)
+ return; /* done */
+ /* FIXME: implement disconnect! */
+}
+
+
+
/**
* List of handlers for the messages understood by this
* service.
sizeof (struct RequestInfoMessage)},
{&handle_client_send, NULL,
GNUNET_MESSAGE_TYPE_CORE_SEND, 0},
+ {&handle_client_request_connect, NULL,
+ GNUNET_MESSAGE_TYPE_CORE_REQUEST_CONNECT,
+ sizeof (struct ConnectMessage)},
+ {&handle_client_request_disconnect, NULL,
+ GNUNET_MESSAGE_TYPE_CORE_REQUEST_DISCONNECT,
+ sizeof (struct ConnectMessage)},
{NULL, NULL, 0, 0}
};
/**
- * PEERINFO is giving us a HELLO for a peer. Add the
- * public key to the neighbour's struct and retry
- * send_key. Or, if we did not get a HELLO, just do
- * nothing.
+ * PEERINFO is giving us a HELLO for a peer. Add the public key to
+ * the neighbour's struct and retry send_key. Or, if we did not get a
+ * HELLO, just do nothing.
*
* @param cls NULL
* @param peer the peer for which this is the HELLO
struct PingMessage pp;
struct PingMessage *pm;
+ if ( (n->retry_set_key_task != GNUNET_SCHEDULER_NO_TASK) ||
+ (n->pitr != NULL) )
+ return; /* already in progress */
#if DEBUG_CORE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Asked to perform key exchange with `%4s'.\n",
handle_pong (struct Neighbour *n, const struct PingMessage *m)
{
struct PingMessage t;
+ struct ConnectNotifyMessage cnm;
#if DEBUG_CORE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
{
GNUNET_SCHEDULER_cancel (sched, n->retry_set_key_task);
n->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK;
- }
+ }
+ cnm.header.size = htons (sizeof (struct ConnectNotifyMessage));
+ cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
+ cnm.reserved = htonl (0);
+ cnm.peer = n->peer;
+ send_to_all_clients (&cnm.header, GNUNET_YES, GNUNET_CORE_OPTION_SEND_CONNECT);
process_encrypted_neighbour_queue (n);
break;
case PEER_STATE_KEY_CONFIRMED:
while (cpos != NULL)
{
deliver_full = GNUNET_NO;
- if (cpos->options & GNUNET_CORE_OPTION_SEND_FULL_INBOUND)
+ if (0 != (cpos->options & GNUNET_CORE_OPTION_SEND_FULL_INBOUND))
deliver_full = GNUNET_YES;
else
{
#endif
schedule_quota_update (n);
cnm.header.size = htons (sizeof (struct ConnectNotifyMessage));
- cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
+ cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_PRE_CONNECT);
cnm.reserved = htonl (0);
cnm.peer = *peer;
- send_to_all_clients (&cnm.header, GNUNET_YES);
+ send_to_all_clients (&cnm.header, GNUNET_YES, GNUNET_CORE_OPTION_SEND_PRE_CONNECT);
+ send_key (n);
}
cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT);
cnm.reserved = htonl (0);
cnm.peer = *peer;
- send_to_all_clients (&cnm.header, GNUNET_YES);
+ send_to_all_clients (&cnm.header, GNUNET_YES, GNUNET_CORE_OPTION_SEND_DISCONNECT);
free_neighbour (n);
}
TIMEOUT,
&p2,
&init_notify,
+ NULL,
&connect_notify,
&disconnect_notify,
&inbound_notify,
TIMEOUT,
&p1,
&init_notify,
+ NULL,
&connect_notify,
&disconnect_notify,
&inbound_notify,
TIMEOUT,
&p2,
&init_notify,
+ NULL,
&connect_notify,
&disconnect_notify,
&inbound_notify,
TIMEOUT,
&p1,
&init_notify,
+ NULL,
&connect_notify,
&disconnect_notify,
&inbound_notify,
GNUNET_TIME_UNIT_FOREVER_REL,
NULL,
NULL,
+ NULL,
&peer_connect_handler,
&peer_disconnect_handler,
NULL, GNUNET_NO,
GNUNET_TIME_UNIT_FOREVER_REL,
NULL,
&core_init,
- ch, dh,
+ NULL, ch, dh,
NULL, GNUNET_NO,
NULL, GNUNET_NO,
handlers);
* @param cls closure for the various callbacks that follow (including handlers in the handlers array)
* @param init callback to call on timeout or once we have successfully
* connected to the core service; note that timeout is only meaningful if init is not NULL
+ * @param pre_connects function to call on peer pre-connect (no session key yet), can be 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 inbound_notify function to call for all inbound messages, can be NULL
struct GNUNET_TIME_Relative timeout,
void *cls,
GNUNET_CORE_StartupCallback init,
+ GNUNET_CORE_ClientEventHandler pre_connects,
GNUNET_CORE_ClientEventHandler connects,
GNUNET_CORE_ClientEventHandler disconnects,
GNUNET_CORE_MessageCallback inbound_notify,
void GNUNET_CORE_disconnect (struct GNUNET_CORE_Handle *handle);
-// FIXME
+/**
+ * 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;
-// FIXME
+
+/**
+ * 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,
- const struct GNUNET_PeerIdentity * peer,
- GNUNET_SCHEDULER_Task cont,
- void *cont_cls);
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
+ struct GNUNET_TIME_Relative timeout,
+ const struct GNUNET_PeerIdentity * peer,
+ GNUNET_SCHEDULER_Task cont,
+ void *cont_cls);
-// FIXME
+/**
+ * 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,
- const struct GNUNET_PeerIdentity * peer,
- GNUNET_SCHEDULER_Task cont,
- void *cont_cls);
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
+ struct GNUNET_TIME_Relative timeout,
+ const struct GNUNET_PeerIdentity * peer,
+ GNUNET_SCHEDULER_Task cont,
+ void *cont_cls);
-// FIXME
+
+/**
+ * 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);
#define GNUNET_MESSAGE_TYPE_CORE_INIT_REPLY 65
/**
- * Notify clients about new peer-to-peer connections.
+ * Notify clients about new peer-to-peer connections (before
+ * key exchange and authentication).
*/
-#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT 66
+#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_PRE_CONNECT 66
+
+/**
+ * Notify clients about new peer-to-peer connections (triggered
+ * after key exchange).
+ */
+#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT 67
/**
* Notify clients about peer disconnecting.
*/
-#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT 67
+#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT 68
/**
* Notify clients about incoming P2P messages.
*/
-#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND 68
+#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND 69
/**
* Notify clients about outgoing P2P transmissions.
*/
-#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND 69
+#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND 70
/**
* Request from client to "configure" P2P connection.
*/
-#define GNUNET_MESSAGE_TYPE_CORE_REQUEST_INFO 70
+#define GNUNET_MESSAGE_TYPE_CORE_REQUEST_INFO 71
/**
* Response from server about (possibly updated) P2P
* connection configuration.
*/
-#define GNUNET_MESSAGE_TYPE_CORE_CONFIGURATION_INFO 71
+#define GNUNET_MESSAGE_TYPE_CORE_CONFIGURATION_INFO 72
/**
* Request from client with message to transmit.
*/
-#define GNUNET_MESSAGE_TYPE_CORE_SEND 72
+#define GNUNET_MESSAGE_TYPE_CORE_SEND 73
+
+/**
+ * Request from client asking to connect to a peer.
+ */
+#define GNUNET_MESSAGE_TYPE_CORE_REQUEST_CONNECT 74
+
+/**
+ * Request from client asking to disconnect from a peer.
+ */
+#define GNUNET_MESSAGE_TYPE_CORE_REQUEST_DISCONNECT 75
/**
*
* @param handle connection to transport service
* @param target who's bandwidth quota is being changed
- * @param quota_in incoming bandwidth quota in bytes per ms; 0 can
- * be used to force all traffic to be discarded
- * @param quota_out outgoing bandwidth quota in bytes per ms; 0 can
- * be used to force all traffic to be discarded
+ * @param quota_in incoming bandwidth quota in bytes per ms
+ * @param quota_out outgoing bandwidth quota in bytes per ms
* @param timeout how long to wait until signaling failure if
* we can not communicate the quota change
* @param cont continuation to call when done, will be called
/**
- * Cancel the specified transmission-ready
- * notification.
+ * Cancel the specified transmission-ready notification.
+ *
+ * @param h handle of the transmission notification request to cancel
*/
void
GNUNET_TRANSPORT_notify_transmit_ready_cancel (struct
ARM_START_WAIT,
d,
&testing_init,
- NULL, NULL,
+ NULL, NULL, NULL,
NULL, GNUNET_NO,
NULL, GNUNET_NO,
no_handlers);
GNUNET_TIME_UNIT_FOREVER_REL,
NULL,
&core_init,
+ NULL,
&connect_notify,
&disconnect_notify,
NULL, GNUNET_NO,
* @file transport/transport_api.c
* @brief library to access the low-level P2P IO service
* @author Christian Grothoff
- *
- * TODO:
- * - set_quota with low bandwidth should cause peer
- * disconnects (currently never does that) (MINOR)
*/
#include "platform.h"
#include "gnunet_client_lib.h"
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));
+ if (NULL != th->notify)
+ 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? */
GNUNET_assert (n->transmit_handle == th);
n->transmit_handle = NULL;
}
- ret += th->notify (th->notify_cls, size, &cbuf[ret]);
+ if (NULL != th->notify)
+ ret += th->notify (th->notify_cls, size, &cbuf[ret]);
GNUNET_free (th);
if (n != NULL)
n->last_sent += ret;
GNUNET_i2s (&th->target));
#endif
remove_from_any_list (th);
- th->notify (th->notify_cls, 0, NULL);
+ if (NULL != th->notify)
+ th->notify (th->notify_cls, 0, NULL);
GNUNET_free (th);
}
*
* @param handle connection to transport service
* @param target who's bandwidth quota is being changed
- * @param quota_in incoming bandwidth quota in bytes per ms; 0 can
- * be used to force all traffic to be discarded
- * @param quota_out outgoing bandwidth quota in bytes per ms; 0 can
- * be used to force all traffic to be discarded
+ * @param quota_in incoming bandwidth quota in bytes per ms
+ * @param quota_out outgoing bandwidth quota in bytes per ms
* @param timeout how long to wait until signaling failure if
* we can not communicate the quota change
* @param cont continuation to call when done, will be called
GNUNET_SCHEDULER_cancel (h->sched, th->notify_delay_task);
th->notify_delay_task = GNUNET_SCHEDULER_NO_TASK;
}
- th->notify (th->notify_cls, 0, NULL);
+ if (NULL != th->notify)
+ GNUNET_assert (0 == th->notify (th->notify_cls, 0, NULL));
GNUNET_free (th);
return 0;
}
duration.value, GNUNET_i2s (&th->target));
#endif
remove_from_wait_list (th);
- th->notify (th->notify_cls, 0, NULL);
+ if (NULL != th->notify)
+ GNUNET_assert (0 == th->notify (th->notify_cls, 0, NULL));
GNUNET_free (th);
return;
}
GNUNET_SCHEDULER_cancel (handle->sched, th->notify_delay_task);
th->notify_delay_task = GNUNET_SCHEDULER_NO_TASK;
}
- th->notify (th->notify_cls, 0, NULL);
+ if (NULL != th->notify)
+ GNUNET_assert (0 == th->notify (th->notify_cls, 0, NULL));
GNUNET_free (th);
}
while (NULL != (th = handle->connect_wait_head))
GNUNET_SCHEDULER_cancel (handle->sched, th->notify_delay_task);
th->notify_delay_task = GNUNET_SCHEDULER_NO_TASK;
}
- th->notify (th->notify_cls, 0, NULL);
+ if (NULL != th->notify)
+ GNUNET_assert (0 == th->notify (th->notify_cls, 0, NULL));
GNUNET_free (th);
}
while (NULL != (n = handle->neighbours))
GNUNET_SCHEDULER_cancel (handle->sched, th->notify_delay_task);
th->notify_delay_task = GNUNET_SCHEDULER_NO_TASK;
}
- th->notify (th->notify_cls, 0, NULL);
+ if (NULL != th->notify)
+ GNUNET_assert (0 == th->notify (th->notify_cls, 0, NULL));
GNUNET_free (th);
}
GNUNET_free (n);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Transmission request could not be satisfied.\n");
#endif
- ret = ctw->notify (ctw->notify_cls, 0, NULL);
- GNUNET_assert (ret == 0);
+ if (NULL != ctw->notify)
+ GNUNET_assert (0 == ctw->notify (ctw->notify_cls, 0, NULL));
GNUNET_free (ctw);
return 0;
}
GNUNET_assert (size >= sizeof (struct OutboundMessage));
obm = buf;
- ret = ctw->notify (ctw->notify_cls,
- size - sizeof (struct OutboundMessage),
- (void *) &obm[1]);
+ if (ctw->notify != NULL)
+ ret = ctw->notify (ctw->notify_cls,
+ size - sizeof (struct OutboundMessage),
+ (void *) &obm[1]);
+ else
+ ret = 0;
if (ret == 0)
{
/* Need to reset flag, no SEND means no SEND_OK! */