#include "transport.h"
+
/**
* Size of the neighbour hash map.
*/
/**
* Function to call when we connected to a neighbour.
*/
-static GNUNET_TRANSPORT_NotifyConnect connect_notify_cb;
+static NotifyConnect connect_notify_cb;
/**
* Function to call when we disconnected from a neighbour.
{
case S_NOT_CONNECTED:
return "S_NOT_CONNECTED";
- break;
case S_INIT_ATS:
return "S_INIT_ATS";
- break;
case S_INIT_BLACKLIST:
return "S_INIT_BLACKLIST";
- break;
case S_CONNECT_SENT:
return "S_CONNECT_SENT";
- break;
case S_CONNECT_RECV_BLACKLIST_INBOUND:
return "S_CONNECT_RECV_BLACKLIST_INBOUND";
- break;
case S_CONNECT_RECV_ATS:
return "S_CONNECT_RECV_ATS";
- break;
case S_CONNECT_RECV_BLACKLIST:
return "S_CONNECT_RECV_BLACKLIST";
- break;
case S_CONNECT_RECV_ACK:
return "S_CONNECT_RECV_ACK";
- break;
case S_CONNECTED:
return "S_CONNECTED";
- break;
case S_RECONNECT_ATS:
return "S_RECONNECT_ATS";
- break;
case S_RECONNECT_BLACKLIST:
return "S_RECONNECT_BLACKLIST";
- break;
case S_RECONNECT_SENT:
return "S_RECONNECT_SENT";
- break;
case S_CONNECTED_SWITCHING_BLACKLIST:
return "S_CONNECTED_SWITCHING_BLACKLIST";
- break;
case S_CONNECTED_SWITCHING_CONNECT_SENT:
return "S_CONNECTED_SWITCHING_CONNECT_SENT";
- break;
case S_DISCONNECT:
return "S_DISCONNECT";
- break;
case S_DISCONNECT_FINISHED:
return "S_DISCONNECT_FINISHED";
- break;
default:
- return "UNDEFINED";
GNUNET_break (0);
- break;
+ return "UNDEFINED";
}
- GNUNET_break (0);
return "UNDEFINED";
}
{
GST_validation_set_address_use (na->address, na->session, GNUNET_NO, __LINE__);
GNUNET_ATS_address_in_use (GST_ats, na->address, na->session, GNUNET_NO);
- GNUNET_ATS_address_destroyed (GST_ats, na->address, na->session);
- }
- else
- {
- if (NULL != na->address)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "HACK: destroy address\n");
- GNUNET_ATS_address_destroyed (GST_ats, na->address, na->session);
- }
}
+
na->ats_active = GNUNET_NO;
if (NULL != na->address)
{
{
struct MessageQueue *mq;
struct GNUNET_TRANSPORT_PluginFunctions *papi;
+ struct GNUNET_HELLO_Address *backup_primary;
n->is_active = NULL; /* always free'd by its own continuation! */
{
GNUNET_CONTAINER_DLL_remove (n->messages_head, n->messages_tail, mq);
if (NULL != mq->cont)
- mq->cont (mq->cont_cls, GNUNET_SYSERR);
+ mq->cont (mq->cont_cls, GNUNET_SYSERR, mq->message_buf_size, 0);
GNUNET_free (mq);
}
/* It is too late to send other peer disconnect notifications, but at
disconnect_notify_cb (callback_cls, &n->id);
}
+ n->state = S_DISCONNECT_FINISHED;
+
+ if (NULL != n->primary_address.address)
+ backup_primary = GNUNET_HELLO_address_copy(n->primary_address.address);
+ else
+ backup_primary = NULL;
+
+ /* free addresses and mark as unused */
+ free_address (&n->primary_address);
+ free_address (&n->alternative_address);
+
/* FIXME-PLUGIN-API: This does not seem to guarantee that all
transport sessions eventually get killed due to inactivity; they
MUST have their own timeout logic (but at least TCP doesn't have
API gives us not even the means to selectively kill only one of
them! Killing all sessions like this seems to be very, very
wrong. */
+
+ /* cut transport-level connection */
if ((GNUNET_NO == keep_sessions) &&
- (NULL != n->primary_address.address) &&
- (NULL != (papi = GST_plugins_find (n->primary_address.address->transport_name))))
+ (NULL != backup_primary) &&
+ (NULL != (papi = GST_plugins_find (backup_primary->transport_name))))
papi->disconnect (papi->cls, &n->id);
- n->state = S_DISCONNECT_FINISHED;
+ GNUNET_free_non_null (backup_primary);
GNUNET_assert (GNUNET_YES ==
GNUNET_CONTAINER_multihashmap_remove (neighbours,
&n->id.hashPubKey, n));
- /* cut transport-level connection */
- free_address (&n->primary_address);
- free_address (&n->alternative_address);
-
// FIXME-ATS-API: we might want to be more specific about
// which states we do this from in the future (ATS should
// have given us a 'suggest_address' handle, and if we have
GNUNET_free (n);
}
-
/**
* Transmit a message using the current session of the given
* neighbour.
struct GNUNET_TRANSPORT_PluginFunctions *papi;
GNUNET_assert (n->primary_address.session != NULL);
- if ( ( (NULL == (papi = GST_plugins_find (n->primary_address.address->transport_name))) ||
+ if ( ((NULL == (papi = GST_plugins_find (n->primary_address.address->transport_name)) ||
(-1 == papi->send (papi->cls,
n->primary_address.session,
msgbuf, msgbuf_size,
priority,
timeout,
- cont, cont_cls))) &&
- (NULL != cont) )
- cont (cont_cls, &n->id, GNUNET_SYSERR);
+ cont, cont_cls)))) &&
+ (NULL != cont))
+ cont (cont_cls, &n->id, GNUNET_SYSERR, msgbuf_size, 0);
GNUNET_break (NULL != papi);
}
* @param cls NULL
* @param target identity of the neighbour that was disconnected
* @param result GNUNET_OK if the disconnect got out successfully
+ * @param payload bytes payload
+ * @param physical bytes physical
*/
static void
send_disconnect_cont (void *cls, const struct GNUNET_PeerIdentity *target,
- int result)
+ int result, size_t payload, size_t physical)
{
struct NeighbourMapEntry *n;
* @param cls the 'struct MessageQueue' of the message
* @param receiver intended receiver
* @param success whether it worked or not
+ * @param size_payload bytes payload sent
+ * @param physical bytes sent on wire
*/
static void
transmit_send_continuation (void *cls,
const struct GNUNET_PeerIdentity *receiver,
- int success)
+ int success, size_t size_payload, size_t physical)
{
struct MessageQueue *mq = cls;
struct NeighbourMapEntry *n;
GNUNET_SCHEDULER_cancel (n->task);
n->task = GNUNET_SCHEDULER_add_now (&master_task, n);
}
- GNUNET_assert (bytes_in_send_queue >= mq->message_buf_size);
+ if (bytes_in_send_queue < mq->message_buf_size)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "bytes_in_send_queue `%u' mq->message_buf_size %u\n",
+ bytes_in_send_queue, mq->message_buf_size );
+ GNUNET_break (0);
+ }
+
+
+ GNUNET_break (size_payload == mq->message_buf_size);
bytes_in_send_queue -= mq->message_buf_size;
GNUNET_STATISTICS_set (GST_stats,
gettext_noop
ntohs (((struct GNUNET_MessageHeader *) mq->message_buf)->type),
(success == GNUNET_OK) ? "success" : "FAILURE");
if (NULL != mq->cont)
- mq->cont (mq->cont_cls, success);
+ mq->cont (mq->cont_cls, success, size_payload, physical);
GNUNET_free (mq);
}
1, GNUNET_NO);
GNUNET_CONTAINER_DLL_remove (n->messages_head, n->messages_tail, mq);
n->is_active = mq;
- transmit_send_continuation (mq, &n->id, GNUNET_SYSERR); /* timeout */
+ transmit_send_continuation (mq, &n->id, GNUNET_SYSERR, mq->message_buf_size, 0); /* timeout */
}
if (NULL == mq)
return; /* no more messages */
{
GNUNET_break (0);
if (NULL != cont)
- cont (cont_cls, GNUNET_SYSERR);
+ cont (cont_cls, GNUNET_SYSERR, msg_size, 0);
return;
}
if (GNUNET_YES != test_connected (n))
{
GNUNET_break (0);
if (NULL != cont)
- cont (cont_cls, GNUNET_SYSERR);
+ cont (cont_cls, GNUNET_SYSERR, msg_size, 0);
return;
}
bytes_in_send_queue += msg_size;
{
struct GNUNET_TRANSPORT_PluginFunctions *papi;
struct SessionConnectMessage connect_msg;
-
+
if (NULL == (papi = GST_plugins_find (na->address->transport_name)))
{
GNUNET_break (0);
UINT_MAX,
GNUNET_TIME_UNIT_FOREVER_REL,
NULL, NULL);
+
}
{
struct GNUNET_TRANSPORT_PluginFunctions *papi;
struct SessionConnectMessage connect_msg;
-
+
if (NULL == (papi = GST_plugins_find (address->transport_name)))
{
GNUNET_break (0);
UINT_MAX,
GNUNET_TIME_UNIT_FOREVER_REL,
NULL, NULL);
+
}
/* fallthrough */
case S_INIT_BLACKLIST:
case S_CONNECT_SENT:
+ case S_CONNECT_RECV_BLACKLIST_INBOUND:
case S_CONNECT_RECV_ATS:
case S_CONNECT_RECV_BLACKLIST:
case S_CONNECT_RECV_ACK:
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "ATS tells us to switch to address '%s' session %p for peer `%s' in state %s\n",
+ "ATS tells us to switch to address '%s' session %p for "
+ "peer `%s' in state %s (quota in/out %u %u )\n",
(address->address_length != 0) ? GST_plugins_a2s (address): "<inbound>",
session,
GNUNET_i2s (peer),
- print_state (n->state));
+ print_state (n->state),
+ ntohl (bandwidth_in.value__),
+ ntohl (bandwidth_out.value__));
if (NULL == session)
{
"Cleaning up connection to `%s' after sending DISCONNECT\n",
GNUNET_i2s (&n->id));
free_neighbour (n, GNUNET_NO);
- n->state = S_DISCONNECT_FINISHED;
return;
case S_DISCONNECT_FINISHED:
/* how did we get here!? */
gettext_noop ("# peers connected"),
++neighbours_connected,
GNUNET_NO);
- connect_notify_cb (callback_cls, &n->id, ats, ats_count);
+ connect_notify_cb (callback_cls, &n->id, ats, ats_count,
+ n->primary_address.bandwidth_in,
+ n->primary_address.bandwidth_out);
/* Tell ATS that the outbound session we created to send CONNECT was successfull */
GNUNET_ATS_address_add (GST_ats,
n->primary_address.address,
break;
case S_DISCONNECT_FINISHED:
/* neighbour was freed and plugins told to terminate session */
+ return GNUNET_NO;
break;
default:
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unhandled state `%s' \n",print_state (n->state));
gettext_noop ("# peers connected"),
++neighbours_connected,
GNUNET_NO);
- connect_notify_cb (callback_cls, &n->id, ats, ats_count);
+ connect_notify_cb (callback_cls, &n->id, ats, ats_count,
+ n->primary_address.bandwidth_in,
+ n->primary_address.bandwidth_out);
GNUNET_ATS_address_add(GST_ats,
n->primary_address.address,
n->primary_address.session,
struct NeighbourMapEntry *n = value;
if (GNUNET_YES == test_connected (n))
- ic->cb (ic->cb_cls, &n->id, NULL, 0, n->primary_address.address);
+ {
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in;
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out;
+
+ if (NULL != n->primary_address.address)
+ {
+ bandwidth_in = n->primary_address.bandwidth_in;
+ bandwidth_out = n->primary_address.bandwidth_out;
+ }
+ else
+ {
+ bandwidth_in = GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT;
+ bandwidth_out = GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT;
+ }
+
+ ic->cb (ic->cb_cls, &n->id, NULL, 0,
+ n->primary_address.address,
+ bandwidth_in, bandwidth_out);
+ }
return GNUNET_OK;
}
switch (n->state)
{
case S_CONNECTED:
+ case S_CONNECTED_SWITCHING_CONNECT_SENT:
+ case S_CONNECTED_SWITCHING_BLACKLIST:
case S_RECONNECT_SENT:
case S_RECONNECT_ATS:
+ case S_RECONNECT_BLACKLIST:
return n->latency;
case S_NOT_CONNECTED:
case S_INIT_BLACKLIST:
case S_INIT_ATS:
case S_CONNECT_RECV_BLACKLIST_INBOUND:
- case S_CONNECT_SENT:
+ case S_CONNECT_RECV_ATS:
case S_CONNECT_RECV_BLACKLIST:
+ case S_CONNECT_RECV_ACK:
+ case S_CONNECT_SENT:
case S_DISCONNECT:
case S_DISCONNECT_FINISHED:
return GNUNET_TIME_UNIT_FOREVER_REL;
*/
void
GST_neighbours_start (void *cls,
- GNUNET_TRANSPORT_NotifyConnect connect_cb,
+ NotifyConnect connect_cb,
GNUNET_TRANSPORT_NotifyDisconnect disconnect_cb,
GNUNET_TRANSPORT_PeerIterateCallback peer_address_cb)
{
connect_notify_cb = connect_cb;
disconnect_notify_cb = disconnect_cb;
address_change_cb = peer_address_cb;
- neighbours = GNUNET_CONTAINER_multihashmap_create (NEIGHBOUR_TABLE_SIZE);
+ neighbours = GNUNET_CONTAINER_multihashmap_create (NEIGHBOUR_TABLE_SIZE, GNUNET_NO);
}