X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fats%2Fgnunet-service-ats_performance.c;h=3249ed42ad4cc37e991813315d84127ff9064273;hb=71896114a4f9c2bd7eb1c3f67cc7ba23d6522152;hp=7800ea46e2379d255cef9c2236edb7f0abb36ea1;hpb=3b014d6c7e60670d60286ffaef041cd26a7af542;p=oweals%2Fgnunet.git diff --git a/src/ats/gnunet-service-ats_performance.c b/src/ats/gnunet-service-ats_performance.c index 7800ea46e..3249ed42a 100644 --- a/src/ats/gnunet-service-ats_performance.c +++ b/src/ats/gnunet-service-ats_performance.c @@ -60,6 +60,24 @@ struct PerformanceClient }; +/** + * We keep clients that are interested in performance in a linked list. + */ +struct AddressIteration +{ + /** + * Actual handle to the client. + */ + struct PerformanceClient *pc; + + int all; + + uint32_t id; + + unsigned int msg_type; +}; + + /** * Head of linked list of all clients to this service. */ @@ -120,6 +138,7 @@ GAS_performance_remove_client (struct GNUNET_SERVER_Client *client) * @param plugin_name 0-termintated string specifying the transport plugin * @param plugin_addr binary address for the plugin to use * @param plugin_addr_len number of bytes in plugin_addr + * @param active is this address active * @param atsi performance data for the address * @param atsi_count number of performance records in 'ats' * @param bandwidth_out assigned outbound bandwidth @@ -130,6 +149,7 @@ GAS_performance_notify_client (struct PerformanceClient *pc, const struct GNUNET_PeerIdentity *peer, 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 @@ -158,9 +178,11 @@ GAS_performance_notify_client (struct PerformanceClient *pc, msg = (struct PeerInformationMessage *) buf; msg->header.size = htons (msize); msg->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_PEER_INFORMATION); + msg->id = htonl (0); msg->ats_count = htonl (atsi_count); msg->peer = *peer; 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; @@ -182,6 +204,7 @@ GAS_performance_notify_client (struct PerformanceClient *pc, * @param plugin_name 0-termintated string specifying the transport plugin * @param plugin_addr binary address for the plugin to use * @param plugin_addr_len number of bytes in plugin_addr + * @param active is this address active * @param atsi performance data for the address * @param atsi_count number of performance records in 'ats' * @param bandwidth_out assigned outbound bandwidth @@ -191,6 +214,7 @@ void GAS_performance_notify_all_clients (const struct GNUNET_PeerIdentity *peer, 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 @@ -205,10 +229,10 @@ GAS_performance_notify_all_clients (const struct GNUNET_PeerIdentity *peer, GAS_performance_notify_client (pc, peer, plugin_name, plugin_addr, plugin_addr_len, + active, atsi, atsi_count, bandwidth_out, bandwidth_in); } - GNUNET_STATISTICS_update (GSA_stats, "# performance updates given to clients", 1, GNUNET_NO); @@ -220,6 +244,7 @@ peerinfo_it (void *cls, 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 @@ -230,6 +255,10 @@ peerinfo_it (void *cls, GNUNET_assert (NULL != pc); if (NULL == id) return; + + if (GNUNET_NO == active) + return; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Callback for peer `%s' plugin `%s' BW out %llu, BW in %llu \n", GNUNET_i2s (id), @@ -239,6 +268,7 @@ peerinfo_it (void *cls, GAS_performance_notify_client(pc, id, plugin_name, plugin_addr, plugin_addr_len, + active, atsi, atsi_count, bandwidth_out, bandwidth_in); } @@ -273,8 +303,8 @@ GAS_performance_add_client (struct GNUNET_SERVER_Client *client, enum StartFlag flag) { struct PerformanceClient *pc; - GNUNET_break (NULL == find_client (client)); + pc = GNUNET_malloc (sizeof (struct PerformanceClient)); pc->client = client; pc->flag = flag; @@ -286,6 +316,140 @@ 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_NO); +} + +static void +req_addr_peerinfo_it (void *cls, + 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 AddressIteration *ai = cls; + + GNUNET_assert (NULL != ai); + GNUNET_assert (NULL != ai->pc); + if (NULL == find_client (ai->pc->client)) + return; /* Client disconnected */ + + if ((NULL == id) && (NULL == id) && (NULL == id)) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Address iteration done\n"); + return; + } + 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 */ + 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); + } +} + + +/** + * Iterator for GAS_handle_request_address_list + * + * @param cls the client requesting information + * @param id result + */ +static void +req_addr_peer_it (void *cls, + const struct GNUNET_PeerIdentity *id) +{ + struct AddressIteration *ai = cls; + if (NULL != 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_DEBUG, "Peer iteration done\n"); + } +} + /** * Handle 'address list request' messages from clients. * @@ -298,8 +462,10 @@ GAS_handle_request_address_list (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { struct PerformanceClient *pc; - struct AddressListRequestMessage * alrm = cls; + 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"); @@ -310,19 +476,25 @@ GAS_handle_request_address_list (void *cls, struct GNUNET_SERVER_Client *client, return; } + 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 (&peer_it, pc); + 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, &peerinfo_it, pc); + 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); } - - + GNUNET_SERVER_receive_done (client, GNUNET_OK); }