gnunet-service-ats_performance.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. /*
  2. This file is part of GNUnet.
  3. Copyright (C) 2011-2015 GNUnet e.V.
  4. GNUnet is free software: you can redistribute it and/or modify it
  5. under the terms of the GNU Affero General Public License as published
  6. by the Free Software Foundation, either version 3 of the License,
  7. or (at your option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Affero General Public License for more details.
  12. You should have received a copy of the GNU Affero General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. SPDX-License-Identifier: AGPL3.0-or-later
  15. */
  16. /**
  17. * @file ats/gnunet-service-ats_performance.c
  18. * @brief ats service, interaction with 'performance' API
  19. * @author Matthias Wachs
  20. * @author Christian Grothoff
  21. *
  22. * TODO:
  23. * - simplify functions by passing a `struct GNUNET_HELLO_Address`
  24. */
  25. #include "platform.h"
  26. #include "gnunet-service-ats.h"
  27. #include "gnunet-service-ats_addresses.h"
  28. #include "gnunet-service-ats_performance.h"
  29. #include "ats.h"
  30. /**
  31. * Context for sending messages to performance clients without PIC.
  32. */
  33. static struct GNUNET_NotificationContext *nc_no_pic;
  34. /**
  35. * Context for sending messages to performance clients with PIC.
  36. */
  37. static struct GNUNET_NotificationContext *nc_pic;
  38. /**
  39. * Transmit the given performance information to all performance
  40. * clients.
  41. *
  42. * @param client client to send to, NULL for all
  43. * @param peer peer for which this is an address suggestion
  44. * @param plugin_name 0-termintated string specifying the transport plugin
  45. * @param plugin_addr binary address for the plugin to use
  46. * @param plugin_addr_len number of bytes in plugin_addr
  47. * @param active #GNUNET_YES if this address is actively used
  48. * to maintain a connection to a peer;
  49. * #GNUNET_NO if the address is not actively used;
  50. * #GNUNET_SYSERR if this address is no longer available for ATS
  51. * @param prop performance data for the address
  52. * @param local_address_info information about the local flags for the address
  53. * @param bandwidth_out assigned outbound bandwidth
  54. * @param bandwidth_in assigned inbound bandwidth
  55. */
  56. static void
  57. notify_client (struct GNUNET_SERVICE_Client *client,
  58. const struct GNUNET_PeerIdentity *peer,
  59. const char *plugin_name,
  60. const void *plugin_addr,
  61. size_t plugin_addr_len,
  62. int active,
  63. const struct GNUNET_ATS_Properties *prop,
  64. enum GNUNET_HELLO_AddressInfo local_address_info,
  65. struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
  66. struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in)
  67. {
  68. struct PeerInformationMessage *msg;
  69. size_t plugin_name_length = strlen (plugin_name) + 1;
  70. size_t msize =
  71. sizeof (struct PeerInformationMessage) +
  72. plugin_addr_len +
  73. plugin_name_length;
  74. char buf[msize] GNUNET_ALIGN;
  75. char *addrp;
  76. if (NULL != prop)
  77. GNUNET_break (GNUNET_NT_UNSPECIFIED != prop->scope);
  78. GNUNET_assert (msize < GNUNET_MAX_MESSAGE_SIZE);
  79. msg = (struct PeerInformationMessage *) buf;
  80. msg->header.size = htons (msize);
  81. msg->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_PEER_INFORMATION);
  82. msg->id = htonl (0);
  83. msg->peer = *peer;
  84. msg->address_length = htons (plugin_addr_len);
  85. msg->address_active = ntohl ((uint32_t) active);
  86. msg->plugin_name_length = htons (plugin_name_length);
  87. msg->bandwidth_out = bandwidth_out;
  88. msg->bandwidth_in = bandwidth_in;
  89. if (NULL != prop)
  90. GNUNET_ATS_properties_hton (&msg->properties,
  91. prop);
  92. else
  93. memset (&msg->properties,
  94. 0,
  95. sizeof (struct GNUNET_ATS_Properties));
  96. msg->address_local_info = htonl (local_address_info);
  97. addrp = (char *) &msg[1];
  98. GNUNET_memcpy (addrp, plugin_addr, plugin_addr_len);
  99. strcpy (&addrp[plugin_addr_len], plugin_name);
  100. if (NULL == client)
  101. {
  102. GNUNET_notification_context_broadcast (nc_pic,
  103. &msg->header,
  104. GNUNET_YES);
  105. }
  106. else
  107. {
  108. struct GNUNET_MQ_Envelope *env;
  109. env = GNUNET_MQ_msg_copy (&msg->header);
  110. GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
  111. env);
  112. }
  113. }
  114. /**
  115. * Transmit the given performance information to all performance
  116. * clients.
  117. *
  118. * @param peer peer for which this is an address suggestion
  119. * @param plugin_name 0-termintated string specifying the transport plugin
  120. * @param plugin_addr binary address for the plugin to use
  121. * @param plugin_addr_len number of bytes in @a plugin_addr
  122. * @param active #GNUNET_YES if this address is actively used
  123. * to maintain a connection to a peer;
  124. * #GNUNET_NO if the address is not actively used;
  125. * #GNUNET_SYSERR if this address is no longer available for ATS
  126. * @param prop performance data for the address
  127. * @param local_address_info information about the local flags for the address
  128. * @param bandwidth_out assigned outbound bandwidth
  129. * @param bandwidth_in assigned inbound bandwidth
  130. */
  131. void
  132. GAS_performance_notify_all_clients (const struct GNUNET_PeerIdentity *peer,
  133. const char *plugin_name,
  134. const void *plugin_addr,
  135. size_t plugin_addr_len,
  136. int active,
  137. const struct GNUNET_ATS_Properties *prop,
  138. enum GNUNET_HELLO_AddressInfo local_address_info,
  139. struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
  140. struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in)
  141. {
  142. GNUNET_break ( (NULL == prop) ||
  143. (GNUNET_NT_UNSPECIFIED != prop->scope) );
  144. notify_client (NULL,
  145. peer,
  146. plugin_name,
  147. plugin_addr,
  148. plugin_addr_len,
  149. active,
  150. prop,
  151. local_address_info,
  152. bandwidth_out,
  153. bandwidth_in);
  154. GNUNET_STATISTICS_update (GSA_stats,
  155. "# performance updates given to clients",
  156. 1,
  157. GNUNET_NO);
  158. }
  159. /**
  160. * Iterator for called from #GAS_addresses_get_peer_info()
  161. *
  162. * @param cls closure with the `struct GNUNET_SERVICE_Client *` to inform.
  163. * @param id the peer id
  164. * @param plugin_name plugin name
  165. * @param plugin_addr address
  166. * @param plugin_addr_len length of @a plugin_addr
  167. * @param active is address actively used
  168. * @param prop performance information
  169. * @param local_address_info information about the local flags for the address
  170. * @param bandwidth_out current outbound bandwidth assigned to address
  171. * @param bandwidth_in current inbound bandwidth assigned to address
  172. */
  173. static void
  174. peerinfo_it (void *cls,
  175. const struct GNUNET_PeerIdentity *id,
  176. const char *plugin_name,
  177. const void *plugin_addr,
  178. size_t plugin_addr_len,
  179. int active,
  180. const struct GNUNET_ATS_Properties *prop,
  181. enum GNUNET_HELLO_AddressInfo local_address_info,
  182. struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
  183. struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in)
  184. {
  185. struct GNUNET_SERVICE_Client *client = cls;
  186. if (NULL == id)
  187. return;
  188. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  189. "Callback for peer `%s' plugin `%s' BW out %u, BW in %u \n",
  190. GNUNET_i2s (id),
  191. plugin_name,
  192. (unsigned int) ntohl (bandwidth_out.value__),
  193. (unsigned int) ntohl (bandwidth_in.value__));
  194. GNUNET_break (GNUNET_NT_UNSPECIFIED != prop->scope);
  195. notify_client (client,
  196. id,
  197. plugin_name,
  198. plugin_addr,
  199. plugin_addr_len,
  200. active,
  201. prop,
  202. local_address_info,
  203. bandwidth_out,
  204. bandwidth_in);
  205. }
  206. /**
  207. * Register a new performance client.
  208. *
  209. * @param client handle of the new client
  210. * @param flag flag specifying the type of the client
  211. */
  212. void
  213. GAS_performance_add_client (struct GNUNET_SERVICE_Client *client,
  214. enum StartFlag flag)
  215. {
  216. struct GNUNET_MQ_Handle *mq;
  217. mq = GNUNET_SERVICE_client_get_mq (client);
  218. if (START_FLAG_PERFORMANCE_WITH_PIC == flag)
  219. {
  220. GNUNET_notification_context_add (nc_pic,
  221. mq);
  222. GAS_addresses_get_peer_info (NULL,
  223. &peerinfo_it,
  224. client);
  225. }
  226. else
  227. {
  228. GNUNET_notification_context_add (nc_no_pic,
  229. mq);
  230. }
  231. }
  232. /**
  233. * Initialize performance subsystem.
  234. *
  235. * @param server handle to our server
  236. */
  237. void
  238. GAS_performance_init ()
  239. {
  240. nc_no_pic = GNUNET_notification_context_create (32);
  241. nc_pic = GNUNET_notification_context_create (32);
  242. }
  243. /**
  244. * Shutdown performance subsystem.
  245. */
  246. void
  247. GAS_performance_done ()
  248. {
  249. GNUNET_notification_context_destroy (nc_no_pic);
  250. nc_no_pic = NULL;
  251. GNUNET_notification_context_destroy (nc_pic);
  252. nc_pic = NULL;
  253. }
  254. /* end of gnunet-service-ats_performance.c */