/**
- * Send a SESSION_CONNECT_ACK message via the given address.
+ * Send a CONNECT_ACK message via the given address.
*
* @param address address to use
* @param session session to use
* @param timestamp timestamp to use for the ACK message
*/
static void
-send_session_connect_ack_message (const struct GNUNET_HELLO_Address *address,
+send_connect_ack_message (const struct GNUNET_HELLO_Address *address,
struct Session *session,
struct GNUNET_TIME_Absolute timestamp)
{
struct GNUNET_TRANSPORT_PluginFunctions *papi;
struct SessionConnectMessage connect_msg;
+ struct NeighbourMapEntry *n;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Sending CONNECT_ACK to peer `%s'\n",
connect_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_CONNECT_ACK);
connect_msg.reserved = htonl (0);
connect_msg.timestamp = GNUNET_TIME_absolute_hton (timestamp);
- (void) papi->send (papi->cls,
+
+ if (GNUNET_SYSERR == papi->send (papi->cls,
session,
(const char *) &connect_msg, sizeof (struct SessionConnectMessage),
UINT_MAX,
GNUNET_TIME_UNIT_FOREVER_REL,
- NULL, NULL);
+ NULL, NULL))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ _("Failed to transmit CONNECT_ACK message via plugin to %s\n"),
+ GST_plugins_a2s (address));
+
+ n = lookup_neighbour (&address->peer);
+ if (NULL == n)
+ {
+ GNUNET_break (0);
+ return;
+ }
+ /* Hard failure to send the CONNECT_ACK message with this address:
+ Destroy session (and address) */
+ if (GNUNET_YES == GNUNET_HELLO_address_check_option(address,
+ GNUNET_HELLO_ADDRESS_INFO_INBOUND))
+ {
+ GNUNET_ATS_address_destroyed (GST_ats, address, session);
+ GNUNET_ATS_address_destroyed (GST_ats, address, NULL);
+ }
+ else
+ {
+ GNUNET_ATS_address_destroyed (GST_ats, address, session);
+ }
+
+ /* Remove address and request and additional one */
+ unset_primary_address (n);
+ set_state_and_timeout (n, GNUNET_TRANSPORT_PS_INIT_ATS,
+ GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
+ return;
+ }
}
* @param result #GNUNET_OK if the address is allowed
*/
static void
-handle_test_blacklist_cont (void *cls,
+handle_connect_blacklist_check_cont (void *cls,
const struct GNUNET_PeerIdentity *peer,
int result)
{
(GNUNET_OK == result) ? "allowed" : "FORBIDDEN");
if (GNUNET_OK == result)
{
+ /* Blacklist agreed on connecting to a peer with this address */
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Notifying ATS peer's `%s' %s address `%s' session %p\n",
+ GNUNET_i2s (peer),
+ (GNUNET_YES == GNUNET_HELLO_address_check_option(bcc->na.address,
+ GNUNET_HELLO_ADDRESS_INFO_INBOUND)) ? "inbound" : "outbound",
+ GST_plugins_a2s (bcc->na.address), bcc->na.session);
GST_ats_add_address (bcc->na.address, bcc->na.session, NULL, 0);
}
- else
- {
- /* Blacklist disagreed on connecting to a peer with this address
- * Destroy address because we are not allowed to use it
- */
- if (NULL != bcc->na.session)
- GNUNET_ATS_address_destroyed (GST_ats, bcc->na.address, bcc->na.session);
- GNUNET_ATS_address_destroyed (GST_ats, bcc->na.address, NULL);
- }
+
if (NULL == (n = lookup_neighbour (peer)))
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
goto cleanup; /* nobody left to care about new address */
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Received blacklist result for peer `%s' in state %s/%s\n",
+ "Received connect blacklist check result for peer `%s' in state %s/%s\n",
GNUNET_i2s (peer),
GNUNET_TRANSPORT_ps2s (n->state),
print_ack_state (n->ack_state));
possibility */
break;
case GNUNET_TRANSPORT_PS_CONNECT_SENT:
+#if 0
+ /* TODO Why should I send an connect ACK message */
/* waiting on CONNECT_ACK, send ACK if one is pending */
+
if ( (GNUNET_OK == result) &&
(ACK_SEND_CONNECT_ACK == n->ack_state) )
{
n->ack_state = ACK_SEND_SESSION_ACK;
- send_session_connect_ack_message (n->primary_address.address,
+ send_connect_ack_message (n->primary_address.address,
n->primary_address.session,
n->connect_ack_timestamp);
}
+#endif
break;
case GNUNET_TRANSPORT_PS_CONNECT_RECV_BLACKLIST_INBOUND:
- set_state_and_timeout (n, GNUNET_TRANSPORT_PS_CONNECT_RECV_ATS,
- GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
- GNUNET_ATS_reset_backoff (GST_ats, peer);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Suggesting address for peer %s to ATS\n",
- GNUNET_i2s (peer));
- n->suggest_handle = GNUNET_ATS_suggest_address (GST_ats, peer,
- &address_suggest_cont, n);
+ if (GNUNET_OK == result)
+ {
+ /* We received a connect request and blacklist allowed to communicate
+ * with this peer, request an address from ATS*/
+ set_state_and_timeout (n, GNUNET_TRANSPORT_PS_CONNECT_RECV_ATS,
+ GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
+ GNUNET_ATS_reset_backoff (GST_ats, peer);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Requesting address for peer %s to ATS\n",
+ GNUNET_i2s (peer));
+ if (NULL == n->suggest_handle)
+ n->suggest_handle = GNUNET_ATS_suggest_address (GST_ats, peer,
+ &address_suggest_cont, n);
+ else
+ GNUNET_ATS_reset_backoff (GST_ats, peer);
+ }
+ else
+ {
+ /* FIXME: state handling required! */
+ }
break;
case GNUNET_TRANSPORT_PS_CONNECT_RECV_ATS:
/* waiting on ATS suggestion, don't care about blacklist */
{
set_state_and_timeout (n, GNUNET_TRANSPORT_PS_CONNECT_RECV_ACK,
GNUNET_TIME_relative_to_absolute (SETUP_CONNECTION_TIMEOUT));
- send_session_connect_ack_message (bcc->na.address,
+ send_connect_ack_message (bcc->na.address,
bcc->na.session,
n->connect_ack_timestamp);
if (ACK_SEND_CONNECT_ACK == n->ack_state)
(ACK_SEND_CONNECT_ACK == n->ack_state) )
{
n->ack_state = ACK_SEND_SESSION_ACK;
- send_session_connect_ack_message (n->primary_address.address,
+ send_connect_ack_message (n->primary_address.address,
n->primary_address.session,
n->connect_ack_timestamp);
}
(ACK_SEND_CONNECT_ACK == n->ack_state) )
{
n->ack_state = ACK_SEND_SESSION_ACK;
- send_session_connect_ack_message (bcc->na.address,
+ send_connect_ack_message (bcc->na.address,
bcc->na.session,
n->connect_ack_timestamp);
}
(ACK_SEND_CONNECT_ACK == n->ack_state) )
{
n->ack_state = ACK_SEND_SESSION_ACK;
- send_session_connect_ack_message (n->primary_address.address,
+ send_connect_ack_message (n->primary_address.address,
n->primary_address.session,
n->connect_ack_timestamp);
}
(ACK_SEND_CONNECT_ACK == n->ack_state) )
{
n->ack_state = ACK_SEND_SESSION_ACK;
- send_session_connect_ack_message (n->primary_address.address,
+ send_connect_ack_message (n->primary_address.address,
n->primary_address.session,
n->connect_ack_timestamp);
}
/**
- * We want to know if connecting to a particular peer via
- * a particular address is allowed. Check it!
+ * We received a CONNECT message and want to know if connecting to a particular
+ * peer via a particular address is allowed. Check it!
*
* @param peer identity of the peer to switch the address for
* @param ts time at which the check was initiated
* @param session session to use (or NULL)
*/
static void
-check_blacklist (const struct GNUNET_PeerIdentity *peer,
+connect_check_blacklist (const struct GNUNET_PeerIdentity *peer,
struct GNUNET_TIME_Absolute ts,
const struct GNUNET_HELLO_Address *address,
struct Session *session)
bc_tail,
bcc);
if (NULL != (bc = GST_blacklist_test_allowed (peer,
- address->transport_name,
- &handle_test_blacklist_cont, bcc)))
+ (NULL != address) ? address->transport_name : NULL,
+ &handle_connect_blacklist_check_cont, bcc)))
bcc->bc = bc;
/* if NULL == bc, 'cont' was already called and 'bcc' already free'd, so
we must only store 'bc' if 'bc' is non-NULL... */
ts = GNUNET_TIME_absolute_ntoh (scm->timestamp);
n = lookup_neighbour (peer);
if (NULL == n)
+ {
+ /* This is a new neighbour and set to not connected */
n = setup_neighbour (peer);
+ }
/* Remember this CONNECT message in neighbour */
n->ack_state = ACK_SEND_CONNECT_ACK;
switch (n->state)
{
case GNUNET_TRANSPORT_PS_NOT_CONNECTED:
- /* Do a blacklist check for the new address */
- set_state (n, GNUNET_TRANSPORT_PS_CONNECT_RECV_BLACKLIST_INBOUND);
- check_blacklist (peer, ts, address, session);
+ /* Check if we are allowed to connect with this peer and this address */
+ set_state_and_timeout (n, GNUNET_TRANSPORT_PS_CONNECT_RECV_BLACKLIST_INBOUND,
+ GNUNET_TIME_relative_to_absolute (BLACKLIST_RESPONSE_TIMEOUT));
+ connect_check_blacklist (peer, ts, address, session);
break;
case GNUNET_TRANSPORT_PS_INIT_ATS:
/* CONNECT message takes priority over us asking ATS for address */
- set_state (n, GNUNET_TRANSPORT_PS_CONNECT_RECV_BLACKLIST_INBOUND);
+ set_state_and_timeout (n, GNUNET_TRANSPORT_PS_CONNECT_RECV_BLACKLIST_INBOUND,
+ GNUNET_TIME_relative_to_absolute (BLACKLIST_RESPONSE_TIMEOUT));
/* fallthrough */
case GNUNET_TRANSPORT_PS_CONNECT_SENT:
case GNUNET_TRANSPORT_PS_CONNECT_RECV_BLACKLIST_INBOUND:
case GNUNET_TRANSPORT_PS_CONNECT_RECV_ACK:
/* It can never hurt to have an alternative address in the above cases,
see if it is allowed */
- check_blacklist (peer, ts, address, session);
+ connect_check_blacklist (peer, ts, address, session);
break;
case GNUNET_TRANSPORT_PS_CONNECTED:
/* we are already connected and can thus send the ACK immediately;
GNUNET_assert (NULL != n->primary_address.address);
GNUNET_assert (NULL != n->primary_address.session);
n->ack_state = ACK_UNDEFINED;
- send_session_connect_ack_message (n->primary_address.address,
+ send_connect_ack_message (n->primary_address.address,
n->primary_address.session, ts);
- check_blacklist (peer, ts, address, session);
+ connect_check_blacklist (peer, ts, address, session);
break;
case GNUNET_TRANSPORT_PS_RECONNECT_ATS:
case GNUNET_TRANSPORT_PS_RECONNECT_BLACKLIST:
case GNUNET_TRANSPORT_PS_RECONNECT_SENT:
/* It can never hurt to have an alternative address in the above cases,
see if it is allowed */
- check_blacklist (peer, ts, address, session);
+ connect_check_blacklist (peer, ts, address, session);
break;
case GNUNET_TRANSPORT_PS_CONNECTED_SWITCHING_BLACKLIST:
case GNUNET_TRANSPORT_PS_CONNECTED_SWITCHING_CONNECT_SENT:
GNUNET_assert (NULL != n->primary_address.address);
GNUNET_assert (NULL != n->primary_address.session);
n->ack_state = ACK_UNDEFINED;
- send_session_connect_ack_message (n->primary_address.address,
+ send_connect_ack_message (n->primary_address.address,
n->primary_address.session, ts);
- check_blacklist (peer, ts, address, session);
+ connect_check_blacklist (peer, ts, address, session);
break;
case GNUNET_TRANSPORT_PS_DISCONNECT:
/* get rid of remains without terminating sessions, ready to re-try */
if (ACK_SEND_CONNECT_ACK == n->ack_state)
{
n->ack_state = ACK_SEND_SESSION_ACK;
- send_session_connect_ack_message (n->primary_address.address,
+ send_connect_ack_message (n->primary_address.address,
n->primary_address.session,
n->connect_ack_timestamp);
}
/* Send an ACK message as a response to the CONNECT msg */
set_state_and_timeout (n, GNUNET_TRANSPORT_PS_CONNECT_RECV_ACK,
GNUNET_TIME_relative_to_absolute (SETUP_CONNECTION_TIMEOUT));
- send_session_connect_ack_message (n->primary_address.address,
+ send_connect_ack_message (n->primary_address.address,
n->primary_address.session,
n->connect_ack_timestamp);
if (ACK_SEND_CONNECT_ACK == n->ack_state)
break;
case GNUNET_TRANSPORT_PS_CONNECT_RECV_BLACKLIST_INBOUND:
set_timeout (n, GNUNET_TIME_relative_to_absolute (BLACKLIST_RESPONSE_TIMEOUT));
- check_blacklist (&n->id, n->connect_ack_timestamp,
+ /* REMOVE */ connect_check_blacklist (&n->id, n->connect_ack_timestamp,
blc_ctx->address, blc_ctx->session);
break;
case GNUNET_TRANSPORT_PS_CONNECT_RECV_BLACKLIST:
blc_ctx->bandwidth_in, blc_ctx->bandwidth_out, GNUNET_NO);
set_state_and_timeout (n, GNUNET_TRANSPORT_PS_CONNECT_RECV_BLACKLIST,
GNUNET_TIME_relative_to_absolute (BLACKLIST_RESPONSE_TIMEOUT));
- check_blacklist (&n->id, n->connect_ack_timestamp,
+ /* REMOVE */ connect_check_blacklist (&n->id, n->connect_ack_timestamp,
blc_ctx->address, blc_ctx->session);
break;
case GNUNET_TRANSPORT_PS_CONNECTED:
set_state (n, GNUNET_TRANSPORT_PS_CONNECTED_SWITCHING_BLACKLIST);
set_alternative_address (n, blc_ctx->address, blc_ctx->session,
blc_ctx->bandwidth_in, blc_ctx->bandwidth_out);
- check_blacklist (&n->id, GNUNET_TIME_absolute_get (),
+ /* REMOVE */ connect_check_blacklist (&n->id, GNUNET_TIME_absolute_get (),
blc_ctx->address, blc_ctx->session);
break;
case GNUNET_TRANSPORT_PS_RECONNECT_ATS:
blc_ctx->bandwidth_in, blc_ctx->bandwidth_out, GNUNET_NO);
set_state_and_timeout (n, GNUNET_TRANSPORT_PS_RECONNECT_BLACKLIST,
GNUNET_TIME_relative_to_absolute (BLACKLIST_RESPONSE_TIMEOUT));
- check_blacklist (&n->id, n->connect_ack_timestamp,
+ /* REMOVE */ connect_check_blacklist (&n->id, n->connect_ack_timestamp,
blc_ctx->address, blc_ctx->session);
break;
case GNUNET_TRANSPORT_PS_RECONNECT_BLACKLIST:
set_primary_address (n, blc_ctx->address, blc_ctx->session,
blc_ctx->bandwidth_in, blc_ctx->bandwidth_out, GNUNET_NO);
set_timeout (n, GNUNET_TIME_relative_to_absolute (BLACKLIST_RESPONSE_TIMEOUT));
- check_blacklist (&n->id, n->connect_ack_timestamp,
+ /* REMOVE */ connect_check_blacklist (&n->id, n->connect_ack_timestamp,
blc_ctx->address, blc_ctx->session);
break;
case GNUNET_TRANSPORT_PS_RECONNECT_SENT:
blc_ctx->bandwidth_in, blc_ctx->bandwidth_out, GNUNET_NO);
set_state_and_timeout (n, GNUNET_TRANSPORT_PS_RECONNECT_BLACKLIST,
GNUNET_TIME_relative_to_absolute (BLACKLIST_RESPONSE_TIMEOUT));
- check_blacklist (&n->id, n->connect_ack_timestamp,
+ /* REMOVE */ connect_check_blacklist (&n->id, n->connect_ack_timestamp,
blc_ctx->address, blc_ctx->session);
break;
case GNUNET_TRANSPORT_PS_CONNECTED_SWITCHING_BLACKLIST:
/* ATS asks us to switch a life connection, update blacklist check */
set_primary_address (n, blc_ctx->address, blc_ctx->session,
blc_ctx->bandwidth_in, blc_ctx->bandwidth_out, GNUNET_NO);
- check_blacklist (&n->id, GNUNET_TIME_absolute_get (),
+ /* REMOVE */ connect_check_blacklist (&n->id, GNUNET_TIME_absolute_get (),
blc_ctx->address, blc_ctx->session);
break;
case GNUNET_TRANSPORT_PS_CONNECTED_SWITCHING_CONNECT_SENT:
set_state (n, GNUNET_TRANSPORT_PS_CONNECTED_SWITCHING_BLACKLIST);
set_alternative_address (n, blc_ctx->address, blc_ctx->session,
blc_ctx->bandwidth_in, blc_ctx->bandwidth_out);
- check_blacklist (&n->id, GNUNET_TIME_absolute_get (),
+ /* REMOVE */ connect_check_blacklist (&n->id, GNUNET_TIME_absolute_get (),
blc_ctx->address, blc_ctx->session);
break;
case GNUNET_TRANSPORT_PS_DISCONNECT:
break;
case GNUNET_TRANSPORT_PS_CONNECTED_SWITCHING_CONNECT_SENT:
/* new address worked; adopt it and go back to connected! */
- set_state_and_timeout (n, GNUNET_TRANSPORT_PS_CONNECTED, GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT));
+ set_state_and_timeout (n, GNUNET_TRANSPORT_PS_CONNECTED,
+ GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT));
GNUNET_break (GNUNET_NO == n->alternative_address.ats_active);
GST_ats_add_address (n->alternative_address.address,