aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-10-13 14:06:14 +0000
committerChristian Grothoff <christian@grothoff.org>2011-10-13 14:06:14 +0000
commit809befdaec48b27239d930b7e6b268c60c333612 (patch)
tree2187a70652e8cd86ae062adc1768d80df4ba1182
parent577b1a0a9146bb2010427f32a1dd0ca8d16f77ad (diff)
downloadgnunet-809befdaec48b27239d930b7e6b268c60c333612.tar.gz
gnunet-809befdaec48b27239d930b7e6b268c60c333612.zip
API change to make mwachs happy
-rw-r--r--src/ats/ats.h3
-rw-r--r--src/ats/ats_api_performance.c368
-rw-r--r--src/include/gnunet_ats_service.h8
3 files changed, 365 insertions, 14 deletions
diff --git a/src/ats/ats.h b/src/ats/ats.h
index 062ceffab..2bf16b125 100644
--- a/src/ats/ats.h
+++ b/src/ats/ats.h
@@ -111,7 +111,7 @@ struct AddressSuggestionMessage
111{ 111{
112 struct GNUNET_MessageHeader header; 112 struct GNUNET_MessageHeader header;
113 113
114 uint32_t reserved GNUNET_PACKED; 114 uint32_t ats_count GNUNET_PACKED;
115 115
116 struct GNUNET_PeerIdentity peer; 116 struct GNUNET_PeerIdentity peer;
117 117
@@ -126,6 +126,7 @@ struct AddressSuggestionMessage
126 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in; 126 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in;
127 127
128 /* followed by: 128 /* followed by:
129 - struct GNUNET_TRANSPORT_ATS_Information [ats_count];
129 - char address[address_length] 130 - char address[address_length]
130 - char plugin_name[plugin_name_length] (including '\0'-termination). 131 - char plugin_name[plugin_name_length] (including '\0'-termination).
131 */ 132 */
diff --git a/src/ats/ats_api_performance.c b/src/ats/ats_api_performance.c
index e23c9bdf3..85f4ae71e 100644
--- a/src/ats/ats_api_performance.c
+++ b/src/ats/ats_api_performance.c
@@ -18,25 +18,301 @@
18 Boston, MA 02111-1307, USA. 18 Boston, MA 02111-1307, USA.
19*/ 19*/
20/** 20/**
21 * @file include/gnunet_ats_service.h 21 * @file ats/ats_api_performance.c
22 * @brief automatic transport selection and outbound bandwidth determination 22 * @brief automatic transport selection and outbound bandwidth determination
23 * @author Christian Grothoff 23 * @author Christian Grothoff
24 * @author Matthias Wachs 24 * @author Matthias Wachs
25 */ 25 */
26#include "platform.h" 26#include "platform.h"
27#include "gnunet_ats_service.h" 27#include "gnunet_ats_service.h"
28#include "ats.h"
29
30
31/**
32 * Message in linked list we should send to the ATS service. The
33 * actual binary message follows this struct.
34 */
35struct PendingMessage
36{
37
38 /**
39 * Kept in a DLL.
40 */
41 struct PendingMessage *next;
42
43 /**
44 * Kept in a DLL.
45 */
46 struct PendingMessage *prev;
47
48 /**
49 * Size of the message.
50 */
51 size_t size;
52
53 /**
54 * Is this the 'ATS_START' message?
55 */
56 int is_init;
57};
58
59
60/**
61 * Linked list of pending reservations.
62 */
63struct GNUNET_ATS_ReservationContext
64{
65
66 /**
67 * Kept in a DLL.
68 */
69 struct GNUNET_ATS_ReservationContext *next;
70
71 /**
72 * Kept in a DLL.
73 */
74 struct GNUNET_ATS_ReservationContext *prev;
75
76 /**
77 * Target peer.
78 */
79 struct GNUNET_PeerIdentity peer;
80
81 /**
82 * Desired reservation
83 */
84 int32_t size;
85
86 /**
87 * Function to call on result.
88 */
89 GNUNET_ATS_ReservationCallback info;
90
91 /**
92 * Closure for 'info'
93 */
94 void *info_cls;
95
96 /**
97 * Do we need to undo this reservation if it succeeded? Set to
98 * GNUNET_YES if a reservation is cancelled. (at that point, 'info'
99 * is also set to NULL; however, info will ALSO be NULL for the
100 * reservation context that is created to undo the original request,
101 * so 'info' being NULL cannot be used to check if undo is
102 * required).
103 */
104 int undo;
105};
28 106
29/* ******************************** Performance API ***************************** */
30 107
31/** 108/**
32 * ATS Handle to obtain and/or modify performance information. 109 * ATS Handle to obtain and/or modify performance information.
33 */ 110 */
34struct GNUNET_ATS_PerformanceHandle 111struct GNUNET_ATS_PerformanceHandle
35{ 112{
113
114 /**
115 * Our configuration.
116 */
117 const struct GNUNET_CONFIGURATION_Handle *cfg;
118
119 /**
120 * Callback to invoke on performance changes.
121 */
122 GNUNET_ATS_PeerInformationCallback infocb;
123
124 /**
125 * Closure for 'infocb'.
126 */
127 void *infocb_cls;
128
129 /**
130 * Connection to ATS service.
131 */
132 struct GNUNET_CLIENT_Connection *client;
133
134 /**
135 * Head of list of messages for the ATS service.
136 */
137 struct PendingMessage *pending_head;
138
139 /**
140 * Tail of list of messages for the ATS service
141 */
142 struct PendingMessage *pending_tail;
143
144 /**
145 * Head of linked list of pending reservation requests.
146 */
147 struct GNUNET_ATS_ReservationContext *reservation_head;
148
149 /**
150 * Tail of linked list of pending reservation requests.
151 */
152 struct GNUNET_ATS_ReservationContext *reservation_tail;
153
154 /**
155 * Current request for transmission to ATS.
156 */
157 struct GNUNET_CLIENT_TransmitHandle *th;
158
36}; 159};
37 160
38 161
39/** 162/**
163 * Re-establish the connection to the ATS service.
164 *
165 * @param sh handle to use to re-connect.
166 */
167static void
168reconnect (struct GNUNET_ATS_PerformanceHandle *ph);
169
170
171/**
172 * Transmit messages from the message queue to the service
173 * (if there are any, and if we are not already trying).
174 *
175 * @param sh handle to use
176 */
177static void
178do_transmit (struct GNUNET_ATS_PerformanceHandle *ph);
179
180
181/**
182 * We can now transmit a message to ATS. Do it.
183 *
184 * @param cls the 'struct GNUNET_ATS_SchedulingHandle'
185 * @param size number of bytes we can transmit to ATS
186 * @param buf where to copy the messages
187 * @return number of bytes copied into buf
188 */
189static size_t
190transmit_message_to_ats (void *cls,
191 size_t size,
192 void *buf)
193{
194 struct GNUNET_ATS_PerformanceHandle *ph = cls;
195 struct PendingMessage *p;
196 size_t ret;
197 char *cbuf;
198
199 ph->th = NULL;
200 ret = 0;
201 cbuf = buf;
202 while ( (NULL != (p = ph->pending_head)) &&
203 (p->size <= size) )
204 {
205 memcpy (&cbuf[ret], &p[1], p->size);
206 ret += p->size;
207 GNUNET_CONTAINER_DLL_remove (ph->pending_head,
208 ph->pending_tail,
209 p);
210 GNUNET_free (p);
211 }
212 do_transmit (ph);
213 return ret;
214}
215
216
217/**
218 * Transmit messages from the message queue to the service
219 * (if there are any, and if we are not already trying).
220 *
221 * @param ph handle to use
222 */
223static void
224do_transmit (struct GNUNET_ATS_PerformanceHandle *ph)
225{
226 struct PendingMessage *p;
227
228 if (NULL != ph->th)
229 return;
230 if (NULL == (p = ph->pending_head))
231 return;
232 ph->th = GNUNET_CLIENT_notify_transmit_ready (ph->client,
233 p->size,
234 GNUNET_TIME_UNIT_FOREVER_REL,
235 GNUNET_YES,
236 &transmit_message_to_ats, ph);
237}
238
239
240/**
241 * Type of a function to call when we receive a message
242 * from the service.
243 *
244 * @param cls the 'struct GNUNET_ATS_SchedulingHandle'
245 * @param msg message received, NULL on timeout or fatal error
246 */
247static void
248process_ats_message (void *cls,
249 const struct GNUNET_MessageHeader *msg)
250{
251 struct GNUNET_ATS_PerformanceHandle *ph = cls;
252
253 if (NULL == msg)
254 {
255 GNUNET_CLIENT_disconnect (ph->client, GNUNET_NO);
256 ph->client = NULL;
257 reconnect (ph);
258 return;
259 }
260 switch (ntohs (msg->type))
261 {
262 // FIXME
263 default:
264 GNUNET_break (0);
265 GNUNET_CLIENT_disconnect (ph->client, GNUNET_NO);
266 ph->client = NULL;
267 reconnect (ph);
268 return;
269 }
270 GNUNET_CLIENT_receive (ph->client,
271 &process_ats_message, ph,
272 GNUNET_TIME_UNIT_FOREVER_REL);
273}
274
275
276/**
277 * Re-establish the connection to the ATS service.
278 *
279 * @param ph handle to use to re-connect.
280 */
281static void
282reconnect (struct GNUNET_ATS_PerformanceHandle *ph)
283{
284 struct PendingMessage *p;
285 struct ClientStartMessage *init;
286
287 GNUNET_assert (NULL == ph->client);
288 ph->client = GNUNET_CLIENT_connect ("ats", ph->cfg);
289 GNUNET_assert (NULL != ph->client);
290 GNUNET_CLIENT_receive (ph->client,
291 &process_ats_message, ph,
292 GNUNET_TIME_UNIT_FOREVER_REL);
293 if ( (NULL == (p = ph->pending_head)) ||
294 (GNUNET_YES != p->is_init) )
295 {
296 p = GNUNET_malloc (sizeof (struct PendingMessage) +
297 sizeof (struct ClientStartMessage));
298 p->size = sizeof (struct ClientStartMessage);
299 p->is_init = GNUNET_YES;
300 init = (struct ClientStartMessage *) &p[1];
301 init->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_START);
302 init->header.size = htons (sizeof (struct ClientStartMessage));
303 init->start_flag = htonl ((ph->infocb == NULL)
304 ? START_FLAG_PERFORMANCE_NO_PIC
305 : START_FLAG_PERFORMANCE_WITH_PIC);
306 GNUNET_CONTAINER_DLL_insert (ph->pending_head,
307 ph->pending_tail,
308 p);
309 }
310 do_transmit (ph);
311}
312
313
314
315/**
40 * Get handle to access performance API of the ATS subsystem. 316 * Get handle to access performance API of the ATS subsystem.
41 * 317 *
42 * @param cfg configuration to use 318 * @param cfg configuration to use
@@ -49,7 +325,14 @@ GNUNET_ATS_performance_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
49 GNUNET_ATS_PeerInformationCallback infocb, 325 GNUNET_ATS_PeerInformationCallback infocb,
50 void *infocb_cls) 326 void *infocb_cls)
51{ 327{
52 return NULL; 328 struct GNUNET_ATS_PerformanceHandle *ph;
329
330 ph = GNUNET_malloc (sizeof (struct GNUNET_ATS_PerformanceHandle));
331 ph->cfg = cfg;
332 ph->infocb = infocb;
333 ph->infocb_cls = infocb_cls;
334 reconnect (ph);
335 return ph;
53} 336}
54 337
55 338
@@ -61,18 +344,30 @@ GNUNET_ATS_performance_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
61void 344void
62GNUNET_ATS_performance_done (struct GNUNET_ATS_SchedulingHandle *ph) 345GNUNET_ATS_performance_done (struct GNUNET_ATS_SchedulingHandle *ph)
63{ 346{
347 struct PendingMessage *p;
348 struct GNUNET_ATS_ReservationContext *rc;
349
350 while (NULL != (p = ph->pending_head))
351 {
352 GNUNET_CONTAINER_DLL_remove (ph->pending_head,
353 ph->pending_tail,
354 p);
355 GNUNET_free (p);
356 }
357 while (NULL != (rc = ph->reservation_head))
358 {
359 GNUNET_CONTAINER_DLL_remove (ph->reservation_head,
360 ph->reservation_tail,
361 rc);
362 GNUNET_break (NULL == rc->info);
363 GNUNET_free (p);
364 }
365 GNUNET_CLIENT_disconnect (ph->client, GNUNET_NO);
366 GNUNET_free (ph);
64} 367}
65 368
66 369
67/** 370/**
68 * Context that can be used to cancel a peer information request.
69 */
70struct GNUNET_ATS_ReservationContext
71{
72};
73
74
75/**
76 * Reserve inbound bandwidth from the given peer. ATS will look at 371 * Reserve inbound bandwidth from the given peer. ATS will look at
77 * the current amount of traffic we receive from the peer and ensure 372 * the current amount of traffic we receive from the peer and ensure
78 * that the peer could add 'amount' of data to its stream. 373 * that the peer could add 'amount' of data to its stream.
@@ -93,7 +388,32 @@ GNUNET_ATS_reserve_bandwidth (struct GNUNET_ATS_PerformanceHandle *ph,
93 GNUNET_ATS_ReservationCallback info, 388 GNUNET_ATS_ReservationCallback info,
94 void *info_cls) 389 void *info_cls)
95{ 390{
96 return NULL; 391 struct GNUNET_ATS_ReservationContext *rc;
392 struct PendingMessage *p;
393 struct ReservationRequestMessage *m;
394
395 rc = GNUNET_malloc (sizeof (struct GNUNET_ATS_ReservationContext));
396 rc->size = amount;
397 rc->peer = *peer;
398 rc->info = info;
399 rc->info_cls = info_cls;
400 GNUNET_CONTAINER_DLL_insert_tail (ph->reservation_head,
401 ph->reservation_tail,
402 rc);
403
404 p = GNUNET_malloc (sizeof (struct PendingMessage) +
405 sizeof (struct ReservationRequestMessage));
406 p->size = sizeof (struct ReservationRequestMessage);
407 p->is_init = GNUNET_NO;
408 m = (struct ReservationRequestMessage*) &p[1];
409 m->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_ADDRESS_UPDATE);
410 m->header.size = htons (sizeof (struct ReservationRequestMessage));
411 m->amount = htonl (amount);
412 m->peer = *peer;
413 GNUNET_CONTAINER_DLL_insert_tail (ph->pending_head,
414 ph->pending_tail,
415 p);
416 return rc;
97} 417}
98 418
99 419
@@ -106,6 +426,7 @@ void
106GNUNET_ATS_reserve_bandwidth_cancel (struct 426GNUNET_ATS_reserve_bandwidth_cancel (struct
107 GNUNET_ATS_ReservationContext *rc) 427 GNUNET_ATS_ReservationContext *rc)
108{ 428{
429 rc->info = NULL;
109} 430}
110 431
111 432
@@ -122,6 +443,29 @@ GNUNET_ATS_change_preference (struct GNUNET_ATS_PerformanceHandle *ph,
122 const struct GNUNET_PeerIdentity *peer, 443 const struct GNUNET_PeerIdentity *peer,
123 ...) 444 ...)
124{ 445{
446 struct PendingMessage *p;
447 struct ChangePreferenceMessage *m;
448 size_t msize;
449 uint32_t count;
450 struct PreferenceInformation *pi;
451
452 // FIXME: set 'count'
453 p = GNUNET_malloc (sizeof (struct PendingMessage) +
454 sizeof (struct ChangePreferenceMessage) +
455 count * sizeof (struct PreferenceInformation));
456 p->size = msize;
457 p->is_init = GNUNET_NO;
458 m = (struct ReservationRequestMessage*) &p[1];
459 m->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_ADDRESS_UPDATE);
460 m->header.size = htons (msize);
461 m->num_preferences = htonl (count);
462 m->peer = *peer;
463 pi = (struct PreferenceInformation*) &m[1];
464 // FIXME: fill in 'pi'
465
466 GNUNET_CONTAINER_DLL_insert_tail (ph->pending_head,
467 ph->pending_tail,
468 p);
125} 469}
126 470
127/* end of ats_api_performance.c */ 471/* end of ats_api_performance.c */
diff --git a/src/include/gnunet_ats_service.h b/src/include/gnunet_ats_service.h
index afbb5d6c6..79be70ce4 100644
--- a/src/include/gnunet_ats_service.h
+++ b/src/include/gnunet_ats_service.h
@@ -61,6 +61,8 @@ struct Session;
61 * @param session session to use 61 * @param session session to use
62 * @param bandwidth_out assigned outbound bandwidth for the connection 62 * @param bandwidth_out assigned outbound bandwidth for the connection
63 * @param bandwidth_in assigned inbound bandwidth for the connection 63 * @param bandwidth_in assigned inbound bandwidth for the connection
64 * @param ats performance data for the address (as far as known)
65 * @param ats_count number of performance records in 'ats'
64 */ 66 */
65typedef void (*GNUNET_ATS_AddressSuggestionCallback) (void *cls, 67typedef void (*GNUNET_ATS_AddressSuggestionCallback) (void *cls,
66 const struct 68 const struct
@@ -75,7 +77,11 @@ typedef void (*GNUNET_ATS_AddressSuggestionCallback) (void *cls,
75 bandwidth_out, 77 bandwidth_out,
76 struct 78 struct
77 GNUNET_BANDWIDTH_Value32NBO 79 GNUNET_BANDWIDTH_Value32NBO
78 bandwidth_in); 80 bandwidth_in,
81 const struct
82 GNUNET_TRANSPORT_ATS_Information
83 * ats,
84 uint32_t ats_count);
79 85
80 86
81/** 87/**