2 This file is part of GNUnet.
3 Copyright (C) 2011 GNUnet e.V.
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
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 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
21 * @file ats/gnunet-service-ats.c
23 * @author Matthias Wachs
24 * @author Christian Grothoff
27 #include "gnunet_util_lib.h"
28 #include "gnunet-service-ats.h"
29 #include "gnunet-service-ats_addresses.h"
30 #include "gnunet-service-ats_connectivity.h"
31 #include "gnunet-service-ats_normalization.h"
32 #include "gnunet-service-ats_performance.h"
33 #include "gnunet-service-ats_preferences.h"
34 #include "gnunet-service-ats_scheduling.h"
35 #include "gnunet-service-ats_reservations.h"
36 #include "gnunet-service-ats_plugins.h"
40 * Handle for statistics.
42 struct GNUNET_STATISTICS_Handle *GSA_stats;
46 * We have received a `struct ClientStartMessage` from a client. Find
47 * out which type of client it is and notify the respective subsystem.
49 * @param cls handle to the client
50 * @param msg the start message
53 handle_ats_start (void *cls,
54 const struct ClientStartMessage *msg)
56 struct GNUNET_SERVICE_Client *client = cls;
59 flag = ntohl (msg->start_flag);
60 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
61 "Received ATS_START (%d) message\n",
65 case START_FLAG_SCHEDULING:
67 GAS_scheduling_add_client (client))
69 GNUNET_SERVICE_client_drop (client);
73 case START_FLAG_PERFORMANCE_WITH_PIC:
74 GAS_performance_add_client (client,
77 case START_FLAG_PERFORMANCE_NO_PIC:
78 GAS_performance_add_client (client,
81 case START_FLAG_CONNECTION_SUGGESTION:
82 /* This client won't receive messages from us, no need to 'add' */
86 GNUNET_SERVICE_client_drop (client);
89 GNUNET_SERVICE_client_continue (client);
95 * Handle 'reservation request' messages from clients.
97 * @param cls client that sent the request
98 * @param message the request message
101 handle_reservation_request (void *cls,
102 const struct ReservationRequestMessage *message)
104 struct GNUNET_SERVICE_Client *client = cls;
106 GAS_handle_reservation_request (client,
108 GNUNET_SERVICE_client_continue (client);
113 * Check 'preference feedback' message is well-formed
115 * @param cls client that sent the request
116 * @param message the request message
117 * @return #GNUNET_OK if @a message is well-formed
120 check_feedback (void *cls,
121 const struct FeedbackPreferenceMessage *message)
126 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
127 "Received PREFERENCE_FEEDBACK message\n");
128 msize = ntohs (message->header.size);
129 nump = ntohl (message->num_feedback);
131 sizeof (struct FeedbackPreferenceMessage) +
132 nump * sizeof (struct PreferenceInformation))
135 return GNUNET_SYSERR;
142 * Handle 'preference feedback' messages from clients.
144 * @param cls client that sent the request
145 * @param msg the request message
148 handle_feedback (void *cls,
149 const struct FeedbackPreferenceMessage *msg)
151 struct GNUNET_SERVICE_Client *client = cls;
152 const struct PreferenceInformation *pi;
155 nump = ntohl (msg->num_feedback);
157 GNUNET_CONTAINER_multipeermap_contains (GSA_addresses,
160 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
161 "Received PREFERENCE FEEDBACK for unknown peer `%s'\n",
162 GNUNET_i2s (&msg->peer));
163 GNUNET_SERVICE_client_continue (client);
167 GNUNET_STATISTICS_update (GSA_stats,
168 "# preference feedbacks requests processed",
171 pi = (const struct PreferenceInformation *) &msg[1];
172 for (uint32_t i = 0; i < nump; i++)
174 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
175 "Received PREFERENCE FEEDBACK for peer `%s'\n",
176 GNUNET_i2s (&msg->peer));
177 GAS_plugin_notify_feedback (client,
179 GNUNET_TIME_relative_ntoh (msg->scope),
180 (enum GNUNET_ATS_PreferenceKind) ntohl (pi[i].preference_kind),
181 pi[i].preference_value);
183 GNUNET_SERVICE_client_continue (client);
188 * Handle 'request address list' messages from clients.
190 * @param cls client that sent the request
191 * @param message the request message
194 handle_request_address_list (void *cls,
195 const struct AddressListRequestMessage *message)
197 struct GNUNET_SERVICE_Client *client = cls;
199 GAS_handle_request_address_list (client,
201 GNUNET_SERVICE_client_continue (client);
206 * Handle 'request address' messages from clients.
208 * @param cls client that sent the request
209 * @param message the request message
212 handle_request_address (void *cls,
213 const struct RequestAddressMessage * message)
215 struct GNUNET_SERVICE_Client *client = cls;
217 GAS_handle_request_address (client,
219 GNUNET_SERVICE_client_continue (client);
224 * Cancel 'request address' messages from clients.
226 * @param cls client that sent the request
227 * @param message the request message
230 handle_request_address_cancel (void *cls,
231 const struct RequestAddressMessage *message)
233 struct GNUNET_SERVICE_Client *client = cls;
235 GAS_handle_request_address_cancel (client,
237 GNUNET_SERVICE_client_continue (client);
242 * Handle 'address add' messages from clients.
244 * @param cls client that sent the request
245 * @param m the request message
248 check_address_add (void *cls,
249 const struct AddressAddMessage *m)
252 const char *plugin_name;
253 uint16_t address_length;
254 uint16_t plugin_name_length;
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];
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') ) )
272 return GNUNET_SYSERR;
279 * Handle 'address add' messages from clients.
281 * @param cls client that sent the request
282 * @param message the request message
285 handle_address_add (void *cls,
286 const struct AddressAddMessage *message)
288 struct GNUNET_SERVICE_Client *client = cls;
290 GAS_handle_address_add (message);
291 GNUNET_SERVICE_client_continue (client);
296 * Handle 'address update' messages from clients.
298 * @param cls client that sent the request
299 * @param message the request message
302 handle_address_update (void *cls,
303 const struct AddressUpdateMessage *message)
305 struct GNUNET_SERVICE_Client *client = cls;
307 GAS_handle_address_update (message);
308 GNUNET_SERVICE_client_continue (client);
313 * Handle 'address destroyed' messages from clients.
315 * @param cls client that sent the request
316 * @param message the request message
319 handle_address_destroyed (void *cls,
320 const struct AddressDestroyedMessage *message)
322 struct GNUNET_SERVICE_Client *client = cls;
324 GAS_handle_address_destroyed (message);
325 GNUNET_SERVICE_client_continue (client);
330 * Check that 'change preference' message is well-formed.
332 * @param cls client that sent the request
333 * @param message the request message
334 * @return #GNUNET_OK if @a message is well-formed
337 check_preference_change (void *cls,
338 const struct ChangePreferenceMessage *message)
343 msize = ntohs (message->header.size);
344 nump = ntohl (message->num_preferences);
346 sizeof (struct ChangePreferenceMessage) +
347 nump * sizeof (struct PreferenceInformation)) ||
348 (UINT16_MAX / sizeof (struct PreferenceInformation) < nump) )
351 return GNUNET_SYSERR;
358 * Handle 'change preference' messages from clients.
360 * @param cls client that sent the request
361 * @param message the request message
364 handle_preference_change (void *cls,
365 const struct ChangePreferenceMessage *message)
367 struct GNUNET_SERVICE_Client *client = cls;
369 GAS_handle_preference_change (client,
371 GNUNET_SERVICE_client_continue (client);
376 * A client connected to us. Setup the local client
380 * @param client handle of the client
381 * @param mq message queue to talk to @a client
385 client_connect_cb (void *cls,
386 struct GNUNET_SERVICE_Client *client,
387 struct GNUNET_MQ_Handle *mq)
394 * A client disconnected from us. Tear down the local client
398 * @param client handle of the client
402 client_disconnect_cb (void *cls,
403 struct GNUNET_SERVICE_Client *client,
408 GAS_scheduling_remove_client (client);
409 GAS_connectivity_remove_client (client);
410 GAS_preference_client_disconnect (client);
415 * Task run during shutdown.
420 cleanup_task (void *cls)
422 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
423 "ATS shutdown initiated\n");
424 GAS_connectivity_done ();
425 GAS_addresses_done ();
427 GAS_normalization_stop ();
428 GAS_performance_done ();
429 GAS_preference_done ();
430 GAS_reservations_done ();
431 if (NULL != GSA_stats)
433 GNUNET_STATISTICS_destroy (GSA_stats, GNUNET_NO);
440 * Process template requests.
443 * @param cfg configuration to use
444 * @param service the initialized service
448 const struct GNUNET_CONFIGURATION_Handle *cfg,
449 struct GNUNET_SERVICE_Handle *service)
451 GSA_stats = GNUNET_STATISTICS_create ("ats",
453 GAS_reservations_init ();
454 GAS_connectivity_init ();
455 GAS_preference_init ();
456 GAS_normalization_start ();
457 GAS_addresses_init ();
459 GAS_plugin_init (cfg))
462 GAS_addresses_done ();
463 GAS_normalization_stop ();
464 GAS_reservations_done ();
465 GAS_connectivity_done ();
466 GAS_preference_done ();
467 if (NULL != GSA_stats)
469 GNUNET_STATISTICS_destroy (GSA_stats,
475 GAS_performance_init ();
476 GNUNET_SCHEDULER_add_shutdown (&cleanup_task,
482 * Define "main" method using service macro.
486 GNUNET_SERVICE_OPTION_NONE,
489 &client_disconnect_cb,
491 GNUNET_MQ_hd_fixed_size (ats_start,
492 GNUNET_MESSAGE_TYPE_ATS_START,
493 struct ClientStartMessage,
495 GNUNET_MQ_hd_fixed_size (request_address,
496 GNUNET_MESSAGE_TYPE_ATS_REQUEST_ADDRESS,
497 struct RequestAddressMessage,
499 GNUNET_MQ_hd_fixed_size (request_address_cancel,
500 GNUNET_MESSAGE_TYPE_ATS_REQUEST_ADDRESS_CANCEL,
501 struct RequestAddressMessage,
503 GNUNET_MQ_hd_fixed_size (request_address_list,
504 GNUNET_MESSAGE_TYPE_ATS_ADDRESSLIST_REQUEST,
505 struct AddressListRequestMessage,
507 GNUNET_MQ_hd_var_size (address_add,
508 GNUNET_MESSAGE_TYPE_ATS_ADDRESS_ADD,
509 struct AddressAddMessage,
511 GNUNET_MQ_hd_fixed_size (address_update,
512 GNUNET_MESSAGE_TYPE_ATS_ADDRESS_UPDATE,
513 struct AddressUpdateMessage,
515 GNUNET_MQ_hd_fixed_size (address_destroyed,
516 GNUNET_MESSAGE_TYPE_ATS_ADDRESS_DESTROYED,
517 struct AddressDestroyedMessage,
519 GNUNET_MQ_hd_fixed_size (reservation_request,
520 GNUNET_MESSAGE_TYPE_ATS_RESERVATION_REQUEST,
521 struct ReservationRequestMessage,
523 GNUNET_MQ_hd_var_size (preference_change,
524 GNUNET_MESSAGE_TYPE_ATS_PREFERENCE_CHANGE,
525 struct ChangePreferenceMessage,
527 GNUNET_MQ_hd_var_size (feedback,
528 GNUNET_MESSAGE_TYPE_ATS_PREFERENCE_FEEDBACK,
529 struct FeedbackPreferenceMessage,
531 GNUNET_MQ_handler_end ());
534 /* end of gnunet-service-ats.c */