*/
int public_key_valid;
+ /**
+ * Performance data for the peer.
+ */
+ struct GNUNET_TRANSPORT_ATS_Information *ats;
+
+ /**
+ * Identity of the neighbour.
+ */
+ struct GNUNET_PeerIdentity peer;
+
};
/**
*
* @param cls closure, identifies the entry on the
* message queue that was transmitted and the
- * client responsible for queueing the message
+ * client responsible for queuing the message
* @param target the peer receiving the message
* @param result GNUNET_OK on success, if the transmission
* failed, we should not tell the client to transmit
static void
notify_clients_connect (const struct GNUNET_PeerIdentity *peer,
struct GNUNET_TIME_Relative latency,
- uint32_t distance)
+ uint32_t distance)
{
- struct ConnectInfoMessage cim;
+ struct ConnectInfoMessage * cim;
struct TransportClient *cpos;
+ uint32_t ats_count;
+ size_t size;
#if DEBUG_TRANSPORT
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
gettext_noop ("# peers connected"),
1,
GNUNET_NO);
- cim.header.size = htons (sizeof (struct ConnectInfoMessage));
- cim.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT);
- cim.distance = htonl (distance);
- cim.latency = GNUNET_TIME_relative_hton (latency);
- cim.ats_count = htonl(0);
- cim.ats.type = htonl(0);
- cim.ats.value = htonl(0);
- memcpy (&cim.id, peer, sizeof (struct GNUNET_PeerIdentity));
+
+ ats_count = 2;
+ size = sizeof (struct ConnectInfoMessage) + ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
+ if (size > GNUNET_SERVER_MAX_MESSAGE_SIZE)
+ {
+ GNUNET_break(0);
+ }
+ cim = GNUNET_malloc (size);
+
+ cim->header.size = htons (size);
+ cim->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT);
+ cim->ats_count = htonl(2);
+ (&(cim->ats))[0].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE);
+ (&(cim->ats))[0].value = htonl (distance);
+ (&(cim->ats))[1].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DELAY);
+ (&(cim->ats))[1].value = htonl ((uint32_t) latency.rel_value);
+ (&(cim->ats))[2].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR);
+ (&(cim->ats))[2].value = htonl (0);
+ memcpy (&cim->id, peer, sizeof (struct GNUNET_PeerIdentity));
cpos = clients;
while (cpos != NULL)
{
- transmit_to_client (cpos, &cim.header, GNUNET_NO);
+ transmit_to_client (cpos, &(cim->header), GNUNET_NO);
cpos = cpos->next;
}
+ GNUNET_free (cim);
}
*
* @param message the payload
* @param n peer who claimed to be the sender
- * @param ats ATS information
- * @param ats_count numbers of elements following the ats struct (excluding the 0-terminator)
*/
static void
handle_payload_message (const struct GNUNET_MessageHeader *message,
- struct NeighbourList *n, struct GNUNET_TRANSPORT_ATS_Information *ats, uint32_t ats_count)
+ struct NeighbourList *n)
{
struct InboundMessage *im;
struct TransportClient *cpos;
gettext_noop ("# payload received from other peers"),
msize,
GNUNET_NO);
-
/* transmit message to all clients */
- im = GNUNET_malloc (sizeof (struct InboundMessage) + ats_count * sizeof(struct GNUNET_TRANSPORT_ATS_Information) + msize);
- im->header.size = htons (sizeof (struct InboundMessage) + ats_count * sizeof(struct GNUNET_TRANSPORT_ATS_Information) + msize);
+ uint32_t ats_count = 2;
+ size_t size = sizeof (struct InboundMessage) + ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information) + msize;
+ if (size > GNUNET_SERVER_MAX_MESSAGE_SIZE)
+ GNUNET_break(0);
+
+ im = GNUNET_malloc (size);
+ im->header.size = htons (size);
im->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_RECV);
im->peer = n->id;
im->ats_count = htonl(ats_count);
- /* insert ATS elements */
- memcpy (&(im->ats), ats, ats_count * sizeof(struct GNUNET_TRANSPORT_ATS_Information));
- /* insert ATS terminator */
- (&im->ats)[ats_count].type = htonl(0);
- (&im->ats)[ats_count].value = htonl(0);
- /* insert msg after terminator */
- memcpy (&(&im->ats)[ats_count+1], message, msize);
-
+ /* Setting ATS data */
+ (&(im->ats))[0].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE);
+ (&(im->ats))[0].value = htonl (n->distance);
+ (&(im->ats))[1].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DELAY);
+ (&(im->ats))[1].value = htonl ((uint32_t) n->latency.rel_value);
+ (&(im->ats))[ats_count].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR);
+ (&(im->ats))[ats_count].value = htonl (0);
+
+ memcpy (&((&(im->ats))[ats_count+1]), message, msize);
cpos = clients;
while (cpos != NULL)
{
if (NULL != (prem = n->pre_connect_message_buffer))
{
n->pre_connect_message_buffer = NULL;
- struct GNUNET_TRANSPORT_ATS_Information * ats = GNUNET_malloc(2 * sizeof(struct GNUNET_TRANSPORT_ATS_Information));
- ats[0].type = htonl(GNUNET_TRANSPORT_ATS_QUALITY_NET_DELAY);
- if (n->latency.rel_value <= UINT32_MAX)
- ats[0].value = htonl((uint32_t) n->latency.rel_value);
- else
- ats[0].value = htonl(UINT32_MAX);
- ats[1].type = htonl(GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE);
- ats[1].value = htonl(n->distance);
- //handle_payload_message (prem, n, NULL, 0);
- handle_payload_message (prem, n, ats, 2);
- GNUNET_free (ats);
+ handle_payload_message (prem, n);
GNUNET_free (prem);
}
}
memcpy (&pong[1],
plugin->short_name,
slen);
- memcpy (&((char*)&pong[1])[slen],
- sender_address,
- sender_address_len);
+ if ((sender_address!=NULL) && (sender_address_len > 0))
+ memcpy (&((char*)&pong[1])[slen],
+ sender_address,
+ sender_address_len);
if (GNUNET_TIME_absolute_get_remaining (session_header->pong_sig_expires).rel_value < PONG_SIGNATURE_LIFETIME.rel_value / 4)
{
/* create / update cached sig */
* @param peer (claimed) identity of the other peer
* @param message the message, NULL if we only care about
* learning about the delay until we should receive again
- * @param distance in overlay hops; use 1 unless DV (or 0 if message == NULL)
+ * @param ats information for automatic transport selection
+ * @param ats_count number of elements in ats not including 0-terminator
* @param session identifier used for this session (can be NULL)
* @param sender_address binary address of the sender (if observed)
* @param sender_address_len number of bytes in sender_address
static struct GNUNET_TIME_Relative
plugin_env_receive (void *cls, const struct GNUNET_PeerIdentity *peer,
const struct GNUNET_MessageHeader *message,
- uint32_t distance,
- struct Session *session,
- const char *sender_address,
+ const struct GNUNET_TRANSPORT_ATS_Information *ats,
+ uint32_t ats_count,
+ struct Session *session,
+ const char *sender_address,
uint16_t sender_address_len)
{
struct TransportPlugin *plugin = cls;
struct ForeignAddressList *peer_address;
uint16_t msize;
struct NeighbourList *n;
- struct GNUNET_TRANSPORT_ATS_Information * ats;
struct GNUNET_TIME_Relative ret;
if (is_blacklisted (peer, plugin))
return GNUNET_TIME_UNIT_FOREVER_REL;
+ uint32_t distance;
+ int c;
n = find_neighbour (peer);
if (n == NULL)
service_context = service_context->next;
GNUNET_assert ((plugin->api->send == NULL) || (service_context != NULL));
peer_address = NULL;
+ distance = 1;
+ for (c=0; c<ats_count; c++)
+ {
+ if (ntohl(ats[c].type) == GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE)
+ {
+ distance = ntohl(ats[c].value);
+ }
+ }
+
if (message != NULL)
{
if ( (session != NULL) ||
handle_pong (plugin, message, peer, sender_address, sender_address_len);
break;
default:
- ats = GNUNET_malloc(2 * sizeof(struct GNUNET_TRANSPORT_ATS_Information));
- ats[0].type = htonl(GNUNET_TRANSPORT_ATS_QUALITY_NET_DELAY);
- if (n->latency.rel_value <= UINT32_MAX)
- ats[0].value = htonl((uint32_t) n->latency.rel_value);
- else
- ats[0].value = htonl(UINT32_MAX);
- ats[1].type = htonl(GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE);
- ats[1].value = htonl(n->distance);
- //handle_payload_message (message, n, NULL, 0);
- handle_payload_message (message, n, ats, 2);
- GNUNET_free(ats);
+ handle_payload_message (message, n);
break;
}
}
{
const struct StartMessage *start;
struct TransportClient *c;
- struct ConnectInfoMessage cim;
+ struct ConnectInfoMessage * cim;
struct NeighbourList *n;
+ uint32_t ats_count;
+ size_t size;
start = (const struct StartMessage*) message;
#if DEBUG_TRANSPORT
clients = c;
c->client = client;
if (our_hello != NULL)
- {
+ {
#if DEBUG_TRANSPORT
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Sending our own `%s' to new client\n", "HELLO");
(const struct GNUNET_MessageHeader *) our_hello,
GNUNET_NO);
/* tell new client about all existing connections */
- cim.header.size = htons (sizeof (struct ConnectInfoMessage));
- cim.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT);
- cim.ats_count = htonl(0);
- cim.ats.type = htonl(0);
- cim.ats.value = htonl(0);
+ ats_count = 2;
+ size = sizeof (struct ConnectInfoMessage) + ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
+ if (size > GNUNET_SERVER_MAX_MESSAGE_SIZE)
+ {
+ GNUNET_break(0);
+ }
+ cim = GNUNET_malloc (size);
+ cim->header.size = htons (size);
+ cim->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT);
+ cim->ats_count = htonl(ats_count);
+ (&(cim->ats))[2].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR);
+ (&(cim->ats))[2].value = htonl (0);
n = neighbours;
while (n != NULL)
- {
- if (GNUNET_YES == n->received_pong)
- {
- cim.id = n->id;
- cim.latency = GNUNET_TIME_relative_hton (n->latency);
- cim.distance = htonl (n->distance);
- transmit_to_client (c, &cim.header, GNUNET_NO);
- }
+ {
+ if (GNUNET_YES == n->received_pong)
+ {
+ (&(cim->ats))[0].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE);
+ (&(cim->ats))[0].value = htonl (n->distance);
+ (&(cim->ats))[1].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DELAY);
+ (&(cim->ats))[1].value = htonl ((uint32_t) n->latency.rel_value);
+ cim->id = n->id;
+ transmit_to_client (c, &cim->header, GNUNET_NO);
+ }
n = n->next;
- }
- }
+ }
+ GNUNET_free (cim);
+ }
GNUNET_SERVER_receive_done (client, GNUNET_OK);
}