From: Matthias Wachs Date: Tue, 20 Nov 2012 14:30:14 +0000 (+0000) Subject: - changes X-Git-Tag: initial-import-from-subversion-38251~10752 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=184c653a98dd3674d2607f72b9db9f13dcdeae8b;p=oweals%2Fgnunet.git - changes --- diff --git a/src/ats-tool/gnunet-ats.c b/src/ats-tool/gnunet-ats.c index 27dfd4dca..2219363d5 100644 --- a/src/ats-tool/gnunet-ats.c +++ b/src/ats-tool/gnunet-ats.c @@ -36,6 +36,8 @@ static int ret; static int results; static int resolve_addresses_numeric; +static int receive_done; + /** * For which peer should we change preference values? */ @@ -43,6 +45,7 @@ static char *pid_str; static char *type_str; static unsigned int value; +static int pending; /** * Print verbose ATS information @@ -97,6 +100,44 @@ struct PendingResolutions 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; @@ -108,58 +149,65 @@ void transport_addr_to_str_cb (void *cls, const char *address) 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, @@ -195,44 +243,23 @@ 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) { @@ -292,9 +319,7 @@ void testservice_ats (void *cls, 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) { @@ -311,8 +336,6 @@ void testservice_ats (void *cls, 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) @@ -388,6 +411,8 @@ main (int argc, char *const *argv) 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, diff --git a/src/ats/ats.h b/src/ats/ats.h index 009a1609d..70b88263d 100644 --- a/src/ats/ats.h +++ b/src/ats/ats.h @@ -172,6 +172,8 @@ struct PeerInformationMessage uint32_t address_active GNUNET_PACKED; + uint32_t id GNUNET_PACKED; + struct GNUNET_PeerIdentity peer; uint16_t address_length GNUNET_PACKED; @@ -194,6 +196,8 @@ struct AddressListRequestMessage { struct GNUNET_MessageHeader header; + uint32_t id GNUNET_PACKED; + int32_t all GNUNET_PACKED; struct GNUNET_PeerIdentity peer; diff --git a/src/ats/ats_api_performance.c b/src/ats/ats_api_performance.c index c4254cf90..855e983b5 100644 --- a/src/ats/ats_api_performance.c +++ b/src/ats/ats_api_performance.c @@ -150,6 +150,11 @@ struct GNUNET_ATS_AddressListHandle * Return all or used address only */ int all_addresses; + + /** + * Request multiplexing + */ + uint32_t id; }; /** @@ -218,6 +223,10 @@ struct GNUNET_ATS_PerformanceHandle */ GNUNET_SCHEDULER_TaskIdentifier task; + /** + * Request multiplexing + */ + uint32_t id; }; @@ -338,6 +347,7 @@ process_pi_message (struct GNUNET_ATS_PerformanceHandle *ph, GNUNET_break (0); return GNUNET_SYSERR; } + pi = (const struct PeerInformationMessage *) msg; ats_count = ntohl (pi->ats_count); plugin_address_length = ntohs (pi->address_length); @@ -359,6 +369,7 @@ process_pi_message (struct GNUNET_ATS_PerformanceHandle *ph, { return GNUNET_OK; } + address.peer = pi->peer; address.address = plugin_address; address.address_length = plugin_address_length; @@ -430,45 +441,89 @@ static int 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; } @@ -577,6 +632,7 @@ GNUNET_ATS_performance_init (const struct GNUNET_CONFIGURATION_Handle *cfg, ph->cfg = cfg; ph->infocb = infocb; ph->infocb_cls = infocb_cls; + ph->id = 0; reconnect (ph); return ph; } @@ -712,6 +768,8 @@ GNUNET_ATS_performance_list_addresses (struct GNUNET_ATS_PerformanceHandle *hand 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; @@ -733,6 +791,7 @@ GNUNET_ATS_performance_list_addresses (struct GNUNET_ATS_PerformanceHandle *hand 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 diff --git a/src/ats/gnunet-service-ats_performance.c b/src/ats/gnunet-service-ats_performance.c index 124654b25..446024b32 100644 --- a/src/ats/gnunet-service-ats_performance.c +++ b/src/ats/gnunet-service-ats_performance.c @@ -72,6 +72,8 @@ struct AddressIteration int all; + uint32_t id; + unsigned int msg_type; }; @@ -311,7 +313,62 @@ GAS_performance_add_client (struct GNUNET_SERVER_Client *client, 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, @@ -326,12 +383,6 @@ 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); @@ -340,46 +391,37 @@ req_addr_peerinfo_it (void *cls, 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); + } } @@ -396,12 +438,12 @@ req_addr_peer_it (void *cls, 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"); } } @@ -420,6 +462,7 @@ GAS_handle_request_address_list (void *cls, struct GNUNET_SERVER_Client *client, 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"); @@ -431,18 +474,22 @@ GAS_handle_request_address_list (void *cls, struct GNUNET_SERVER_Client *client, } 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); } }