GNUnet  0.10.x
gnunet-service-ats.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2011 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19 */
26 #include "platform.h"
27 #include "gnunet_util_lib.h"
28 #include "gnunet-service-ats.h"
37 #include "ats.h"
38 
43 
44 
52 static void
53 handle_ats_start (void *cls,
54  const struct ClientStartMessage *msg)
55 {
56  struct GNUNET_SERVICE_Client *client = cls;
57  enum StartFlag flag;
58 
59  flag = ntohl (msg->start_flag);
61  "Received ATS_START (%d) message\n",
62  (int) flag);
63  switch (flag)
64  {
66  if (GNUNET_OK !=
68  {
70  return;
71  }
72  break;
75  flag);
76  break;
79  flag);
80  break;
82  /* This client won't receive messages from us, no need to 'add' */
83  break;
84  default:
85  GNUNET_break (0);
87  return;
88  }
90 }
91 
92 
93 
100 static void
102  const struct ReservationRequestMessage *message)
103 {
104  struct GNUNET_SERVICE_Client *client = cls;
105 
107  message);
109 }
110 
111 
119 static int
120 check_feedback (void *cls,
121  const struct FeedbackPreferenceMessage *message)
122 {
123  uint16_t msize;
124  uint32_t nump;
125 
127  "Received PREFERENCE_FEEDBACK message\n");
128  msize = ntohs (message->header.size);
129  nump = ntohl (message->num_feedback);
130  if (msize !=
131  sizeof (struct FeedbackPreferenceMessage) +
132  nump * sizeof (struct PreferenceInformation))
133  {
134  GNUNET_break (0);
135  return GNUNET_SYSERR;
136  }
137  return GNUNET_OK;
138 }
139 
140 
147 static void
148 handle_feedback (void *cls,
149  const struct FeedbackPreferenceMessage *msg)
150 {
151  struct GNUNET_SERVICE_Client *client = cls;
152  const struct PreferenceInformation *pi;
153  uint32_t nump;
154 
155  nump = ntohl (msg->num_feedback);
156  if (GNUNET_NO ==
158  &msg->peer))
159  {
161  "Received PREFERENCE FEEDBACK for unknown peer `%s'\n",
162  GNUNET_i2s (&msg->peer));
164  return;
165  }
166 
167  GNUNET_STATISTICS_update (GSA_stats,
168  "# preference feedbacks requests processed",
169  1,
170  GNUNET_NO);
171  pi = (const struct PreferenceInformation *) &msg[1];
172  for (uint32_t i = 0; i < nump; i++)
173  {
175  "Received PREFERENCE FEEDBACK for peer `%s'\n",
176  GNUNET_i2s (&msg->peer));
178  &msg->peer,
180  (enum GNUNET_ATS_PreferenceKind) ntohl (pi[i].preference_kind),
181  pi[i].preference_value);
182  }
184 }
185 
186 
193 static void
195  const struct AddressListRequestMessage *message)
196 {
197  struct GNUNET_SERVICE_Client *client = cls;
198 
200  message);
202 }
203 
204 
211 static void
213  const struct RequestAddressMessage * message)
214 {
215  struct GNUNET_SERVICE_Client *client = cls;
216 
218  message);
220 }
221 
222 
229 static void
231  const struct RequestAddressMessage *message)
232 {
233  struct GNUNET_SERVICE_Client *client = cls;
234 
236  message);
238 }
239 
240 
247 static int
248 check_address_add (void *cls,
249  const struct AddressAddMessage *m)
250 {
251  const char *address;
252  const char *plugin_name;
253  uint16_t address_length;
254  uint16_t plugin_name_length;
255  uint16_t size;
256 
257  size = ntohs (m->header.size);
258  address_length = ntohs (m->address_length);
259  plugin_name_length = ntohs (m->plugin_name_length);
260  address = (const char *) &m[1];
261  if (plugin_name_length != 0)
262  plugin_name = &address[address_length];
263  else
264  plugin_name = "";
265 
266  if ( (address_length + plugin_name_length +
267  sizeof (struct AddressAddMessage) != size) ||
268  ( (plugin_name_length > 0) &&
269  (plugin_name[plugin_name_length - 1] != '\0') ) )
270  {
271  GNUNET_break (0);
272  return GNUNET_SYSERR;
273  }
274  return GNUNET_OK;
275 }
276 
277 
284 static void
286  const struct AddressAddMessage *message)
287 {
288  struct GNUNET_SERVICE_Client *client = cls;
289 
290  GAS_handle_address_add (message);
292 }
293 
294 
301 static void
303  const struct AddressUpdateMessage *message)
304 {
305  struct GNUNET_SERVICE_Client *client = cls;
306 
307  GAS_handle_address_update (message);
309 }
310 
311 
318 static void
320  const struct AddressDestroyedMessage *message)
321 {
322  struct GNUNET_SERVICE_Client *client = cls;
323 
326 }
327 
328 
336 static int
338  const struct ChangePreferenceMessage *message)
339 {
340  uint16_t msize;
341  uint32_t nump;
342 
343  msize = ntohs (message->header.size);
344  nump = ntohl (message->num_preferences);
345  if ( (msize !=
346  sizeof (struct ChangePreferenceMessage) +
347  nump * sizeof (struct PreferenceInformation)) ||
348  (UINT16_MAX / sizeof (struct PreferenceInformation) < nump) )
349  {
350  GNUNET_break (0);
351  return GNUNET_SYSERR;
352  }
353  return GNUNET_OK;
354 }
355 
356 
363 static void
365  const struct ChangePreferenceMessage *message)
366 {
367  struct GNUNET_SERVICE_Client *client = cls;
368 
370  message);
372 }
373 
374 
384 static void *
385 client_connect_cb (void *cls,
386  struct GNUNET_SERVICE_Client *client,
387  struct GNUNET_MQ_Handle *mq)
388 {
389  return client;
390 }
391 
392 
401 static void
403  struct GNUNET_SERVICE_Client *client,
404  void *app_ctx)
405 {
406  if (NULL == client)
407  return;
411 }
412 
413 
419 static void
420 cleanup_task (void *cls)
421 {
423  "ATS shutdown initiated\n");
426  GAS_plugin_done ();
431  if (NULL != GSA_stats)
432  {
434  GSA_stats = NULL;
435  }
436 }
437 
438 
446 static void
447 run (void *cls,
448  const struct GNUNET_CONFIGURATION_Handle *cfg,
450 {
451  GSA_stats = GNUNET_STATISTICS_create ("ats",
452  cfg);
458  if (GNUNET_OK !=
459  GAS_plugin_init (cfg))
460  {
461  GNUNET_break (0);
467  if (NULL != GSA_stats)
468  {
469  GNUNET_STATISTICS_destroy (GSA_stats,
470  GNUNET_NO);
471  GSA_stats = NULL;
472  }
473  return;
474  }
477  NULL);
478 }
479 
480 
485 ("ats",
487  &run,
490  NULL,
491  GNUNET_MQ_hd_fixed_size (ats_start,
493  struct ClientStartMessage,
494  NULL),
495  GNUNET_MQ_hd_fixed_size (request_address,
497  struct RequestAddressMessage,
498  NULL),
499  GNUNET_MQ_hd_fixed_size (request_address_cancel,
501  struct RequestAddressMessage,
502  NULL),
503  GNUNET_MQ_hd_fixed_size (request_address_list,
506  NULL),
507  GNUNET_MQ_hd_var_size (address_add,
509  struct AddressAddMessage,
510  NULL),
511  GNUNET_MQ_hd_fixed_size (address_update,
513  struct AddressUpdateMessage,
514  NULL),
515  GNUNET_MQ_hd_fixed_size (address_destroyed,
518  NULL),
519  GNUNET_MQ_hd_fixed_size (reservation_request,
522  NULL),
523  GNUNET_MQ_hd_var_size (preference_change,
526  NULL),
527  GNUNET_MQ_hd_var_size (feedback,
530  NULL),
532 
533 
534 /* end of gnunet-service-ats.c */
#define GNUNET_MESSAGE_TYPE_ATS_ADDRESS_DESTROYED
Type of the &#39;struct AddressDestroyedMessage&#39; sent by clients to ATS to inform ATS about an address be...
Connectivity client to ATS service: we would like to have address suggestions for this peer...
Definition: ats.h:88
void GAS_normalization_stop()
Stop the normalization component and free all items.
void GAS_handle_reservation_request(struct GNUNET_SERVICE_Client *client, const struct ReservationRequestMessage *msg)
Handle &#39;reservation request&#39; messages from clients.
uint16_t address_length
Number of bytes in the address that follows this struct.
Definition: ats.h:122
void GAS_handle_address_destroyed(const struct AddressDestroyedMessage *m)
Handle &#39;address destroyed&#39; messages from clients.
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
#define GNUNET_MESSAGE_TYPE_ATS_START
Type of the &#39;struct ClientStartMessage&#39; sent by clients to ATS to identify the type of the client...
static int check_preference_change(void *cls, const struct ChangePreferenceMessage *message)
Check that &#39;change preference&#39; message is well-formed.
static void handle_reservation_request(void *cls, const struct ReservationRequestMessage *message)
Handle &#39;reservation request&#39; messages from clients.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
void GAS_handle_address_update(const struct AddressUpdateMessage *m)
Handle &#39;address update&#39; messages from clients.
Handle to a service.
Definition: service.c:116
uint32_t start_flag
NBO value of an enum StartFlag.
Definition: ats.h:80
StartFlag
Flag used to indicate which type of client is connecting to the ATS service.
Definition: ats.h:37
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1293
void GAS_reservations_done()
Shutdown reservations subsystem.
void GAS_plugin_notify_feedback(struct GNUNET_SERVICE_Client *application, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_TIME_Relative scope, enum GNUNET_ATS_PreferenceKind kind, float score_abs)
Tell the solver that the given client has expressed its appreciation for the past performance of a gi...
void GAS_preference_init()
Initialize preferences subsystem.
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
void GAS_connectivity_remove_client(struct GNUNET_SERVICE_Client *client)
Unregister a client (which may have been a connectivity client, but this is not assured).
static void handle_request_address(void *cls, const struct RequestAddressMessage *message)
Handle &#39;request address&#39; messages from clients.
uint32_t preference_kind
An enum GNUNET_ATS_PreferenceKind in NBO.
Definition: ats.h:433
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
ats service address: management of ATS properties and preferences normalization
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_ATS_PREFERENCE_CHANGE.
Definition: ats.h:452
ats service plugin management
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
Performance monitoring client that does NOT want to learn about changes in performance characteristic...
Definition: ats.h:55
static void handle_request_address_list(void *cls, const struct AddressListRequestMessage *message)
Handle &#39;request address list&#39; messages from clients.
static void client_disconnect_cb(void *cls, struct GNUNET_SERVICE_Client *client, void *app_ctx)
A client disconnected from us.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
static struct GNUNET_PEERINFO_Handle * pi
Handle to peerinfo service.
static void handle_feedback(void *cls, const struct FeedbackPreferenceMessage *msg)
Handle &#39;preference feedback&#39; messages from clients.
Handle for the service.
uint32_t num_feedback
Number of feedback values included.
Definition: ats.h:483
void GAS_connectivity_init()
Shutdown connectivity subsystem.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define GNUNET_MESSAGE_TYPE_ATS_ADDRESSLIST_REQUEST
Type of the &#39;struct AddressListRequestMessage&#39; sent by client to ATS to request information about add...
void GAS_reservations_init()
Initialize reservations subsystem.
static void run(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_SERVICE_Handle *service)
Process template requests.
static void handle_address_add(void *cls, const struct AddressAddMessage *message)
Handle &#39;address add&#39; messages from clients.
ats service, interaction with &#39;performance&#39; API
void GAS_preference_client_disconnect(struct GNUNET_SERVICE_Client *client)
A performance client disconnected.
Message used to notify ATS that the performance characteristics for an address have changed...
Definition: ats.h:163
static int check_address_add(void *cls, const struct AddressAddMessage *m)
Handle &#39;address add&#39; messages from clients.
Handle to a client that is connected to a service.
Definition: service.c:249
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition: gnunet-arm.c:99
ats service, inbound bandwidth reservation management
This is a scheduling client (aka transport service)
Definition: ats.h:43
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
int GAS_scheduling_add_client(struct GNUNET_SERVICE_Client *client)
Register a new scheduling client.
int GAS_plugin_init(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize plugins subsystem.
void GAS_scheduling_remove_client(struct GNUNET_SERVICE_Client *client)
Unregister a client (which may have been a scheduling client, but this is not assured).
static void handle_preference_change(void *cls, const struct ChangePreferenceMessage *message)
Handle &#39;change preference&#39; messages from clients.
void GAS_performance_add_client(struct GNUNET_SERVICE_Client *client, enum StartFlag flag)
Register a new performance client.
#define GNUNET_MESSAGE_TYPE_ATS_REQUEST_ADDRESS_CANCEL
Type of the &#39;struct RequestAddressMessage&#39; sent by clients to ATS to request an address to help conne...
GNUNET_SERVICE_MAIN("ats", GNUNET_SERVICE_OPTION_NONE, &run, &client_connect_cb, &client_disconnect_cb, NULL, GNUNET_MQ_hd_fixed_size(ats_start, GNUNET_MESSAGE_TYPE_ATS_START, struct ClientStartMessage, NULL), GNUNET_MQ_hd_fixed_size(request_address, GNUNET_MESSAGE_TYPE_ATS_REQUEST_ADDRESS, struct RequestAddressMessage, NULL), GNUNET_MQ_hd_fixed_size(request_address_cancel, GNUNET_MESSAGE_TYPE_ATS_REQUEST_ADDRESS_CANCEL, struct RequestAddressMessage, NULL), GNUNET_MQ_hd_fixed_size(request_address_list, GNUNET_MESSAGE_TYPE_ATS_ADDRESSLIST_REQUEST, struct AddressListRequestMessage, NULL), GNUNET_MQ_hd_var_size(address_add, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_ADD, struct AddressAddMessage, NULL), GNUNET_MQ_hd_fixed_size(address_update, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_UPDATE, struct AddressUpdateMessage, NULL), GNUNET_MQ_hd_fixed_size(address_destroyed, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_DESTROYED, struct AddressDestroyedMessage, NULL), GNUNET_MQ_hd_fixed_size(reservation_request, GNUNET_MESSAGE_TYPE_ATS_RESERVATION_REQUEST, struct ReservationRequestMessage, NULL), GNUNET_MQ_hd_var_size(preference_change, GNUNET_MESSAGE_TYPE_ATS_PREFERENCE_CHANGE, struct ChangePreferenceMessage, NULL), GNUNET_MQ_hd_var_size(feedback, GNUNET_MESSAGE_TYPE_ATS_PREFERENCE_FEEDBACK, struct FeedbackPreferenceMessage, NULL), GNUNET_MQ_handler_end())
Define "main" method using service macro.
static void handle_request_address_cancel(void *cls, const struct RequestAddressMessage *message)
Cancel &#39;request address&#39; messages from clients.
static char * plugin_name
Solver plugin name as string.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_ntoh(struct GNUNET_TIME_RelativeNBO a)
Convert relative time from network byte order.
Definition: time.c:638
struct GNUNET_PeerIdentity peer
Peer this feedback is for.
Definition: ats.h:493
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2618
void GAS_preference_done()
Shutdown preferences subsystem.
uint16_t plugin_name_length
Number of bytes in the plugin name that follows this struct.
Definition: ats.h:127
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:104
static void * client_connect_cb(void *cls, struct GNUNET_SERVICE_Client *client, struct GNUNET_MQ_Handle *mq)
A client connected to us.
static void handle_ats_start(void *cls, const struct ClientStartMessage *msg)
We have received a struct ClientStartMessage from a client.
void GAS_performance_init()
Initialize performance subsystem.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
static unsigned int size
Size of the "table".
Definition: peer.c:67
Client to service: please give us an overview of the addresses.
Definition: ats.h:348
uint32_t num_preferences
How many struct PreferenceInformation entries follow this struct?
Definition: ats.h:458
#define GNUNET_MESSAGE_TYPE_ATS_PREFERENCE_FEEDBACK
Type of the &#39;struct ChangePreferenceMessage&#39; sent by clients to ATS to ask for allocation preference ...
void GAS_plugin_done()
Shutdown address subsystem.
Connection suggestion handle.
Definition: ats.h:60
struct GNUNET_CONTAINER_MultiPeerMap * GSA_addresses
A multihashmap to store all addresses.
ats service, interaction with &#39;connecivity&#39; API
static void cleanup_task(void *cls)
Task run during shutdown.
manage preferences expressed by clients
ats service address management
void GAS_connectivity_done()
Shutdown connectivity subsystem.
static void handle_address_update(void *cls, const struct AddressUpdateMessage *message)
Handle &#39;address update&#39; messages from clients.
Handle to a message queue.
Definition: mq.c:85
void GAS_handle_preference_change(struct GNUNET_SERVICE_Client *client, const struct ChangePreferenceMessage *msg)
Handle &#39;preference change&#39; messages from clients.
void GAS_handle_address_add(const struct AddressAddMessage *m)
Handle &#39;address add&#39; messages from clients.
void GAS_handle_request_address(struct GNUNET_SERVICE_Client *client, const struct RequestAddressMessage *msg)
Handle GNUNET_MESSAGE_TYPE_ATS_REQUEST_ADDRESS messages from clients.
void GAS_handle_request_address_cancel(struct GNUNET_SERVICE_Client *client, const struct RequestAddressMessage *msg)
Handle GNUNET_MESSAGE_TYPE_ATS_REQUEST_ADDRESS_CANCEL messages from clients.
Message containing application feedback for a peer.
Definition: ats.h:473
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_ATS_ADDRESS_ADD.
Definition: ats.h:117
#define GNUNET_MESSAGE_TYPE_ATS_REQUEST_ADDRESS
Type of the &#39;struct RequestAddressMessage&#39; sent by clients to ATS to request an address to help conne...
struct GNUNET_TIME_RelativeNBO scope
Relative time describing for which time interval this feedback is.
Definition: ats.h:488
struct GNUNET_STATISTICS_Handle * GSA_stats
Handle for statistics.
configuration data
Definition: configuration.c:85
void GAS_normalization_start()
Start the normalization component.
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
#define GNUNET_log(kind,...)
Variable-size entry in a struct ChangePreferenceMessage or struct FeedbackPreferenceMessage.
Definition: ats.h:427
Client to ATS: I have a performance preference for a peer.
Definition: ats.h:447
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_ATS_PREFERENCE_FEEDBACK.
Definition: ats.h:478
static void handle_address_destroyed(void *cls, const struct AddressDestroyedMessage *message)
Handle &#39;address destroyed&#39; messages from clients.
#define GNUNET_MESSAGE_TYPE_ATS_RESERVATION_REQUEST
Type of the &#39;struct ReservationRequestMessage&#39; sent by clients to ATS to ask for inbound bandwidth re...
void GAS_performance_done()
Shutdown performance subsystem.
void GAS_addresses_init()
Initialize address subsystem.
static int check_feedback(void *cls, const struct FeedbackPreferenceMessage *message)
Check &#39;preference feedback&#39; message is well-formed.
ats service, interaction with &#39;scheduling&#39; API
void GAS_addresses_done()
Shutdown address subsystem.
#define GNUNET_MESSAGE_TYPE_ATS_ADDRESS_ADD
Type of the &#39;struct AddressUpdateMessage&#39; sent by client to ATS to add a new address.
Message sent by ATS client to ATS service when an address was destroyed and must thus henceforth no l...
Definition: ats.h:195
GNUNET_ATS_PreferenceKind
Enum defining all known preference categories.
float preference_value
Degree of preference (or appreciation) for this preference_kind being expressed.
Definition: ats.h:439
int GNUNET_CONTAINER_multipeermap_contains(const struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key)
Check if the map contains any value under the given key (including values that are NULL)...
static char * address
GNS address for this phone.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2533
#define GNUNET_MESSAGE_TYPE_ATS_PREFERENCE_CHANGE
Type of the &#39;struct ChangePreferenceMessage&#39; sent by clients to ATS to ask for allocation preference ...
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
automatic transport selection messages
#define GNUNET_MESSAGE_TYPE_ATS_ADDRESS_UPDATE
Type of the &#39;struct AddressUpdateMessage&#39; sent by clients to ATS to inform ATS about performance chan...
First message any client sends to ATS, used to self-identify (what type of client this is)...
Definition: ats.h:70
Performance monitoring client that wants to learn about changes in performance characteristics.
Definition: ats.h:49
void GAS_handle_request_address_list(struct GNUNET_SERVICE_Client *client, const struct AddressListRequestMessage *alrm)
Handle &#39;address list request&#39; messages from clients.
Scheduling client to ATS service: here is another address you can use.
Definition: ats.h:112