aboutsummaryrefslogtreecommitdiff
path: root/src/fs/gnunet-service-fs_cp.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-03-27 11:00:57 +0000
committerChristian Grothoff <christian@grothoff.org>2011-03-27 11:00:57 +0000
commit79a55c154e2b706ad6fbc8d522955f240f33a8e4 (patch)
tree539b23e6463c9a85f9323c7d2e35a48af6e70183 /src/fs/gnunet-service-fs_cp.c
parentc30009f3a51396348326b0591241af66203f29f1 (diff)
downloadgnunet-79a55c154e2b706ad6fbc8d522955f240f33a8e4.tar.gz
gnunet-79a55c154e2b706ad6fbc8d522955f240f33a8e4.zip
delay as needed
Diffstat (limited to 'src/fs/gnunet-service-fs_cp.c')
-rw-r--r--src/fs/gnunet-service-fs_cp.c91
1 files changed, 73 insertions, 18 deletions
diff --git a/src/fs/gnunet-service-fs_cp.c b/src/fs/gnunet-service-fs_cp.c
index 05638b657..a6f151e9e 100644
--- a/src/fs/gnunet-service-fs_cp.c
+++ b/src/fs/gnunet-service-fs_cp.c
@@ -153,11 +153,15 @@ struct GSF_ConnectedPeer
153 153
154 /** 154 /**
155 * Context of our GNUNET_CORE_peer_change_preference call (or NULL). 155 * Context of our GNUNET_CORE_peer_change_preference call (or NULL).
156 * NULL if we have successfully reserved 32k, otherwise non-NULL.
157 */ 156 */
158 struct GNUNET_CORE_InformationRequestContext *irc; 157 struct GNUNET_CORE_InformationRequestContext *irc;
159 158
160 /** 159 /**
160 * Task scheduled if we need to retry bandwidth reservation later.
161 */
162 GNUNET_SCHEDULER_TaskIdentifier irc_delay_task;
163
164 /**
161 * Active requests from this neighbour. 165 * Active requests from this neighbour.
162 */ 166 */
163 struct GNUNET_CONTAINER_MultiHashMap *request_map; 167 struct GNUNET_CONTAINER_MultiHashMap *request_map;
@@ -190,6 +194,12 @@ struct GSF_ConnectedPeer
190 */ 194 */
191 unsigned int last_request_times_off; 195 unsigned int last_request_times_off;
192 196
197 /**
198 * GNUNET_YES if we did successfully reserve 32k bandwidth,
199 * GNUNET_NO if not.
200 */
201 int did_reserve;
202
193}; 203};
194 204
195 205
@@ -340,32 +350,71 @@ core_reserve_callback (void *cls,
340 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, 350 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
341 int32_t amount, 351 int32_t amount,
342 struct GNUNET_TIME_Relative res_delay, 352 struct GNUNET_TIME_Relative res_delay,
353 uint64_t preference);
354
355
356/**
357 * (re)try to reserve bandwidth from the given peer.
358 *
359 * @param cls the 'struct GSF_ConnectedPeer' to reserve from
360 * @param tc scheduler context
361 */
362static void
363retry_reservation (void *cls,
364 const struct GNUNET_SCHEDULER_TaskContext *tc)
365{
366 struct GSF_ConnectedPeer *cp = cls;
367 uint64_t ip;
368 struct GNUNET_PeerIdentity target;
369
370 GNUNET_PEER_resolve (cp->ppd.pid,
371 &target);
372 cp->irc_delay_task = GNUNET_SCHEDULER_NO_TASK;
373 ip = cp->inc_preference;
374 cp->inc_preference = 0;
375 cp->irc = GNUNET_CORE_peer_change_preference (GSF_core,
376 &target,
377 GNUNET_TIME_UNIT_FOREVER_REL,
378 GNUNET_BANDWIDTH_VALUE_MAX,
379 DBLOCK_SIZE,
380 ip,
381 &core_reserve_callback,
382 cp);
383}
384
385
386/**
387 * Function called by core upon success or failure of our bandwidth reservation request.
388 *
389 * @param cls the 'struct GSF_ConnectedPeer' of the peer for which we made the request
390 * @param peer identifies the peer
391 * @param bandwidth_out available amount of outbound bandwidth
392 * @param amount set to the amount that was actually reserved or unreserved;
393 * either the full requested amount or zero (no partial reservations)
394 * @param res_delay if the reservation could not be satisfied (amount was 0), how
395 * long should the client wait until re-trying?
396 * @param preference current traffic preference for the given peer
397 */
398static void
399core_reserve_callback (void *cls,
400 const struct GNUNET_PeerIdentity *peer,
401 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
402 int32_t amount,
403 struct GNUNET_TIME_Relative res_delay,
343 uint64_t preference) 404 uint64_t preference)
344{ 405{
345 struct GSF_ConnectedPeer *cp = cls; 406 struct GSF_ConnectedPeer *cp = cls;
346 struct GSF_PeerTransmitHandle *pth; 407 struct GSF_PeerTransmitHandle *pth;
347 uint64_t ip;
348 408
349 cp->irc = NULL; 409 cp->irc = NULL;
350 if (0 == amount) 410 if (0 == amount)
351 { 411 {
352 /* failed; retry! (how did we get here!?) */ 412 cp->irc_delay_task = GNUNET_SCHEDULER_add_delayed (res_delay,
353 /* FIXME: wait res_delay before re-trying! */ 413 &retry_reservation,
354 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 414 cp);
355 _("Failed to reserve bandwidth to peer `%s'\n"),
356 GNUNET_i2s (peer));
357 ip = cp->inc_preference;
358 cp->inc_preference = 0;
359 cp->irc = GNUNET_CORE_peer_change_preference (GSF_core,
360 peer,
361 GNUNET_TIME_UNIT_FOREVER_REL,
362 GNUNET_BANDWIDTH_VALUE_MAX,
363 DBLOCK_SIZE,
364 ip,
365 &core_reserve_callback,
366 cp);
367 return; 415 return;
368 } 416 }
417 cp->did_reserve = GNUNET_YES;
369 pth = cp->pth_head; 418 pth = cp->pth_head;
370 if ( (NULL != pth) && 419 if ( (NULL != pth) &&
371 (NULL == pth->cth) ) 420 (NULL == pth->cth) )
@@ -1089,8 +1138,9 @@ GSF_peer_transmit_ (struct GSF_ConnectedPeer *cp,
1089 { 1138 {
1090 /* query, need reservation */ 1139 /* query, need reservation */
1091 cp->ppd.pending_queries++; 1140 cp->ppd.pending_queries++;
1092 if (NULL == cp->irc) 1141 if (GNUNET_YES == cp->did_reserve)
1093 { 1142 {
1143 cp->did_reserve = GNUNET_NO;
1094 /* reservation already done! */ 1144 /* reservation already done! */
1095 is_ready = GNUNET_YES; 1145 is_ready = GNUNET_YES;
1096 ip = cp->inc_preference; 1146 ip = cp->inc_preference;
@@ -1310,6 +1360,11 @@ GSF_peer_disconnect_handler_ (void *cls,
1310 GNUNET_CORE_peer_change_preference_cancel (cp->irc); 1360 GNUNET_CORE_peer_change_preference_cancel (cp->irc);
1311 cp->irc = NULL; 1361 cp->irc = NULL;
1312 } 1362 }
1363 if (GNUNET_SCHEDULER_NO_TASK != cp->irc_delay_task)
1364 {
1365 GNUNET_SCHEDULER_cancel (cp->irc_delay_task);
1366 cp->irc_delay_task = GNUNET_SCHEDULER_NO_TASK;
1367 }
1313 GNUNET_CONTAINER_multihashmap_iterate (cp->request_map, 1368 GNUNET_CONTAINER_multihashmap_iterate (cp->request_map,
1314 &cancel_pending_request, 1369 &cancel_pending_request,
1315 cp); 1370 cp);