diff options
Diffstat (limited to 'src/ats/ats_api_performance.c')
-rw-r--r-- | src/ats/ats_api_performance.c | 160 |
1 files changed, 148 insertions, 12 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 | */ | ||
247 | static int | ||
248 | process_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 | */ | ||
305 | static int | ||
306 | process_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 * | |||
385 | GNUNET_ATS_reserve_bandwidth (struct GNUNET_ATS_PerformanceHandle *ph, | 519 | GNUNET_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 | |||
426 | GNUNET_ATS_reserve_bandwidth_cancel (struct | 562 | GNUNET_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 | ||