static int ret;
static int results;
static int resolve_addresses_numeric;
+static int receive_done;
+
/**
* For which peer should we change preference values?
*/
static char *type_str;
static unsigned int value;
+static int pending;
/**
* Print verbose ATS information
struct PendingResolutions *head;
struct PendingResolutions *tail;
+void end (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ struct PendingResolutions * pr;
+ struct PendingResolutions * next;
+ unsigned int pending;
+
+ if (NULL != alh)
+ {
+ GNUNET_ATS_performance_list_addresses_cancel (alh);
+ alh = NULL;
+ }
+
+ if (NULL != ph)
+ {
+ GNUNET_ATS_performance_done (ph);
+ ph = NULL;
+ }
+
+ pending = 0;
+ next = head;
+ while (NULL != (pr = next))
+ {
+ next = pr->next;
+ GNUNET_CONTAINER_DLL_remove (head, tail, pr);
+ GNUNET_TRANSPORT_address_to_string_cancel (pr->tats_ctx);
+ GNUNET_free (pr->address);
+ GNUNET_free (pr);
+ pending ++;
+ }
+ if (0 < pending)
+ fprintf (stderr, _("%u address resolutions had a timeout\n"), pending);
+
+ fprintf (stderr, _("ATS returned results for %u addresses\n"), results);
+ ret = 0;
+}
+
+
void transport_addr_to_str_cb (void *cls, const char *address)
{
struct PendingResolutions * pr = cls;
unsigned int c;
uint32_t ats_type;
uint32_t ats_value;
-
if (NULL != address)
{
- ats_str = GNUNET_strdup("");
- if (verbose)
- {
- for (c = 0; c < pr->ats_count; c++)
- {
- ats_tmp = ats_str;
-
- ats_type = ntohl(pr->ats[c].type);
- ats_value = ntohl(pr->ats[c].value);
-
- if (ats_type > GNUNET_ATS_PropertyCount)
- {
- GNUNET_break (0);
- continue;
- }
-
- switch (ats_type) {
- case GNUNET_ATS_NETWORK_TYPE:
- if (ats_value > GNUNET_ATS_NetworkTypeCount)
- {
- GNUNET_break (0);
- continue;
- }
- GNUNET_asprintf (&ats_prop_value, "%s", ats_net_arr[ats_value]);
- break;
- default:
- GNUNET_asprintf (&ats_prop_value, "%u", ats_value);
- break;
- }
-
- GNUNET_asprintf (&ats_str, "%s%s=%s, ", ats_tmp, ats_prop_arr[ats_type] , ats_prop_value);
- GNUNET_free (ats_tmp);
- GNUNET_free (ats_prop_value);
+ ats_str = GNUNET_strdup("");
+ if (verbose)
+ {
+ for (c = 0; c < pr->ats_count; c++)
+ {
+ ats_tmp = ats_str;
+
+ ats_type = ntohl(pr->ats[c].type);
+ ats_value = ntohl(pr->ats[c].value);
+
+ if (ats_type > GNUNET_ATS_PropertyCount)
+ {
+ GNUNET_break (0);
+ continue;
+ }
+
+ switch (ats_type) {
+ case GNUNET_ATS_NETWORK_TYPE:
+ if (ats_value > GNUNET_ATS_NetworkTypeCount)
+ {
+ GNUNET_break (0);
+ continue;
+ }
+ GNUNET_asprintf (&ats_prop_value, "%s", ats_net_arr[ats_value]);
+ break;
+ default:
+ GNUNET_asprintf (&ats_prop_value, "%u", ats_value);
+ break;
}
+
+ GNUNET_asprintf (&ats_str, "%s%s=%s, ", ats_tmp, ats_prop_arr[ats_type] , ats_prop_value);
+ GNUNET_free (ats_tmp);
+ GNUNET_free (ats_prop_value);
}
+ }
- fprintf (stderr, _("Peer `%s' plugin `%s', address `%s', bw out: %u Bytes/s, bw in %u Bytes/s, %s\n"),
- GNUNET_i2s (&pr->address->peer), pr->address->transport_name, address,
- ntohl (pr->bandwidth_out.value__), ntohl (pr->bandwidth_in.value__),ats_str);
- GNUNET_free (ats_str);
+ fprintf (stderr, _("Peer `%s' plugin `%s', address `%s', bw out: %u Bytes/s, bw in %u Bytes/s, %s\n"),
+ GNUNET_i2s (&pr->address->peer), pr->address->transport_name, address,
+ ntohl (pr->bandwidth_out.value__), ntohl (pr->bandwidth_in.value__),ats_str);
+ GNUNET_free (ats_str);
}
- else if (NULL != pr)
+ else
{
- /* We're done */
- GNUNET_CONTAINER_DLL_remove (head, tail, pr);
- GNUNET_free (pr->address);
- GNUNET_free (pr);
- }
+ /* We're done */
+ GNUNET_CONTAINER_DLL_remove (head, tail, pr);
+ GNUNET_free (pr->address);
+ GNUNET_free (pr);
+ pending--;
+ if ((GNUNET_YES == receive_done) && (0 == pending))
+ {
+ /* All messages received and no resolutions pending*/
+ if (end_task != GNUNET_SCHEDULER_NO_TASK)
+ GNUNET_SCHEDULER_cancel (end_task);
+ end_task = GNUNET_SCHEDULER_add_now (end, NULL);
+ }
+ }
}
void ats_perf_cb (void *cls,
resolve_addresses_numeric, GNUNET_TIME_UNIT_FOREVER_REL, transport_addr_to_str_cb, pr);
GNUNET_CONTAINER_DLL_insert (head, tail, pr);
results++;
+ pending++;
}
-}
-
-
-void end (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- struct PendingResolutions * pr;
- struct PendingResolutions * next;
- unsigned int pending;
-
- if (NULL != alh)
- {
- GNUNET_ATS_performance_list_addresses_cancel (alh);
- alh = NULL;
- }
-
- GNUNET_ATS_performance_done (ph);
- ph = NULL;
-
- pending = 0;
- next = head;
- while (NULL != (pr = next))
+ else
{
- next = pr->next;
- GNUNET_CONTAINER_DLL_remove (head, tail, pr);
- GNUNET_TRANSPORT_address_to_string_cancel (pr->tats_ctx);
- GNUNET_free (pr->address);
- GNUNET_free (pr);
- pending ++;
+ /* All messages received */
+ receive_done = GNUNET_YES;
+ if (0 == pending)
+ {
+ /* All messages received and no resolutions pending*/
+ if (end_task != GNUNET_SCHEDULER_NO_TASK)
+ GNUNET_SCHEDULER_cancel (end_task);
+ end_task = GNUNET_SCHEDULER_add_now (end, NULL);
+ }
}
- if (0 < pending)
- fprintf (stderr, _("%u address resolutions had a timeout\n"), pending);
-
- fprintf (stderr, _("ATS returned results for %u addresses\n"), results);
- ret = 0;
}
+
void testservice_ats (void *cls,
const struct GNUNET_SCHEDULER_TaskContext *tc)
{
end_task = GNUNET_SCHEDULER_add_now (&end, NULL);
return;
}
-
end_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &end, NULL);
-
}
else if (op_list_used)
{
end_task = GNUNET_SCHEDULER_add_now (&end, NULL);
return;
}
-
-
end_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &end, NULL);
}
else if (op_monitor)
op_monitor = GNUNET_NO;
op_list_all = GNUNET_NO;
op_list_used = GNUNET_NO;
+ pending = 0;
+ receive_done = GNUNET_NO;
static const struct GNUNET_GETOPT_CommandLineOption options[] = {
{'u', "used", NULL,
uint32_t address_active GNUNET_PACKED;
+ uint32_t id GNUNET_PACKED;
+
struct GNUNET_PeerIdentity peer;
uint16_t address_length GNUNET_PACKED;
{
struct GNUNET_MessageHeader header;
+ uint32_t id GNUNET_PACKED;
+
int32_t all GNUNET_PACKED;
struct GNUNET_PeerIdentity peer;
* Return all or used address only
*/
int all_addresses;
+
+ /**
+ * Request multiplexing
+ */
+ uint32_t id;
};
/**
*/
GNUNET_SCHEDULER_TaskIdentifier task;
+ /**
+ * Request multiplexing
+ */
+ uint32_t id;
};
GNUNET_break (0);
return GNUNET_SYSERR;
}
+
pi = (const struct PeerInformationMessage *) msg;
ats_count = ntohl (pi->ats_count);
plugin_address_length = ntohs (pi->address_length);
{
return GNUNET_OK;
}
+
address.peer = pi->peer;
address.address = plugin_address;
address.address_length = plugin_address_length;
process_ar_message (struct GNUNET_ATS_PerformanceHandle *ph,
const struct GNUNET_MessageHeader *msg)
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "TO BE IMPLEMENTED\n");
-# if 0
- TBD!
- const struct ReservationResultMessage *rr;
- struct GNUNET_ATS_ReservationContext *rc;
- int32_t amount;
+ const struct PeerInformationMessage *pi;
+ struct GNUNET_ATS_AddressListHandle *alh;
+ struct GNUNET_ATS_AddressListHandle *next;
+ const struct GNUNET_ATS_Information *atsi;
+ const char *plugin_address;
+ const char *plugin_name;
+ struct GNUNET_HELLO_Address address;
+ struct GNUNET_PeerIdentity allzeros;
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_zero;
+ uint16_t plugin_address_length;
+ uint16_t plugin_name_length;
+ uint32_t ats_count;
+ uint32_t active;
+ uint32_t id;
- if (ntohs (msg->size) < sizeof (struct ReservationResultMessage))
+ if (ntohs (msg->size) < sizeof (struct PeerInformationMessage))
{
GNUNET_break (0);
return GNUNET_SYSERR;
}
- rr = (const struct ReservationResultMessage *) msg;
- amount = ntohl (rr->amount);
- rc = ph->reservation_head;
- if (0 != memcmp (&rr->peer, &rc->peer, sizeof (struct GNUNET_PeerIdentity)))
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ _("Received %s message\n"), "ATS_ADDRESSLIST_RESPONSE");
+
+ pi = (const struct PeerInformationMessage *) msg;
+ id = ntohl (pi->id);
+ ats_count = ntohl (pi->ats_count);
+ active = ntohl (pi->address_active);
+ plugin_address_length = ntohs (pi->address_length);
+ plugin_name_length = ntohs (pi->plugin_name_length);
+ atsi = (const struct GNUNET_ATS_Information *) &pi[1];
+ plugin_address = (const char *) &atsi[ats_count];
+ plugin_name = &plugin_address[plugin_address_length];
+ if ((plugin_address_length + plugin_name_length +
+ ats_count * sizeof (struct GNUNET_ATS_Information) +
+ sizeof (struct PeerInformationMessage) != ntohs (msg->size)) ||
+ (ats_count >
+ GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_ATS_Information))
+ || (plugin_name[plugin_name_length - 1] != '\0'))
{
GNUNET_break (0);
return GNUNET_SYSERR;
}
- GNUNET_CONTAINER_DLL_remove (ph->reservation_head, ph->reservation_tail, rc);
- if ((amount == 0) || (rc->rcb != NULL))
+
+ next = ph->addresslist_head;
+ while (NULL != (alh = next))
{
- /* tell client if not cancelled */
- if (rc->rcb != NULL)
- rc->rcb (rc->rcb_cls, &rr->peer, amount,
- GNUNET_TIME_relative_ntoh (rr->res_delay));
- GNUNET_free (rc);
- return GNUNET_OK;
+ next = alh->next;
+ if (alh->id == id)
+ break;
}
- /* amount non-zero, but client cancelled, consider undo! */
- if (GNUNET_YES != rc->undo)
+ if (NULL == alh)
{
- GNUNET_free (rc);
- return GNUNET_OK; /* do not try to undo failed undos or negative amounts */
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+
+ memset (&allzeros, '\0', sizeof (allzeros));
+ if ((0 == memcmp (&allzeros, &pi->peer, sizeof (allzeros))) &&
+ (0 == plugin_name_length) &&
+ (0 == plugin_address_length) &&
+ (0 == ats_count))
+ {
+ /* Done */
+ bandwidth_zero.value__ = htonl (0);
+ alh->cb (ph->infocb_cls,
+ NULL,
+ bandwidth_zero, bandwidth_zero,
+ NULL, 0);
+ return GNUNET_OK;
+ }
+
+ address.peer = pi->peer;
+ address.address = plugin_address;
+ address.address_length = plugin_address_length;
+ address.transport_name = plugin_name;
+
+ if ((GNUNET_YES == alh->all_peers) || (GNUNET_YES == active))
+ {
+ alh->cb (ph->infocb_cls,
+ &address,
+ pi->bandwidth_out, pi->bandwidth_in,
+ atsi, ats_count);
}
- GNUNET_free (rc);
- (void) GNUNET_ATS_reserve_bandwidth (ph, &rr->peer, -amount, NULL, NULL);
-#endif
return GNUNET_OK;
}
ph->cfg = cfg;
ph->infocb = infocb;
ph->infocb_cls = infocb_cls;
+ ph->id = 0;
reconnect (ph);
return ph;
}
GNUNET_assert (NULL != handle);
alh = GNUNET_malloc (sizeof (struct GNUNET_ATS_AddressListHandle));
+ alh->id = handle->id;
+ handle->id ++;
alh->cb = infocb;
alh->cb_cls = infocb_cls;
alh->ph = handle;
m->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_ADDRESSLIST_REQUEST);
m->header.size = htons (sizeof (struct AddressListRequestMessage));
m->all = htonl (all);
+ m->id = htonl (alh->id);
if (NULL != peer)
m->peer = *peer;
else
int all;
+ uint32_t id;
+
unsigned int msg_type;
};
GAS_addresses_iterate_peers (&peer_it, pc);
}
+static void transmit_req_addr (struct AddressIteration *ai,
+ const struct GNUNET_PeerIdentity *id,
+ const char *plugin_name,
+ const void *plugin_addr, size_t plugin_addr_len,
+ const int active,
+ const struct GNUNET_ATS_Information *atsi,
+ uint32_t atsi_count,
+ struct GNUNET_BANDWIDTH_Value32NBO
+ bandwidth_out,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in)
+
+{
+ struct GNUNET_ATS_Information *atsp;
+ struct PeerInformationMessage *msg;
+ char *addrp;
+ size_t plugin_name_length;
+ size_t msize;
+
+ if (NULL != plugin_name)
+ plugin_name_length = strlen (plugin_name) + 1;
+ else
+ plugin_name_length = 0;
+ msize = sizeof (struct PeerInformationMessage) +
+ atsi_count * sizeof (struct GNUNET_ATS_Information) +
+ plugin_addr_len + plugin_name_length;
+ char buf[msize] GNUNET_ALIGN;
+
+ GNUNET_assert (msize < GNUNET_SERVER_MAX_MESSAGE_SIZE);
+ GNUNET_assert (atsi_count <
+ GNUNET_SERVER_MAX_MESSAGE_SIZE /
+ sizeof (struct GNUNET_ATS_Information));
+ msg = (struct PeerInformationMessage *) buf;
+ msg->header.size = htons (msize);
+ msg->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_ADDRESSLIST_RESPONSE);
+ msg->ats_count = htonl (atsi_count);
+ msg->id = htonl (ai->id);
+ if (NULL != id)
+ msg->peer = *id;
+ else
+ memset (&msg->peer, '\0', sizeof (struct GNUNET_PeerIdentity));
+ msg->address_length = htons (plugin_addr_len);
+ msg->address_active = ntohl (active);
+ msg->plugin_name_length = htons (plugin_name_length);
+ msg->bandwidth_out = bandwidth_out;
+ msg->bandwidth_in = bandwidth_in;
+ atsp = (struct GNUNET_ATS_Information *) &msg[1];
+ memcpy (atsp, atsi, sizeof (struct GNUNET_ATS_Information) * atsi_count);
+ addrp = (char *) &atsp[atsi_count];
+ if (NULL != plugin_addr)
+ memcpy (addrp, plugin_addr, plugin_addr_len);
+ if (NULL != plugin_name)
+ strcpy (&addrp[plugin_addr_len], plugin_name);
+ GNUNET_SERVER_notification_context_unicast (nc, ai->pc->client, &msg->header,
+ GNUNET_YES);
+}
static void
req_addr_peerinfo_it (void *cls,
struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in)
{
struct AddressIteration *ai = cls;
- struct PeerInformationMessage *msg;
- size_t plugin_name_length;
- size_t msize;
- struct GNUNET_ATS_Information *atsp;
- char *addrp;
-
GNUNET_assert (NULL != ai);
GNUNET_assert (NULL != ai->pc);
if ((NULL == id) && (NULL == id) && (NULL == id))
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Address iteration done\n");
return;
}
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Callback for peer `%s' plugin `%s' BW out %llu, BW in %llu \n",
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Callback for %s peer `%s' plugin `%s' BW out %llu, BW in %llu \n",
+ (active == GNUNET_YES) ? "ACTIVE" : "INACTIVE",
GNUNET_i2s (id),
plugin_name,
ntohl (bandwidth_out.value__),
ntohl (bandwidth_in.value__));
/* Transmit result */
-
- plugin_name_length = strlen (plugin_name) + 1;
- msize = sizeof (struct PeerInformationMessage) +
- atsi_count * sizeof (struct GNUNET_ATS_Information) +
- plugin_addr_len + plugin_name_length;
- char buf[msize] GNUNET_ALIGN;
-
- GNUNET_assert (msize < GNUNET_SERVER_MAX_MESSAGE_SIZE);
- GNUNET_assert (atsi_count <
- GNUNET_SERVER_MAX_MESSAGE_SIZE /
- sizeof (struct GNUNET_ATS_Information));
- msg = (struct PeerInformationMessage *) buf;
- msg->header.size = htons (msize);
- msg->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_ADDRESSLIST_RESPONSE);
- msg->ats_count = htonl (atsi_count);
- msg->peer = *id;
- msg->address_length = htons (plugin_addr_len);
- msg->address_active = ntohl (active);
- msg->plugin_name_length = htons (plugin_name_length);
- msg->bandwidth_out = bandwidth_out;
- msg->bandwidth_in = bandwidth_in;
- atsp = (struct GNUNET_ATS_Information *) &msg[1];
- memcpy (atsp, atsi, sizeof (struct GNUNET_ATS_Information) * atsi_count);
- addrp = (char *) &atsp[atsi_count];
- memcpy (addrp, plugin_addr, plugin_addr_len);
- strcpy (&addrp[plugin_addr_len], plugin_name);
- GNUNET_SERVER_notification_context_unicast (nc, ai->pc->client, &msg->header,
- GNUNET_YES);
+ if ((GNUNET_YES == ai->all) || (GNUNET_YES == active))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Sending result for %s peer `%s' plugin `%s' BW out %llu, BW in %llu \n",
+ (active == GNUNET_YES) ? "ACTIVE" : "INACTIVE",
+ GNUNET_i2s (id),
+ plugin_name,
+ ntohl (bandwidth_out.value__),
+ ntohl (bandwidth_in.value__));
+ transmit_req_addr (cls,
+ id,
+ plugin_name,
+ plugin_addr, plugin_addr_len,
+ active,
+ atsi,
+ atsi_count,
+ bandwidth_out, bandwidth_in);
+ }
}
struct AddressIteration *ai = cls;
if (NULL != id)
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Callback for peer `%s'\n", GNUNET_i2s (id));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Callback for peer `%s'\n", GNUNET_i2s (id));
GAS_addresses_get_peer_info (id, &req_addr_peerinfo_it, ai);
}
else
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Peer iteration done\n");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer iteration done\n");
}
}
struct AddressIteration ai;
struct AddressListRequestMessage * alrm = (struct AddressListRequestMessage *) message;
struct GNUNET_PeerIdentity allzeros;
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_zero;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n",
"ADDRESSLIST_REQUEST");
}
ai.all = ntohl (alrm->all);
+ ai.id = ntohl (alrm->id);
ai.pc = pc;
memset (&allzeros, '\0', sizeof (struct GNUNET_PeerIdentity));
+ bandwidth_zero.value__ = htonl (0);
if (0 == memcmp (&alrm->peer, &allzeros, sizeof (struct GNUNET_PeerIdentity)))
{
/* Return addresses for all peers */
GAS_addresses_iterate_peers (&req_addr_peer_it, &ai);
+ transmit_req_addr (&ai, NULL, NULL, NULL, 0, GNUNET_NO, NULL, 0, bandwidth_zero, bandwidth_zero);
}
else
{
/* Return addresses for a specific peer */
GAS_addresses_get_peer_info (&alrm->peer, &req_addr_peerinfo_it, &ai);
+ transmit_req_addr (&ai, NULL, NULL, NULL, 0, GNUNET_NO, NULL, 0, bandwidth_zero, bandwidth_zero);
}
}