static void
handle_peer_status_change (struct Neighbour *n)
{
- struct PeerStatusNotifyMessage psnm;
+ struct PeerStatusNotifyMessage *psnm;
+ char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1];
+ struct GNUNET_TRANSPORT_ATS_Information *ats;
+ size_t size;
if ( (! n->is_connected) ||
(n->status != PEER_STATE_KEY_CONFIRMED) )
"Peer `%4s' changed status\n",
GNUNET_i2s (&n->peer));
#endif
- psnm.header.size = htons (sizeof (struct PeerStatusNotifyMessage));
- psnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_STATUS_CHANGE);
- psnm.ats_count = htonl (0);
- psnm.ats.type = htonl (0);
- psnm.ats.value = htonl (0);
- psnm.timeout = GNUNET_TIME_absolute_hton (get_neighbour_timeout (n));
- psnm.bandwidth_in = n->bw_in;
- psnm.bandwidth_out = n->bw_out;
- psnm.peer = n->peer;
- send_to_all_clients (&psnm.header,
+ size = sizeof (struct PeerStatusNotifyMessage) +
+ n->ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
+ if (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
+ {
+ GNUNET_break (0);
+ /* recovery strategy: throw away performance data */
+ GNUNET_array_grow (n->ats,
+ n->ats_count,
+ 0);
+ size = sizeof (struct PeerStatusNotifyMessage) +
+ n->ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
+ }
+ psnm = (struct PeerStatusNotifyMessage*) buf;
+ psnm->header.size = htons (size);
+ psnm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_STATUS_CHANGE);
+ psnm->timeout = GNUNET_TIME_absolute_hton (get_neighbour_timeout (n));
+ psnm->bandwidth_in = n->bw_in;
+ psnm->bandwidth_out = n->bw_out;
+ psnm->peer = n->peer;
+ psnm->ats_count = htonl (n->ats_count);
+ ats = &psnm->ats;
+ memcpy (ats,
+ n->ats,
+ n->ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information));
+ ats[n->ats_count].type = htonl (0);
+ ats[n->ats_count].value = htonl (0);
+ send_to_all_clients (&psnm->header,
GNUNET_YES,
GNUNET_CORE_OPTION_SEND_STATUS_CHANGE);
GNUNET_STATISTICS_update (stats,
const uint16_t *types;
uint16_t *wtypes;
struct Neighbour *n;
- struct ConnectNotifyMessage cnm;
+ struct ConnectNotifyMessage *cnm;
+ char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1];
+ struct GNUNET_TRANSPORT_ATS_Information *ats;
+ size_t size;
unsigned int i;
#if DEBUG_CORE_CLIENT
if (0 != (c->options & GNUNET_CORE_OPTION_SEND_CONNECT))
{
/* notify new client about existing neighbours */
- cnm.header.size = htons (sizeof (struct ConnectNotifyMessage));
- cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
- cnm.ats_count = htonl (0);
- cnm.ats.type = htonl (0);
- cnm.ats.value = htonl (0);
n = neighbours;
while (n != NULL)
{
+ size = sizeof (struct ConnectNotifyMessage) +
+ (n->ats_count) * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
+ if (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
+ {
+ GNUNET_break (0);
+ /* recovery strategy: throw away performance data */
+ GNUNET_array_grow (n->ats,
+ n->ats_count,
+ 0);
+ size = sizeof (struct ConnectNotifyMessage) +
+ (n->ats_count) * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
+ }
+ cnm = (struct ConnectNotifyMessage*) buf;
+ cnm->header.size = htons (size);
+ cnm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
+ cnm->ats_count = htonl (n->ats_count);
+ ats = &cnm->ats;
+ memcpy (ats,
+ n->ats,
+ sizeof (struct GNUNET_TRANSPORT_ATS_Information) * n->ats_count);
+ ats[n->ats_count].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR);
+ ats[n->ats_count].value = htonl (0);
if (n->status == PEER_STATE_KEY_CONFIRMED)
{
#if DEBUG_CORE_CLIENT
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Sending `%s' message to client.\n", "NOTIFY_CONNECT");
#endif
- cnm.peer = n->peer;
- send_to_client (c, &cnm.header, GNUNET_NO);
+ cnm->peer = n->peer;
+ send_to_client (c, &cnm->header, GNUNET_NO);
}
n = n->next;
}
/**
* Handle CORE_ITERATE_PEERS request.
+ *
+ * @param cls unused
+ * @param client client sending the iteration request
+ * @param message iteration request message
*/
static void
handle_client_iterate_peers (void *cls,
{
struct Neighbour *n;
- struct ConnectNotifyMessage cnm;
+ struct ConnectNotifyMessage *cnm;
struct GNUNET_MessageHeader done_msg;
struct GNUNET_SERVER_TransmitContext *tc;
+ char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1];
+ struct GNUNET_TRANSPORT_ATS_Information *ats;
+ size_t size;
/* notify new client about existing neighbours */
- cnm.header.size = htons (sizeof (struct ConnectNotifyMessage));
- cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
- done_msg.size = htons (sizeof (struct GNUNET_MessageHeader));
- done_msg.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
tc = GNUNET_SERVER_transmit_context_create (client);
+ cnm = (struct ConnectNotifyMessage*) buf;
n = neighbours;
- cnm.ats_count = htonl (0);
- cnm.ats.type = htonl (0);
- cnm.ats.value = htonl (0);
while (n != NULL)
{
if (n->status == PEER_STATE_KEY_CONFIRMED)
{
+ size = sizeof (struct ConnectNotifyMessage) +
+ (n->ats_count) * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
+ if (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
+ {
+ GNUNET_break (0);
+ /* recovery strategy: throw away performance data */
+ GNUNET_array_grow (n->ats,
+ n->ats_count,
+ 0);
+ size = sizeof (struct PeerStatusNotifyMessage) +
+ n->ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
+ }
+ cnm = (struct ConnectNotifyMessage*) buf;
+ cnm->header.size = htons (size);
+ cnm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
+ cnm->ats_count = htonl (n->ats_count);
+ ats = &cnm->ats;
+ memcpy (ats,
+ n->ats,
+ n->ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information));
+ ats[n->ats_count].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR);
+ ats[n->ats_count].value = htonl (0);
#if DEBUG_CORE_CLIENT
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Sending `%s' message to client.\n", "NOTIFY_CONNECT");
+ "Sending `%s' message to client.\n",
+ "NOTIFY_CONNECT");
#endif
- cnm.peer = n->peer;
- GNUNET_SERVER_transmit_context_append_message (tc, &cnm.header);
+ cnm->peer = n->peer;
+ GNUNET_SERVER_transmit_context_append_message (tc,
+ &cnm->header);
}
n = n->next;
}
+ done_msg.size = htons (sizeof (struct GNUNET_MessageHeader));
+ done_msg.type = htons (GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS_END);
GNUNET_SERVER_transmit_context_append_message (tc, &done_msg);
GNUNET_SERVER_transmit_context_run (tc,
GNUNET_TIME_UNIT_FOREVER_REL);
if (ats_count == 0)
return;
- for (i=0;i<ats_count;i++)
+ for (i = 0; i < ats_count; i++)
{
- for (j=0;j<n->ats_count;j++)
+ for (j=0;j < n->ats_count; j++)
{
if (n->ats[j].type == ats[i].type)
{
break;
}
}
- if (j == n->ats_count)
- GNUNET_array_append (n->ats,
- n->ats_count,
- *ats);
+ if (j == n->ats_count)
+ {
+ GNUNET_array_append (n->ats,
+ n->ats_count,
+ ats[i]);
+ }
}
}
uint32_t ats_count)
{
struct PongMessage t;
- struct ConnectNotifyMessage cnm;
+ struct ConnectNotifyMessage *cnm;
struct GNUNET_CRYPTO_AesInitializationVector iv;
+ char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1];
+ struct GNUNET_TRANSPORT_ATS_Information *mats;
+ size_t size;
#if DEBUG_CORE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
GNUNET_SCHEDULER_cancel (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.ats_count = htonl (0);
- cnm.peer = n->peer;
- cnm.ats.type = htonl (0);
- cnm.ats.value = htonl (0);
- send_to_all_clients (&cnm.header, GNUNET_NO, GNUNET_CORE_OPTION_SEND_CONNECT);
+ update_neighbour_performance (n, ats, ats_count);
+ size = sizeof (struct ConnectNotifyMessage) +
+ (n->ats_count) * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
+ if (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
+ {
+ GNUNET_break (0);
+ /* recovery strategy: throw away performance data */
+ GNUNET_array_grow (n->ats,
+ n->ats_count,
+ 0);
+ size = sizeof (struct PeerStatusNotifyMessage) +
+ n->ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
+ }
+ cnm = (struct ConnectNotifyMessage*) buf;
+ cnm->header.size = htons (size);
+ cnm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
+ cnm->ats_count = htonl (n->ats_count);
+ cnm->peer = n->peer;
+ mats = &cnm->ats;
+ memcpy (mats,
+ n->ats,
+ n->ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information));
+ mats[n->ats_count].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR);
+ mats[n->ats_count].value = htonl (0);
+ send_to_all_clients (&cnm->header,
+ GNUNET_NO,
+ GNUNET_CORE_OPTION_SEND_CONNECT);
process_encrypted_neighbour_queue (n);
/* fall-through! */
case PEER_STATE_KEY_CONFIRMED:
= GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_divide (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, 2),
&send_keep_alive,
n);
- update_neighbour_performance (n, ats, ats_count);
handle_peer_status_change (n);
break;
default:
struct Client *client,
const void *m, size_t msize)
{
- char buf[msize + sizeof (struct NotifyTrafficMessage)];
+ size_t size = msize + sizeof (struct NotifyTrafficMessage) +
+ (sender->ats_count) * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
+ char buf[size];
struct NotifyTrafficMessage *ntm;
+ struct GNUNET_TRANSPORT_ATS_Information *ats;
+ if (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
+ {
+ GNUNET_break (0);
+ /* recovery strategy: throw performance data away... */
+ GNUNET_array_grow (sender->ats,
+ sender->ats_count,
+ 0);
+ size = msize + sizeof (struct NotifyTrafficMessage) +
+ (sender->ats_count) * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
+ }
#if DEBUG_CORE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Core service passes message from `%4s' of type %u to client.\n",
(unsigned int) ntohs (((const struct GNUNET_MessageHeader *) m)->type));
#endif
ntm = (struct NotifyTrafficMessage *) buf;
- ntm->header.size = htons (msize + sizeof (struct NotifyTrafficMessage));
+ ntm->header.size = htons (size);
ntm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND);
- ntm->ats_count = htonl (0);
- ntm->ats.type = htonl (0);
- ntm->ats.value = htonl (0);
+ ntm->ats_count = htonl (sender->ats_count);
ntm->peer = sender->peer;
- memcpy (&ntm[1], m, msize);
+ ats = &ntm->ats;
+ memcpy (ats,
+ sender->ats,
+ sizeof (struct GNUNET_TRANSPORT_ATS_Information) * sender->ats_count);
+ ats[sender->ats_count].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR);
+ ats[sender->ats_count].value = htonl (0);
+ memcpy (&ats[sender->ats_count+1],
+ m,
+ msize);
send_to_client (client, &ntm->header, GNUNET_YES);
}
cnm.peer = *peer;
send_to_all_clients (&cnm.header, GNUNET_NO, GNUNET_CORE_OPTION_SEND_DISCONNECT);
}
- if (NULL != n->th)
+
+ /* On transport disconnect transport doesn't cancel requests, so must do so here. */
+ if (n->th != NULL)
{
- GNUNET_TRANSPORT_notify_transmit_ready_cancel (n->th);
- n->th = NULL;
+ GNUNET_TRANSPORT_notify_transmit_ready_cancel(n->th);
}
+ n->th = NULL;
+
n->is_connected = GNUNET_NO;
n->status = PEER_STATE_DOWN;
while (NULL != (car = n->active_client_request_head))