From cfa7d229b27b9c387351c9bf3c8a9eb7994de13a Mon Sep 17 00:00:00 2001 From: Matthias Wachs Date: Tue, 7 Jan 2014 16:00:27 +0000 Subject: new monitoring API --- src/include/gnunet_transport_service.h | 284 +++++++++++++++++++++++++++++---- 1 file changed, 253 insertions(+), 31 deletions(-) (limited to 'src/include/gnunet_transport_service.h') diff --git a/src/include/gnunet_transport_service.h b/src/include/gnunet_transport_service.h index 4b0735b10..dee8e7118 100644 --- a/src/include/gnunet_transport_service.h +++ b/src/include/gnunet_transport_service.h @@ -44,6 +44,170 @@ extern "C" #define GNUNET_TRANSPORT_VERSION 0x00000000 +/** + * Possible state of a neighbour. Initially, we are #S_NOT_CONNECTED. + * + * Then, there are two main paths. If we receive a CONNECT message, we + * first run a check against the blacklist (#S_CONNECT_RECV_BLACKLIST_INBOUND). + * If this check is successful, we give the inbound address to ATS. + * After the check we ask ATS for a suggestion (S_CONNECT_RECV_ATS). + * If ATS makes a suggestion, we ALSO give that suggestion to the blacklist + * (#S_CONNECT_RECV_BLACKLIST). Once the blacklist approves the + * address we got from ATS, we send our CONNECT_ACK and go to + * #S_CONNECT_RECV_ACK. If we receive a SESSION_ACK, we go to + * #S_CONNECTED (and notify everyone about the new connection). If the + * operation times out, we go to #S_DISCONNECT. + * + * The other case is where we transmit a CONNECT message first. We + * start with #S_INIT_ATS. If we get an address, we enter + * #S_INIT_BLACKLIST and check the blacklist. If the blacklist is OK + * with the connection, we actually send the CONNECT message and go to + * state S_CONNECT_SENT. Once we receive a CONNECT_ACK, we go to + * #S_CONNECTED (and notify everyone about the new connection and send + * back a SESSION_ACK). If the operation times out, we go to + * #S_DISCONNECT. + * + * If the session is in trouble (i.e. transport-level disconnect or + * timeout), we go to #S_RECONNECT_ATS where we ask ATS for a new + * address (we don't notify anyone about the disconnect yet). Once we + * have a new address, we go to #S_RECONNECT_BLACKLIST to check the new + * address against the blacklist. If the blacklist approves, we enter + * #S_RECONNECT_SENT and send a CONNECT message. If we receive a + * CONNECT_ACK, we go to #S_CONNECTED and nobody noticed that we had + * trouble; we also send a SESSION_ACK at this time just in case. If + * the operation times out, we go to S_DISCONNECT (and notify everyone + * about the lost connection). + * + * If ATS decides to switch addresses while we have a normal + * connection, we go to #S_CONNECTED_SWITCHING_BLACKLIST to check the + * new address against the blacklist. If the blacklist approves, we + * go to #S_CONNECTED_SWITCHING_CONNECT_SENT and send a + * SESSION_CONNECT. If we get a SESSION_ACK back, we switch the + * primary connection to the suggested alternative from ATS, go back + * to #S_CONNECTED and send a SESSION_ACK to the other peer just to be + * sure. If the operation times out (or the blacklist disapproves), + * we go to #S_CONNECTED (and notify ATS that the given alternative + * address is "invalid"). + * + * Once a session is in #S_DISCONNECT, it is cleaned up and then goes + * to (#S_DISCONNECT_FINISHED). If we receive an explicit disconnect + * request, we can go from any state to #S_DISCONNECT, possibly after + * generating disconnect notifications. + * + * Note that it is quite possible that while we are in any of these + * states, we could receive a 'CONNECT' request from the other peer. + * We then enter a 'weird' state where we pursue our own primary state + * machine (as described above), but with the 'send_connect_ack' flag + * set to 1. If our state machine allows us to send a 'CONNECT_ACK' + * (because we have an acceptable address), we send the 'CONNECT_ACK' + * and set the 'send_connect_ack' to 2. If we then receive a + * 'SESSION_ACK', we go to #S_CONNECTED (and reset 'send_connect_ack' + * to 0). + * + */ +enum GNUNET_TRANSPORT_PeerState +{ + /** + * fresh peer or completely disconnected + */ + S_NOT_CONNECTED = 0, + + /** + * Asked to initiate connection, trying to get address from ATS + */ + S_INIT_ATS, + + /** + * Asked to initiate connection, trying to get address approved + * by blacklist. + */ + S_INIT_BLACKLIST, + + /** + * Sent CONNECT message to other peer, waiting for CONNECT_ACK + */ + S_CONNECT_SENT, + + /** + * Received a CONNECT, do a blacklist check for inbound address + */ + S_CONNECT_RECV_BLACKLIST_INBOUND, + + /** + * Received a CONNECT, asking ATS about address suggestions. + */ + S_CONNECT_RECV_ATS, + + /** + * Received CONNECT from other peer, got an address, checking with blacklist. + */ + S_CONNECT_RECV_BLACKLIST, + + /** + * CONNECT request from other peer was SESSION_ACK'ed, waiting for + * SESSION_ACK. + */ + S_CONNECT_RECV_ACK, + + /** + * Got our CONNECT_ACK/SESSION_ACK, connection is up. + */ + S_CONNECTED, + + /** + * Connection got into trouble, rest of the system still believes + * it to be up, but we're getting a new address from ATS. + */ + S_RECONNECT_ATS, + + /** + * Connection got into trouble, rest of the system still believes + * it to be up; we are checking the new address against the blacklist. + */ + S_RECONNECT_BLACKLIST, + + /** + * Sent CONNECT over new address (either by ATS telling us to switch + * addresses or from RECONNECT_ATS); if this fails, we need to tell + * the rest of the system about a disconnect. + */ + S_RECONNECT_SENT, + + /** + * We have some primary connection, but ATS suggested we switch + * to some alternative; we're now checking the alternative against + * the blacklist. + */ + S_CONNECTED_SWITCHING_BLACKLIST, + + /** + * We have some primary connection, but ATS suggested we switch + * to some alternative; we now sent a CONNECT message for the + * alternative session to the other peer and waiting for a + * CONNECT_ACK to make this our primary connection. + */ + S_CONNECTED_SWITCHING_CONNECT_SENT, + + /** + * Disconnect in progress (we're sending the DISCONNECT message to the + * other peer; after that is finished, the state will be cleaned up). + */ + S_DISCONNECT, + + /** + * We're finished with the disconnect; and are cleaning up the state + * now! We put the struct into this state when we are really in the + * task that calls 'free' on it and are about to remove the record + * from the map. We should never find a 'struct NeighbourMapEntry' + * in this state in the map. Accessing a 'struct NeighbourMapEntry' + * in this state virtually always means using memory that has been + * freed (the exception being the cleanup code in #free_neighbour()). + */ + S_DISCONNECT_FINISHED +}; + + + /** * Function called by the transport for each received message. * @@ -119,19 +283,39 @@ typedef void (*GNUNET_TRANSPORT_AddressToStringCallback) (void *cls, /** - * Function to call with a binary format of an address + * Function to call with information about a peer * * @param cls closure - * @param peer peer this update is about (never NULL) + * @param peer peer this update is about, + * NULL if this is the final last callback for a iteration operation * @param address address, NULL for disconnect notification in monitor mode + * @param state current state this peer is in + * @param state_timeout timeout for the current state of the peer */ typedef void (*GNUNET_TRANSPORT_PeerIterateCallback) (void *cls, - const struct - GNUNET_PeerIdentity * - peer, - const struct - GNUNET_HELLO_Address * - address); + const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_HELLO_Address *address, + enum GNUNET_TRANSPORT_PeerState state, + struct GNUNET_TIME_Absolute state_timeout); + + +/** + * Function to call with validation information about a peer + * + * @param cls closure + * @param peer peer this update is about, + * NULL if this is the final last callback for a iteration operation + * @param address address, NULL for disconnect notification in monitor mode + * @param valid_until when does this address expire + * @param next_validation time of the next validation operation + * + */ +typedef void (*GNUNET_TRANSPORT_ValidationIterateCallback) (void *cls, + const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_HELLO_Address *address, + struct GNUNET_TIME_Absolute valid_until, + struct GNUNET_TIME_Absolute next_validation); + /** @@ -401,46 +585,84 @@ GNUNET_TRANSPORT_address_to_string (const struct GNUNET_CONFIGURATION_Handle void GNUNET_TRANSPORT_address_to_string_cancel (struct GNUNET_TRANSPORT_AddressToStringContext - *alc); + *pic); /** - * Return all the known addresses for a specific peer or all peers. - * Returns continuously all address if one_shot is set to GNUNET_NO + * Return information about a specific peer or all peers currently known to + * transport service once or in monitoring mode. To obtain information about + * a specific peer, a peer identity can be passed. To obtain information about + * all peers currently known to transport service, NULL can be passed as peer + * identity. * - * CHANGE: Returns the address(es) that we are currently using for this - * peer. Upon completion, the 'AddressLookUpCallback' is called one more - * time with 'NULL' for the address and the peer. After this, the operation must no - * longer be explicitly cancelled. + * For each peer, the callback is called with information about the address used + * to communicate with this peer, the state this peer is currently in and the + * the current timeout for this state. + * + * Upon completion, the 'GNUNET_TRANSPORT_PeerIterateCallback' is called one + * more time with 'NULL'. After this, the operation must no longer be + * explicitly canceled. * * @param cfg configuration to use - * @param peer peer identity to look up the addresses of, CHANGE: allow NULL for all (connected) peers + * @param peer a specific peer identity to obtain information for, + * NULL for all peers * @param one_shot GNUNET_YES to return the current state and then end (with NULL+NULL), - * GNUNET_NO to monitor the set of addresses used (continuously, must be explicitly canceled, NOT implemented yet!) + * GNUNET_NO to monitor peers continuously * @param timeout how long is the lookup allowed to take at most * @param peer_address_callback function to call with the results * @param peer_address_callback_cls closure for peer_address_callback */ -struct GNUNET_TRANSPORT_PeerIterateContext * -GNUNET_TRANSPORT_peer_get_active_addresses (const struct - GNUNET_CONFIGURATION_Handle *cfg, - const struct GNUNET_PeerIdentity - *peer, int one_shot, - struct GNUNET_TIME_Relative timeout, - GNUNET_TRANSPORT_PeerIterateCallback - peer_address_callback, - void *peer_address_callback_cls); +struct GNUNET_TRANSPORT_PeerMonitoringContext * +GNUNET_TRANSPORT_monitor_peers (const struct + GNUNET_CONFIGURATION_Handle *cfg, + const struct GNUNET_PeerIdentity *peer, + int one_shot, + struct GNUNET_TIME_Relative timeout, + GNUNET_TRANSPORT_PeerIterateCallback peer_callback, + void *peer_callback_cls); /** - * Cancel request for peer lookup. + * Cancel request to monitor peers * - * @param alc handle for the request to cancel + * @param pic handle for the request to cancel */ void -GNUNET_TRANSPORT_peer_get_active_addresses_cancel (struct - GNUNET_TRANSPORT_PeerIterateContext - *alc); +GNUNET_TRANSPORT_monitor_peers_cancel (struct GNUNET_TRANSPORT_PeerMonitoringContext *pic); + + + +/** + * Return information about pending address validation operations for a specific + * or all peers + * + * @param cfg configuration to use + * @param peer a specific peer identity to obtain validation entries for, + * NULL for all peers + * @param one_shot GNUNET_YES to return all entries and then end (with NULL+NULL), + * GNUNET_NO to monitor validation entries continuously + * @param timeout how long is the lookup allowed to take at most + * @param validation_callback function to call with the results + * @param validation_callback_cls closure for peer_address_callback + */ +struct GNUNET_TRANSPORT_ValidationMonitoringContext * +GNUNET_TRANSPORT_monitor_validation_entries (const struct + GNUNET_CONFIGURATION_Handle *cfg, + const struct GNUNET_PeerIdentity *peer, + int one_shot, + struct GNUNET_TIME_Relative timeout, + GNUNET_TRANSPORT_ValidationIterateCallback validation_callback, + void *validation_callback_cls); + + +/** + * Return information about all current pending validation operations + * + * @param vic handle for the request to cancel + */ +void +GNUNET_TRANSPORT_monitor_validation_entries_cancel (struct GNUNET_TRANSPORT_ValidationMonitoringContext *vic); + /** -- cgit v1.2.3