aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-10-13 14:49:55 +0000
committerChristian Grothoff <christian@grothoff.org>2011-10-13 14:49:55 +0000
commite2c076da0b595591c5646916cf2b629404489709 (patch)
treeec49ddd4b767526c1e1c7f2ba8dfc7922c0fdf99
parent2f983f47bd3c923b7cea0839eba90c1bb77554e0 (diff)
downloadgnunet-e2c076da0b595591c5646916cf2b629404489709.tar.gz
gnunet-e2c076da0b595591c5646916cf2b629404489709.zip
finish ATS API implementation
-rw-r--r--src/ats/ats_api_performance.c160
-rw-r--r--src/ats/ats_api_scheduling.c8
-rw-r--r--src/include/gnunet_ats_service.h10
3 files changed, 158 insertions, 20 deletions
diff --git a/src/ats/ats_api_performance.c b/src/ats/ats_api_performance.c
index cf948da48..fd733911d 100644
--- a/src/ats/ats_api_performance.c
+++ b/src/ats/ats_api_performance.c
@@ -86,12 +86,12 @@ struct GNUNET_ATS_ReservationContext
86 /** 86 /**
87 * Function to call on result. 87 * Function to call on result.
88 */ 88 */
89 GNUNET_ATS_ReservationCallback info; 89 GNUNET_ATS_ReservationCallback rcb;
90 90
91 /** 91 /**
92 * Closure for 'info' 92 * Closure for 'rcb'
93 */ 93 */
94 void *info_cls; 94 void *rcb_cls;
95 95
96 /** 96 /**
97 * Do we need to undo this reservation if it succeeded? Set to 97 * Do we need to undo this reservation if it succeeded? Set to
@@ -238,6 +238,123 @@ do_transmit (struct GNUNET_ATS_PerformanceHandle *ph)
238 238
239 239
240/** 240/**
241 * We received a peer information message. Validate and process it.
242 *
243 * @param ph our context with the callback
244 * @param msg the message
245 * @return GNUNET_OK if the message was well-formed
246 */
247static int
248process_pi_message (struct GNUNET_ATS_PerformanceHandle *ph,
249 const struct GNUNET_MessageHeader *msg)
250{
251 const struct PeerInformationMessage *pi;
252 const struct GNUNET_TRANSPORT_ATS_Information *atsi;
253 const char *address;
254 const char *plugin_name;
255 uint16_t address_length;
256 uint16_t plugin_name_length;
257 uint32_t ats_count;
258
259 if (ph->infocb == NULL)
260 {
261 GNUNET_break (0);
262 return GNUNET_SYSERR;
263 }
264 if (ntohs (msg->size) < sizeof (struct PeerInformationMessage))
265 {
266 GNUNET_break (0);
267 return GNUNET_SYSERR;
268 }
269 pi = (const struct PeerInformationMessage*) msg;
270 ats_count = ntohl (pi->ats_count);
271 address_length = ntohs (pi->address_length);
272 plugin_name_length = ntohs (pi->plugin_name_length);
273 atsi = (const struct GNUNET_TRANSPORT_ATS_Information*) &pi[1];
274 address = (const char*) &atsi[ats_count];
275 plugin_name = &address[address_length];
276 if ( (address_length +
277 plugin_name_length +
278 ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information) +
279 sizeof (struct PeerInformationMessage) != ntohs (msg->size)) ||
280 (ats_count > GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_TRANSPORT_ATS_Information)) ||
281 (plugin_name[plugin_name_length - 1] != '\0') )
282 {
283 GNUNET_break (0);
284 return GNUNET_SYSERR;
285 }
286 ph->infocb (ph->infocb_cls,
287 &pi->peer,
288 plugin_name,
289 address, address_length,
290 pi->bandwidth_out,
291 pi->bandwidth_in,
292 atsi,
293 ats_count);
294 return GNUNET_OK;
295}
296
297
298/**
299 * We received a reservation result message. Validate and process it.
300 *
301 * @param ph our context with the callback
302 * @param msg the message
303 * @return GNUNET_OK if the message was well-formed
304 */
305static int
306process_rr_message (struct GNUNET_ATS_PerformanceHandle *ph,
307 const struct GNUNET_MessageHeader *msg)
308{
309 const struct ReservationResultMessage *rr;
310 struct GNUNET_ATS_ReservationContext *rc;
311 int32_t amount;
312
313 if (ph->infocb == NULL)
314 {
315 GNUNET_break (0);
316 return GNUNET_SYSERR;
317 }
318 if (ntohs (msg->size) < sizeof (struct ReservationResultMessage))
319 {
320 GNUNET_break (0);
321 return GNUNET_SYSERR;
322 }
323 rr = (const struct ReservationResultMessage*) msg;
324 amount = ntohl (rr->amount);
325 rc = ph->reservation_head;
326 if (0 != memcmp (&rr->peer,
327 &rc->peer,
328 sizeof (struct GNUNET_PeerIdentity)))
329 {
330 GNUNET_break (0);
331 return GNUNET_SYSERR;
332 }
333 GNUNET_CONTAINER_DLL_remove (ph->reservation_head,
334 ph->reservation_tail,
335 rc);
336 if ( (amount == 0) ||
337 (rc->rcb != NULL) )
338 {
339 /* tell client if not cancelled */
340 if (rc->rcb != NULL)
341 rc->rcb (rc->rcb_cls,
342 &rr->peer,
343 amount,
344 GNUNET_TIME_relative_ntoh (rr->res_delay));
345 GNUNET_free (rc);
346 return GNUNET_OK;
347 }
348 GNUNET_free (rc);
349 /* amount non-zero, but client cancelled, consider undo! */
350 if (GNUNET_YES != rc->undo)
351 return GNUNET_OK; /* do not try to undo failed undos or negative amounts */
352 (void) GNUNET_ATS_reserve_bandwidth (ph, &rr->peer, -amount, NULL, NULL);
353 return GNUNET_OK;
354}
355
356
357/**
241 * Type of a function to call when we receive a message 358 * Type of a function to call when we receive a message
242 * from the service. 359 * from the service.
243 * 360 *
@@ -259,7 +376,24 @@ process_ats_message (void *cls,
259 } 376 }
260 switch (ntohs (msg->type)) 377 switch (ntohs (msg->type))
261 { 378 {
262 // FIXME 379 case GNUNET_MESSAGE_TYPE_ATS_PEER_INFORMATION:
380 if (GNUNET_OK != process_pi_message (ph, msg))
381 {
382 GNUNET_CLIENT_disconnect (ph->client, GNUNET_NO);
383 ph->client = NULL;
384 reconnect (ph);
385 return;
386 }
387 break;
388 case GNUNET_MESSAGE_TYPE_ATS_RESERVATION_RESULT:
389 if (GNUNET_OK != process_rr_message (ph, msg))
390 {
391 GNUNET_CLIENT_disconnect (ph->client, GNUNET_NO);
392 ph->client = NULL;
393 reconnect (ph);
394 return;
395 }
396 break;
263 default: 397 default:
264 GNUNET_break (0); 398 GNUNET_break (0);
265 GNUNET_CLIENT_disconnect (ph->client, GNUNET_NO); 399 GNUNET_CLIENT_disconnect (ph->client, GNUNET_NO);
@@ -359,7 +493,7 @@ GNUNET_ATS_performance_done (struct GNUNET_ATS_PerformanceHandle *ph)
359 GNUNET_CONTAINER_DLL_remove (ph->reservation_head, 493 GNUNET_CONTAINER_DLL_remove (ph->reservation_head,
360 ph->reservation_tail, 494 ph->reservation_tail,
361 rc); 495 rc);
362 GNUNET_break (NULL == rc->info); 496 GNUNET_break (NULL == rc->rcb);
363 GNUNET_free (p); 497 GNUNET_free (p);
364 } 498 }
365 GNUNET_CLIENT_disconnect (ph->client, GNUNET_NO); 499 GNUNET_CLIENT_disconnect (ph->client, GNUNET_NO);
@@ -376,8 +510,8 @@ GNUNET_ATS_performance_done (struct GNUNET_ATS_PerformanceHandle *ph)
376 * @param peer identifies the peer 510 * @param peer identifies the peer
377 * @param amount reserve N bytes for receiving, negative 511 * @param amount reserve N bytes for receiving, negative
378 * amounts can be used to undo a (recent) reservation; 512 * amounts can be used to undo a (recent) reservation;
379 * @param info function to call with the resulting reservation information 513 * @param rcb function to call with the resulting reservation information
380 * @param info_cls closure for info 514 * @param rcb_cls closure for info
381 * @return NULL on error 515 * @return NULL on error
382 * @deprecated will be replaced soon 516 * @deprecated will be replaced soon
383 */ 517 */
@@ -385,8 +519,8 @@ struct GNUNET_ATS_ReservationContext *
385GNUNET_ATS_reserve_bandwidth (struct GNUNET_ATS_PerformanceHandle *ph, 519GNUNET_ATS_reserve_bandwidth (struct GNUNET_ATS_PerformanceHandle *ph,
386 const struct GNUNET_PeerIdentity *peer, 520 const struct GNUNET_PeerIdentity *peer,
387 int32_t amount, 521 int32_t amount,
388 GNUNET_ATS_ReservationCallback info, 522 GNUNET_ATS_ReservationCallback rcb,
389 void *info_cls) 523 void *rcb_cls)
390{ 524{
391 struct GNUNET_ATS_ReservationContext *rc; 525 struct GNUNET_ATS_ReservationContext *rc;
392 struct PendingMessage *p; 526 struct PendingMessage *p;
@@ -395,8 +529,10 @@ GNUNET_ATS_reserve_bandwidth (struct GNUNET_ATS_PerformanceHandle *ph,
395 rc = GNUNET_malloc (sizeof (struct GNUNET_ATS_ReservationContext)); 529 rc = GNUNET_malloc (sizeof (struct GNUNET_ATS_ReservationContext));
396 rc->size = amount; 530 rc->size = amount;
397 rc->peer = *peer; 531 rc->peer = *peer;
398 rc->info = info; 532 rc->rcb = rcb;
399 rc->info_cls = info_cls; 533 rc->rcb_cls = rcb_cls;
534 if ( (rc != NULL) && (amount > 0) )
535 rc->undo = GNUNET_YES;
400 GNUNET_CONTAINER_DLL_insert_tail (ph->reservation_head, 536 GNUNET_CONTAINER_DLL_insert_tail (ph->reservation_head,
401 ph->reservation_tail, 537 ph->reservation_tail,
402 rc); 538 rc);
@@ -426,7 +562,7 @@ void
426GNUNET_ATS_reserve_bandwidth_cancel (struct 562GNUNET_ATS_reserve_bandwidth_cancel (struct
427 GNUNET_ATS_ReservationContext *rc) 563 GNUNET_ATS_ReservationContext *rc)
428{ 564{
429 rc->info = NULL; 565 rc->rcb = NULL;
430} 566}
431 567
432 568
diff --git a/src/ats/ats_api_scheduling.c b/src/ats/ats_api_scheduling.c
index 8b3e849b2..93cd7eab4 100644
--- a/src/ats/ats_api_scheduling.c
+++ b/src/ats/ats_api_scheduling.c
@@ -281,6 +281,7 @@ process_ats_message (void *cls,
281 const char *address; 281 const char *address;
282 const char *plugin_name; 282 const char *plugin_name;
283 uint16_t address_length; 283 uint16_t address_length;
284 uint16_t plugin_name_length;
284 uint32_t ats_count; 285 uint32_t ats_count;
285 286
286 if (NULL == msg) 287 if (NULL == msg)
@@ -305,12 +306,13 @@ process_ats_message (void *cls,
305 atsi = (const struct GNUNET_TRANSPORT_ATS_Information*) &m[1]; 306 atsi = (const struct GNUNET_TRANSPORT_ATS_Information*) &m[1];
306 address = (const char*) &atsi[ats_count]; 307 address = (const char*) &atsi[ats_count];
307 plugin_name = &address[address_length]; 308 plugin_name = &address[address_length];
308 if ( (ntohs (m->address_length) + 309 plugin_name_length = ntohs (m->plugin_name_length);
309 ntohs (m->plugin_name_length) + 310 if ( (address_length +
311 plugin_name_length +
310 ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information) + 312 ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information) +
311 sizeof (struct AddressSuggestionMessage) != ntohs (msg->size)) || 313 sizeof (struct AddressSuggestionMessage) != ntohs (msg->size)) ||
312 (ats_count > GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_TRANSPORT_ATS_Information)) || 314 (ats_count > GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_TRANSPORT_ATS_Information)) ||
313 (plugin_name[ntohs (m->plugin_name_length) - 1] != '\0') ) 315 (plugin_name[plugin_name_length - 1] != '\0') )
314 { 316 {
315 GNUNET_break (0); 317 GNUNET_break (0);
316 GNUNET_CLIENT_disconnect (sh->client, GNUNET_NO); 318 GNUNET_CLIENT_disconnect (sh->client, GNUNET_NO);
diff --git a/src/include/gnunet_ats_service.h b/src/include/gnunet_ats_service.h
index 79be70ce4..0213f0ed1 100644
--- a/src/include/gnunet_ats_service.h
+++ b/src/include/gnunet_ats_service.h
@@ -225,7 +225,7 @@ GNUNET_ATS_performance_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
225 * @param ph handle 225 * @param ph handle
226 */ 226 */
227void 227void
228GNUNET_ATS_performance_done (struct GNUNET_ATS_SchedulingHandle *ph); 228GNUNET_ATS_performance_done (struct GNUNET_ATS_PerformanceHandle *ph);
229 229
230 230
231/** 231/**
@@ -264,8 +264,8 @@ struct GNUNET_ATS_ReservationContext;
264 * @param peer identifies the peer 264 * @param peer identifies the peer
265 * @param amount reserve N bytes for receiving, negative 265 * @param amount reserve N bytes for receiving, negative
266 * amounts can be used to undo a (recent) reservation; 266 * amounts can be used to undo a (recent) reservation;
267 * @param info function to call with the resulting reservation information 267 * @param rcb function to call with the resulting reservation information
268 * @param info_cls closure for info 268 * @param rcb_cls closure for info
269 * @return NULL on error 269 * @return NULL on error
270 * @deprecated will be replaced soon 270 * @deprecated will be replaced soon
271 */ 271 */
@@ -273,8 +273,8 @@ struct GNUNET_ATS_ReservationContext *
273GNUNET_ATS_reserve_bandwidth (struct GNUNET_ATS_PerformanceHandle *ph, 273GNUNET_ATS_reserve_bandwidth (struct GNUNET_ATS_PerformanceHandle *ph,
274 const struct GNUNET_PeerIdentity *peer, 274 const struct GNUNET_PeerIdentity *peer,
275 int32_t amount, 275 int32_t amount,
276 GNUNET_ATS_ReservationCallback info, 276 GNUNET_ATS_ReservationCallback rcb,
277 void *info_cls); 277 void *rcb_cls);
278 278
279 279
280/** 280/**