#define ATS_RESPONSE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3)
+
+#define SETUP_CONNECTION_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
+
+
/**
* Entry in neighbours.
*/
*/
struct GNUNET_TIME_Absolute connect_ts;
+ /**
+ * Timeout for ATS
+ * We asked ATS for a new address for this peer
+ */
GNUNET_SCHEDULER_TaskIdentifier ats_suggest;
+ /**
+ * Task the resets the peer state after due to an pending
+ * unsuccessful connection setup
+ */
+ GNUNET_SCHEDULER_TaskIdentifier state_reset;
+
/**
* How often has the other peer (recently) violated the inbound
* traffic limit? Incremented by 10 per violation, decremented by 1
*/
unsigned int quota_violation_count;
- /**
- * Number of values in 'ats' array.
- */
- //unsigned int ats_count;
-
/**
- * Do we currently consider this neighbour connected? (as far as
- * the connect/disconnect callbacks are concerned)?
+ * The current state of the peer
+ * Element of enum State
*/
- //int is_connected;
-
int state;
};
return NULL;
}
+static int
+change (struct NeighbourMapEntry * n, int state, int line);
+
+static void
+ats_suggest_cancel (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc);
+
+static void
+reset_task (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ struct NeighbourMapEntry * n = cls;
+
+ n->state_reset = GNUNET_SCHEDULER_NO_TASK;
+
+#if DEBUG_TRANSPORT
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Connection to peer `%s' %s failed in state `%s', resetting connection attempt \n",
+ GNUNET_i2s (&n->id), GST_plugins_a2s(n->plugin_name, n->addr, n->addrlen), print_state(n->state));
+#endif
+ GNUNET_STATISTICS_update (GST_stats,
+ gettext_noop ("# failed connection attempts due to timeout"),
+ 1,
+ GNUNET_NO);
+
+ /* resetting state */
+ n->state = S_NOT_CONNECTED;
+
+ /* destroying address */
+ GNUNET_ATS_address_destroyed (GST_ats,
+ &n->id,
+ n->plugin_name,
+ n->addr,
+ n->addrlen,
+ NULL);
+
+ /* request new address */
+ if (n->ats_suggest != GNUNET_SCHEDULER_NO_TASK)
+ GNUNET_SCHEDULER_cancel(n->ats_suggest);
+ n->ats_suggest = GNUNET_SCHEDULER_add_delayed (ATS_RESPONSE_TIMEOUT, ats_suggest_cancel, n);
+ GNUNET_ATS_suggest_address(GST_ats, &n->id);
+}
+
static int
change (struct NeighbourMapEntry * n, int state, int line)
{
(state == S_DISCONNECT))
{
allowed = GNUNET_YES;
+
+ /* Schedule reset task */
+ if ((state == S_CONNECT_RECV) || (state == S_CONNECT_SENT) )
+ {
+ GNUNET_assert (n->state_reset == GNUNET_SCHEDULER_NO_TASK);
+ n->state_reset = GNUNET_SCHEDULER_add_delayed (SETUP_CONNECTION_TIMEOUT, &reset_task, n);
+ }
+
break;
}
break;
case S_CONNECT_RECV:
if ((state == S_NOT_CONNECTED) || (state == S_DISCONNECT) ||
- (state == S_CONNECTED))
+ (state == S_CONNECTED) || /* FIXME SENT -> RECV ISSUE!*/ (state == S_CONNECT_SENT))
{
+ if ((state == S_CONNECTED) || (state == S_DISCONNECT) || (state == S_NOT_CONNECTED))
+ {
+#if DEBUG_TRANSPORT
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Removed reset task for peer `%s' %s failed in state transition `%s' -> `%s' \n",
+ GNUNET_i2s (&n->id), GST_plugins_a2s(n->plugin_name, n->addr, n->addrlen), print_state(n->state), print_state(state));
+#endif
+ GNUNET_assert (n->state_reset != GNUNET_SCHEDULER_NO_TASK);
+ GNUNET_SCHEDULER_cancel (n->state_reset);
+ n->state_reset = GNUNET_SCHEDULER_NO_TASK;
+ }
+
allowed = GNUNET_YES;
break;
}
if ((state == S_NOT_CONNECTED) || (state == S_CONNECTED) ||
(state == S_DISCONNECT) || /* FIXME SENT -> RECV ISSUE!*/ (state == S_CONNECT_RECV))
{
+ if ((state == S_CONNECTED) || (state == S_DISCONNECT) || (state == S_NOT_CONNECTED))
+ {
+#if DEBUG_TRANSPORT
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Removed reset task for peer `%s' %s failed in state transition `%s' -> `%s' \n",
+ GNUNET_i2s (&n->id), GST_plugins_a2s(n->plugin_name, n->addr, n->addrlen), print_state(n->state), print_state(state));
+#endif
+ GNUNET_assert (n->state_reset != GNUNET_SCHEDULER_NO_TASK);
+ GNUNET_SCHEDULER_cancel (n->state_reset);
+ n->state_reset = GNUNET_SCHEDULER_NO_TASK;
+ }
+
allowed = GNUNET_YES;
break;
}
}
n->state = state;
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "State for neighbour `%s' %X changed from `%s' to `%s' in line %u\n",
+#if DEBUG_TRANSPORT
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "State for neighbour `%s' %X changed from `%s' to `%s' in line %u\n",
GNUNET_i2s (&n->id), n, old, new, line);
+#endif
GNUNET_free (old);
GNUNET_free (new);
return GNUNET_OK;
struct MessageQueue *mq;
int was_connected = is_connected(n);
- if (is_disconnecting(n) == GNUNET_YES)
- return;
-
/* send DISCONNECT MESSAGE */
if (is_connected(n) || is_connecting(n))
{
n->ats_suggest = GNUNET_SCHEDULER_NO_TASK;
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
" ATS did not suggested address to connect to peer `%s'\n",
GNUNET_i2s (&n->id));
}
return GNUNET_NO;
}
-
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid connection state to switch addresses %u ", n->state);
+ else if (n->state == S_CONNECT_SENT)
+ {
+ //FIXME
+ return GNUNET_NO;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid connection state to switch addresses %u \n", n->state);
GNUNET_break_op (0);
return GNUNET_NO;
}
GNUNET_i2s (&n->id));
#endif
- if (n->ats_suggest != GNUNET_SCHEDULER_NO_TASK)
- GNUNET_SCHEDULER_cancel(n->ats_suggest);
- n->ats_suggest = GNUNET_SCHEDULER_add_delayed (ATS_RESPONSE_TIMEOUT, ats_suggest_cancel, n);
GNUNET_ATS_suggest_address (GST_ats, &n->id);
}
}
if (!is_connected(n))
{
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- _("Plugin gave us %d bytes of data but somehow the session is not marked as UP yet!\n"),
- (int) size);
*do_forward = GNUNET_SYSERR;
return GNUNET_TIME_UNIT_ZERO;
}
const struct SessionConnectMessage *scm;
struct QuotaSetMessage q_msg;
struct GNUNET_MessageHeader msg;
- struct GNUNET_TIME_Absolute ts;
struct NeighbourMapEntry *n;
size_t msg_len;
size_t ret;
+ int was_connected;
#if DEBUG_TRANSPORT
-#endif
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Received CONNECT_ACK message from peer `%s'\n", GNUNET_i2s (peer));
-
+#endif
if (ntohs (message->size) != sizeof (struct SessionConnectMessage))
{
scm = (const struct SessionConnectMessage *) message;
GNUNET_break_op (ntohl (scm->reserved) == 0);
- ts = GNUNET_TIME_absolute_ntoh (scm->timestamp);
n = lookup_neighbour (peer);
if (NULL == n)
n = setup_neighbour (peer);
plugin_name, sender_address, sender_address_len,
session, ats, ats_count);
- change_state (n, S_CONNECTED);
+ was_connected = is_connected(n);
+ if (!is_connected(n))
+ change_state (n, S_CONNECTED);
#if DEBUG_TRANSPORT
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
#endif
GST_neighbours_set_incoming_quota(&n->id, n->bandwidth_in);
- n->keepalive_task = GNUNET_SCHEDULER_add_delayed (KEEPALIVE_FREQUENCY,
- &neighbour_keepalive_task,
- n);
/* send ACK (ACK)*/
msg_len = sizeof (msg);
msg.size = htons (msg_len);
n->addrlen),
n->session);
- neighbours_connected++;
- GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# peers connected"), 1,
- GNUNET_NO);
- connect_notify_cb (callback_cls, &n->id, ats, ats_count);
+
+ if (!was_connected)
+ {
+ if (n->keepalive_task == GNUNET_SCHEDULER_NO_TASK)
+ n->keepalive_task = GNUNET_SCHEDULER_add_delayed (KEEPALIVE_FREQUENCY,
+ &neighbour_keepalive_task,
+ n);
+
+ neighbours_connected++;
+ GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# peers connected"), 1,
+ GNUNET_NO);
+ connect_notify_cb (callback_cls, &n->id, ats, ats_count);
#if DEBUG_TRANSPORT
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Sending outbound quota of %u Bps for peer `%s' to all clients\n",
- ntohl (n->bandwidth_out.value__), GNUNET_i2s (peer));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Sending outbound quota of %u Bps for peer `%s' to all clients\n",
+ ntohl (n->bandwidth_out.value__), GNUNET_i2s (peer));
#endif
- q_msg.header.size = htons (sizeof (struct QuotaSetMessage));
- q_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SET_QUOTA);
- q_msg.quota = n->bandwidth_out;
- q_msg.peer = (*peer);
- GST_clients_broadcast (&q_msg.header, GNUNET_NO);
+ q_msg.header.size = htons (sizeof (struct QuotaSetMessage));
+ q_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SET_QUOTA);
+ q_msg.quota = n->bandwidth_out;
+ q_msg.peer = (*peer);
+ GST_clients_broadcast (&q_msg.header, GNUNET_NO);
+ }
}
void
GST_neighbours_set_incoming_quota(&n->id, n->bandwidth_in);
- n->keepalive_task = GNUNET_SCHEDULER_add_delayed (KEEPALIVE_FREQUENCY,
+ if (n->keepalive_task == GNUNET_SCHEDULER_NO_TASK)
+ n->keepalive_task = GNUNET_SCHEDULER_add_delayed (KEEPALIVE_FREQUENCY,
&neighbour_keepalive_task,
n);