glitch in the license text detected by hyazinthe, thank you!
[oweals/gnunet.git] / src / ats / gnunet-service-ats_scheduling.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2011-2016 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
16 /**
17  * @file ats/gnunet-service-ats_scheduling.c
18  * @brief ats service, interaction with 'scheduling' API
19  * @author Matthias Wachs
20  * @author Christian Grothoff
21  */
22 #include "platform.h"
23 #include "gnunet-service-ats_addresses.h"
24 #include "gnunet-service-ats_scheduling.h"
25 #include "ats.h"
26
27 /**
28  * Actual handle to the client.
29  */
30 static struct GNUNET_SERVICE_Client *my_client;
31
32
33 /**
34  * Register a new scheduling client.
35  *
36  * @param client handle of the new client
37  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
38  */
39 int
40 GAS_scheduling_add_client (struct GNUNET_SERVICE_Client *client)
41 {
42   if (NULL != my_client)
43   {
44     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
45                 "This ATS already has a scheduling client, refusing new scheduling client for now.\n");
46     return GNUNET_SYSERR;
47   }
48   my_client = client;
49   return GNUNET_OK;
50 }
51
52
53 /**
54  * Unregister a client (which may have been a scheduling client,
55  * but this is not assured).
56  *
57  * @param client handle of the (now dead) client
58  */
59 void
60 GAS_scheduling_remove_client (struct GNUNET_SERVICE_Client *client)
61 {
62   if (my_client != client)
63     return;
64   GAS_addresses_destroy_all ();
65   my_client = NULL;
66 }
67
68
69 /**
70  * Transmit the given address suggestion and bandwidth update to all scheduling
71  * clients.
72  *
73  * @param peer peer for which this is an address suggestion
74  * @param session_id session ID to use for the given client
75  * @param bandwidth_out assigned outbound bandwidth
76  * @param bandwidth_in assigned inbound bandwidth
77  */
78 void
79 GAS_scheduling_transmit_address_suggestion (const struct GNUNET_PeerIdentity *peer,
80                                             uint32_t session_id,
81                                             struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
82                                             struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in)
83 {
84   struct GNUNET_MQ_Envelope *env;
85   struct AddressSuggestionMessage *msg;
86
87   if (NULL == my_client)
88     return;
89   GNUNET_STATISTICS_update (GSA_stats,
90                             "# address suggestions made",
91                             1,
92                             GNUNET_NO);
93   env = GNUNET_MQ_msg (msg,
94                        GNUNET_MESSAGE_TYPE_ATS_ADDRESS_SUGGESTION);
95   msg->peer = *peer;
96   msg->session_id = htonl (session_id);
97   msg->bandwidth_out = bandwidth_out;
98   msg->bandwidth_in = bandwidth_in;
99   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
100               "ATS sends quota for peer `%s': (in/out) %u/%u\n",
101               GNUNET_i2s (peer),
102               (unsigned int) ntohl (bandwidth_in.value__),
103               (unsigned int) ntohl (bandwidth_out.value__));
104   GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (my_client),
105                   env);
106 }
107
108
109 /**
110  * Handle 'address add' messages from clients.
111  *
112  * @param m the request message
113  */
114 void
115 GAS_handle_address_add (const struct AddressAddMessage *m)
116 {
117   const char *address;
118   const char *plugin_name;
119   uint16_t address_length;
120   uint16_t plugin_name_length;
121   struct GNUNET_ATS_Properties prop;
122
123   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
124               "Received `%s' message\n",
125               "ADDRESS_ADD");
126   address_length = ntohs (m->address_length);
127   plugin_name_length = ntohs (m->plugin_name_length);
128   address = (const char *) &m[1];
129   if (plugin_name_length != 0)
130     plugin_name = &address[address_length];
131   else
132     plugin_name = "";
133   GNUNET_STATISTICS_update (GSA_stats,
134                             "# addresses created",
135                             1,
136                             GNUNET_NO);
137   GNUNET_ATS_properties_ntoh (&prop,
138                               &m->properties);
139   GNUNET_break (GNUNET_ATS_NET_UNSPECIFIED != prop.scope);
140   GAS_addresses_add (&m->peer,
141                      plugin_name,
142                      address,
143                      address_length,
144                      ntohl (m->address_local_info),
145                      ntohl (m->session_id),
146                      &prop);
147 }
148
149
150 /**
151  * Handle 'address update' messages from clients.
152  *
153  * @param m the request message
154  */
155 void
156 GAS_handle_address_update (const struct AddressUpdateMessage *m)
157 {
158   struct GNUNET_ATS_Properties prop;
159
160   GNUNET_STATISTICS_update (GSA_stats,
161                             "# address updates received",
162                             1,
163                             GNUNET_NO);
164   GNUNET_ATS_properties_ntoh (&prop,
165                               &m->properties);
166   GAS_addresses_update (&m->peer,
167                         ntohl (m->session_id),
168                         &prop);
169 }
170
171
172 /**
173  * Handle 'address destroyed' messages from clients.
174  *
175  * @param m the request message
176  */
177 void
178 GAS_handle_address_destroyed (const struct AddressDestroyedMessage *m)
179 {
180   struct GNUNET_MQ_Envelope *env;
181   struct GNUNET_ATS_SessionReleaseMessage *srm;
182
183   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
184               "Received `%s' message\n",
185               "ADDRESS_DESTROYED");
186   GNUNET_STATISTICS_update (GSA_stats,
187                             "# addresses destroyed",
188                             1,
189                             GNUNET_NO);
190   GAS_addresses_destroy (&m->peer,
191                          ntohl (m->session_id));
192   env = GNUNET_MQ_msg (srm,
193                        GNUNET_MESSAGE_TYPE_ATS_SESSION_RELEASE);
194   srm->session_id = m->session_id;
195   srm->peer = m->peer;
196   GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (my_client),
197                   env);
198 }
199
200
201 /* end of gnunet-service-ats_scheduling.c */