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 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.
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.
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/>.
19 * @file ats/gnunet-service-ats.c
21 * @author Matthias Wachs
22 * @author Christian Grothoff
25 #include "gnunet_util_lib.h"
26 #include "gnunet-service-ats.h"
27 #include "gnunet-service-ats_addresses.h"
28 #include "gnunet-service-ats_connectivity.h"
29 #include "gnunet-service-ats_normalization.h"
30 #include "gnunet-service-ats_performance.h"
31 #include "gnunet-service-ats_preferences.h"
32 #include "gnunet-service-ats_scheduling.h"
33 #include "gnunet-service-ats_reservations.h"
34 #include "gnunet-service-ats_plugins.h"
38 * Handle for statistics.
40 struct GNUNET_STATISTICS_Handle *GSA_stats;
44 * We have received a `struct ClientStartMessage` from a client. Find
45 * out which type of client it is and notify the respective subsystem.
47 * @param cls handle to the client
48 * @param msg the start message
51 handle_ats_start (void *cls,
52 const struct ClientStartMessage *msg)
54 struct GNUNET_SERVICE_Client *client = cls;
57 flag = ntohl (msg->start_flag);
58 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
59 "Received ATS_START (%d) message\n",
63 case START_FLAG_SCHEDULING:
65 GAS_scheduling_add_client (client))
67 GNUNET_SERVICE_client_drop (client);
71 case START_FLAG_PERFORMANCE_WITH_PIC:
72 GAS_performance_add_client (client,
75 case START_FLAG_PERFORMANCE_NO_PIC:
76 GAS_performance_add_client (client,
79 case START_FLAG_CONNECTION_SUGGESTION:
80 /* This client won't receive messages from us, no need to 'add' */
84 GNUNET_SERVICE_client_drop (client);
87 GNUNET_SERVICE_client_continue (client);
93 * Handle 'reservation request' messages from clients.
95 * @param cls client that sent the request
96 * @param message the request message
99 handle_reservation_request (void *cls,
100 const struct ReservationRequestMessage *message)
102 struct GNUNET_SERVICE_Client *client = cls;
104 GAS_handle_reservation_request (client,
106 GNUNET_SERVICE_client_continue (client);
111 * Check 'preference feedback' message is well-formed
113 * @param cls client that sent the request
114 * @param message the request message
115 * @return #GNUNET_OK if @a message is well-formed
118 check_feedback (void *cls,
119 const struct FeedbackPreferenceMessage *message)
124 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
125 "Received PREFERENCE_FEEDBACK message\n");
126 msize = ntohs (message->header.size);
127 nump = ntohl (message->num_feedback);
129 sizeof (struct FeedbackPreferenceMessage) +
130 nump * sizeof (struct PreferenceInformation))
133 return GNUNET_SYSERR;
140 * Handle 'preference feedback' messages from clients.
142 * @param cls client that sent the request
143 * @param msg the request message
146 handle_feedback (void *cls,
147 const struct FeedbackPreferenceMessage *msg)
149 struct GNUNET_SERVICE_Client *client = cls;
150 const struct PreferenceInformation *pi;
153 nump = ntohl (msg->num_feedback);
155 GNUNET_CONTAINER_multipeermap_contains (GSA_addresses,
158 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
159 "Received PREFERENCE FEEDBACK for unknown peer `%s'\n",
160 GNUNET_i2s (&msg->peer));
161 GNUNET_SERVICE_client_continue (client);
165 GNUNET_STATISTICS_update (GSA_stats,
166 "# preference feedbacks requests processed",
169 pi = (const struct PreferenceInformation *) &msg[1];
170 for (uint32_t i = 0; i < nump; i++)
172 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
173 "Received PREFERENCE FEEDBACK for peer `%s'\n",
174 GNUNET_i2s (&msg->peer));
175 GAS_plugin_notify_feedback (client,
177 GNUNET_TIME_relative_ntoh (msg->scope),
178 (enum GNUNET_ATS_PreferenceKind) ntohl (pi[i].preference_kind),
179 pi[i].preference_value);
181 GNUNET_SERVICE_client_continue (client);
186 * Handle 'request address list' messages from clients.
188 * @param cls client that sent the request
189 * @param message the request message
192 handle_request_address_list (void *cls,
193 const struct AddressListRequestMessage *message)
195 struct GNUNET_SERVICE_Client *client = cls;
197 GAS_handle_request_address_list (client,
199 GNUNET_SERVICE_client_continue (client);
204 * Handle 'request address' messages from clients.
206 * @param cls client that sent the request
207 * @param message the request message
210 handle_request_address (void *cls,
211 const struct RequestAddressMessage * message)
213 struct GNUNET_SERVICE_Client *client = cls;
215 GAS_handle_request_address (client,
217 GNUNET_SERVICE_client_continue (client);
222 * Cancel 'request address' messages from clients.
224 * @param cls client that sent the request
225 * @param message the request message
228 handle_request_address_cancel (void *cls,
229 const struct RequestAddressMessage *message)
231 struct GNUNET_SERVICE_Client *client = cls;
233 GAS_handle_request_address_cancel (client,
235 GNUNET_SERVICE_client_continue (client);
240 * Handle 'address add' messages from clients.
242 * @param cls client that sent the request
243 * @param m the request message
246 check_address_add (void *cls,
247 const struct AddressAddMessage *m)
250 const char *plugin_name;
251 uint16_t address_length;
252 uint16_t plugin_name_length;
255 size = ntohs (m->header.size);
256 address_length = ntohs (m->address_length);
257 plugin_name_length = ntohs (m->plugin_name_length);
258 address = (const char *) &m[1];
259 if (plugin_name_length != 0)
260 plugin_name = &address[address_length];
264 if ( (address_length + plugin_name_length +
265 sizeof (struct AddressAddMessage) != size) ||
266 ( (plugin_name_length > 0) &&
267 (plugin_name[plugin_name_length - 1] != '\0') ) )
270 return GNUNET_SYSERR;
277 * Handle 'address add' messages from clients.
279 * @param cls client that sent the request
280 * @param message the request message
283 handle_address_add (void *cls,
284 const struct AddressAddMessage *message)
286 struct GNUNET_SERVICE_Client *client = cls;
288 GAS_handle_address_add (message);
289 GNUNET_SERVICE_client_continue (client);
294 * Handle 'address update' messages from clients.
296 * @param cls client that sent the request
297 * @param message the request message
300 handle_address_update (void *cls,
301 const struct AddressUpdateMessage *message)
303 struct GNUNET_SERVICE_Client *client = cls;
305 GAS_handle_address_update (message);
306 GNUNET_SERVICE_client_continue (client);
311 * Handle 'address destroyed' messages from clients.
313 * @param cls client that sent the request
314 * @param message the request message
317 handle_address_destroyed (void *cls,
318 const struct AddressDestroyedMessage *message)
320 struct GNUNET_SERVICE_Client *client = cls;
322 GAS_handle_address_destroyed (message);
323 GNUNET_SERVICE_client_continue (client);
328 * Check that 'change preference' message is well-formed.
330 * @param cls client that sent the request
331 * @param message the request message
332 * @return #GNUNET_OK if @a message is well-formed
335 check_preference_change (void *cls,
336 const struct ChangePreferenceMessage *message)
341 msize = ntohs (message->header.size);
342 nump = ntohl (message->num_preferences);
344 sizeof (struct ChangePreferenceMessage) +
345 nump * sizeof (struct PreferenceInformation)) ||
346 (UINT16_MAX / sizeof (struct PreferenceInformation) < nump) )
349 return GNUNET_SYSERR;
356 * Handle 'change preference' messages from clients.
358 * @param cls client that sent the request
359 * @param message the request message
362 handle_preference_change (void *cls,
363 const struct ChangePreferenceMessage *message)
365 struct GNUNET_SERVICE_Client *client = cls;
367 GAS_handle_preference_change (client,
369 GNUNET_SERVICE_client_continue (client);
374 * A client connected to us. Setup the local client
378 * @param client handle of the client
379 * @param mq message queue to talk to @a client
383 client_connect_cb (void *cls,
384 struct GNUNET_SERVICE_Client *client,
385 struct GNUNET_MQ_Handle *mq)
392 * A client disconnected from us. Tear down the local client
396 * @param client handle of the client
400 client_disconnect_cb (void *cls,
401 struct GNUNET_SERVICE_Client *client,
406 GAS_scheduling_remove_client (client);
407 GAS_connectivity_remove_client (client);
408 GAS_preference_client_disconnect (client);
413 * Task run during shutdown.
418 cleanup_task (void *cls)
420 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
421 "ATS shutdown initiated\n");
422 GAS_connectivity_done ();
423 GAS_addresses_done ();
425 GAS_normalization_stop ();
426 GAS_performance_done ();
427 GAS_preference_done ();
428 GAS_reservations_done ();
429 if (NULL != GSA_stats)
431 GNUNET_STATISTICS_destroy (GSA_stats, GNUNET_NO);
438 * Process template requests.
441 * @param cfg configuration to use
442 * @param service the initialized service
446 const struct GNUNET_CONFIGURATION_Handle *cfg,
447 struct GNUNET_SERVICE_Handle *service)
449 GSA_stats = GNUNET_STATISTICS_create ("ats",
451 GAS_reservations_init ();
452 GAS_connectivity_init ();
453 GAS_preference_init ();
454 GAS_normalization_start ();
455 GAS_addresses_init ();
457 GAS_plugin_init (cfg))
460 GAS_addresses_done ();
461 GAS_normalization_stop ();
462 GAS_reservations_done ();
463 GAS_connectivity_done ();
464 GAS_preference_done ();
465 if (NULL != GSA_stats)
467 GNUNET_STATISTICS_destroy (GSA_stats,
473 GAS_performance_init ();
474 GNUNET_SCHEDULER_add_shutdown (&cleanup_task,
480 * Define "main" method using service macro.
484 GNUNET_SERVICE_OPTION_NONE,
487 &client_disconnect_cb,
489 GNUNET_MQ_hd_fixed_size (ats_start,
490 GNUNET_MESSAGE_TYPE_ATS_START,
491 struct ClientStartMessage,
493 GNUNET_MQ_hd_fixed_size (request_address,
494 GNUNET_MESSAGE_TYPE_ATS_REQUEST_ADDRESS,
495 struct RequestAddressMessage,
497 GNUNET_MQ_hd_fixed_size (request_address_cancel,
498 GNUNET_MESSAGE_TYPE_ATS_REQUEST_ADDRESS_CANCEL,
499 struct RequestAddressMessage,
501 GNUNET_MQ_hd_fixed_size (request_address_list,
502 GNUNET_MESSAGE_TYPE_ATS_ADDRESSLIST_REQUEST,
503 struct AddressListRequestMessage,
505 GNUNET_MQ_hd_var_size (address_add,
506 GNUNET_MESSAGE_TYPE_ATS_ADDRESS_ADD,
507 struct AddressAddMessage,
509 GNUNET_MQ_hd_fixed_size (address_update,
510 GNUNET_MESSAGE_TYPE_ATS_ADDRESS_UPDATE,
511 struct AddressUpdateMessage,
513 GNUNET_MQ_hd_fixed_size (address_destroyed,
514 GNUNET_MESSAGE_TYPE_ATS_ADDRESS_DESTROYED,
515 struct AddressDestroyedMessage,
517 GNUNET_MQ_hd_fixed_size (reservation_request,
518 GNUNET_MESSAGE_TYPE_ATS_RESERVATION_REQUEST,
519 struct ReservationRequestMessage,
521 GNUNET_MQ_hd_var_size (preference_change,
522 GNUNET_MESSAGE_TYPE_ATS_PREFERENCE_CHANGE,
523 struct ChangePreferenceMessage,
525 GNUNET_MQ_hd_var_size (feedback,
526 GNUNET_MESSAGE_TYPE_ATS_PREFERENCE_FEEDBACK,
527 struct FeedbackPreferenceMessage,
529 GNUNET_MQ_handler_end ());
532 /* end of gnunet-service-ats.c */