aboutsummaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-06-09 15:12:03 +0000
committerChristian Grothoff <christian@grothoff.org>2012-06-09 15:12:03 +0000
commit7831efe09b1e8d30c7361e4b6c17b6966ad0fafa (patch)
treeb4824d071fc9721bbec6609d98ef1fd069dfb232 /src/core
parent7ae3bcd234e062c28f66db9758f61af401d0a707 (diff)
downloadgnunet-7831efe09b1e8d30c7361e4b6c17b6966ad0fafa.tar.gz
gnunet-7831efe09b1e8d30c7361e4b6c17b6966ad0fafa.zip
-fixing #2400
Diffstat (limited to 'src/core')
-rw-r--r--src/core/core.h4
-rw-r--r--src/core/core_api.c289
2 files changed, 98 insertions, 195 deletions
diff --git a/src/core/core.h b/src/core/core.h
index 03e328ca8..9b1802fbc 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -257,9 +257,9 @@ struct SendMessageRequest
257 struct GNUNET_PeerIdentity peer; 257 struct GNUNET_PeerIdentity peer;
258 258
259 /** 259 /**
260 * How large is the client's message queue for this peer? 260 * Always zero.
261 */ 261 */
262 uint32_t queue_size GNUNET_PACKED; 262 uint32_t reserved GNUNET_PACKED;
263 263
264 /** 264 /**
265 * How large is the message? 265 * How large is the message?
diff --git a/src/core/core_api.c b/src/core/core_api.c
index 2b6407b6e..5c16adeae 100644
--- a/src/core/core_api.c
+++ b/src/core/core_api.c
@@ -31,6 +31,65 @@
31 31
32#define LOG(kind,...) GNUNET_log_from (kind, "core-api",__VA_ARGS__) 32#define LOG(kind,...) GNUNET_log_from (kind, "core-api",__VA_ARGS__)
33 33
34
35/**
36 * Handle for a transmission request.
37 */
38struct GNUNET_CORE_TransmitHandle
39{
40
41 /**
42 * Corresponding peer record.
43 */
44 struct PeerRecord *peer;
45
46 /**
47 * Corresponding SEND_REQUEST message. Only non-NULL
48 * while SEND_REQUEST message is pending.
49 */
50 struct ControlMessage *cm;
51
52 /**
53 * Function that will be called to get the actual request
54 * (once we are ready to transmit this request to the core).
55 * The function will be called with a NULL buffer to signal
56 * timeout.
57 */
58 GNUNET_CONNECTION_TransmitReadyNotify get_message;
59
60 /**
61 * Closure for get_message.
62 */
63 void *get_message_cls;
64
65 /**
66 * Timeout for this handle.
67 */
68 struct GNUNET_TIME_Absolute timeout;
69
70 /**
71 * How important is this message?
72 */
73 uint32_t priority;
74
75 /**
76 * Size of this request.
77 */
78 uint16_t msize;
79
80 /**
81 * Send message request ID for this request.
82 */
83 uint16_t smr_id;
84
85 /**
86 * Is corking allowed?
87 */
88 int cork;
89
90};
91
92
34/** 93/**
35 * Information we track for each peer. 94 * Information we track for each peer.
36 */ 95 */
@@ -62,16 +121,10 @@ struct PeerRecord
62 struct GNUNET_CORE_Handle *ch; 121 struct GNUNET_CORE_Handle *ch;
63 122
64 /** 123 /**
65 * Head of doubly-linked list of pending requests. 124 * Pending request, if any. 'th->peer' is set to NULL if the
66 * Requests are sorted by deadline *except* for HEAD, 125 * request is not active.
67 * which is only modified upon transmission to core.
68 */ 126 */
69 struct GNUNET_CORE_TransmitHandle *pending_head; 127 struct GNUNET_CORE_TransmitHandle th;
70
71 /**
72 * Tail of doubly-linked list of pending requests.
73 */
74 struct GNUNET_CORE_TransmitHandle *pending_tail;
75 128
76 /** 129 /**
77 * ID of timeout task for the 'pending_head' handle 130 * ID of timeout task for the 'pending_head' handle
@@ -85,11 +138,6 @@ struct PeerRecord
85 GNUNET_SCHEDULER_TaskIdentifier ntr_task; 138 GNUNET_SCHEDULER_TaskIdentifier ntr_task;
86 139
87 /** 140 /**
88 * Current size of the queue of pending requests.
89 */
90 unsigned int queue_size;
91
92 /**
93 * SendMessageRequest ID generator for this peer. 141 * SendMessageRequest ID generator for this peer.
94 */ 142 */
95 uint16_t smr_id_gen; 143 uint16_t smr_id_gen;
@@ -247,11 +295,6 @@ struct GNUNET_CORE_Handle
247 struct GNUNET_TIME_Relative retry_backoff; 295 struct GNUNET_TIME_Relative retry_backoff;
248 296
249 /** 297 /**
250 * Number of messages we are allowed to queue per target.
251 */
252 unsigned int queue_size;
253
254 /**
255 * Number of entries in the handlers array. 298 * Number of entries in the handlers array.
256 */ 299 */
257 unsigned int hcnt; 300 unsigned int hcnt;
@@ -278,74 +321,6 @@ struct GNUNET_CORE_Handle
278 321
279 322
280/** 323/**
281 * Handle for a transmission request.
282 */
283struct GNUNET_CORE_TransmitHandle
284{
285
286 /**
287 * We keep active transmit handles in a doubly-linked list.
288 */
289 struct GNUNET_CORE_TransmitHandle *next;
290
291 /**
292 * We keep active transmit handles in a doubly-linked list.
293 */
294 struct GNUNET_CORE_TransmitHandle *prev;
295
296 /**
297 * Corresponding peer record.
298 */
299 struct PeerRecord *peer;
300
301 /**
302 * Corresponding SEND_REQUEST message. Only non-NULL
303 * while SEND_REQUEST message is pending.
304 */
305 struct ControlMessage *cm;
306
307 /**
308 * Function that will be called to get the actual request
309 * (once we are ready to transmit this request to the core).
310 * The function will be called with a NULL buffer to signal
311 * timeout.
312 */
313 GNUNET_CONNECTION_TransmitReadyNotify get_message;
314
315 /**
316 * Closure for get_message.
317 */
318 void *get_message_cls;
319
320 /**
321 * Timeout for this handle.
322 */
323 struct GNUNET_TIME_Absolute timeout;
324
325 /**
326 * How important is this message?
327 */
328 uint32_t priority;
329
330 /**
331 * Size of this request.
332 */
333 uint16_t msize;
334
335 /**
336 * Send message request ID for this request.
337 */
338 uint16_t smr_id;
339
340 /**
341 * Is corking allowed?
342 */
343 int cork;
344
345};
346
347
348/**
349 * Our current client connection went down. Clean it up 324 * Our current client connection went down. Clean it up
350 * and try to reconnect! 325 * and try to reconnect!
351 * 326 *
@@ -404,23 +379,18 @@ disconnect_and_free_peer_entry (void *cls, const GNUNET_HashCode * key,
404 if (h->disconnects != NULL) 379 if (h->disconnects != NULL)
405 h->disconnects (h->cls, &pr->peer); 380 h->disconnects (h->cls, &pr->peer);
406 /* all requests should have been cancelled, clean up anyway, just in case */ 381 /* all requests should have been cancelled, clean up anyway, just in case */
407 GNUNET_break (pr->queue_size == 0); 382 th = &pr->th;
408 while (NULL != (th = pr->pending_head)) 383 if (NULL != th->peer)
409 { 384 {
410 GNUNET_break (0); 385 GNUNET_break (0);
411 GNUNET_CONTAINER_DLL_remove (pr->pending_head, pr->pending_tail, th); 386 th->peer = NULL;
412 pr->queue_size--;
413 if (th->cm != NULL) 387 if (th->cm != NULL)
414 th->cm->th = NULL; 388 th->cm->th = NULL;
415 GNUNET_free (th);
416 } 389 }
417 /* done with 'voluntary' cleanups, now on to normal freeing */ 390 /* done with 'voluntary' cleanups, now on to normal freeing */
418 GNUNET_assert (GNUNET_YES == 391 GNUNET_assert (GNUNET_YES ==
419 GNUNET_CONTAINER_multihashmap_remove (h->peers, key, pr)); 392 GNUNET_CONTAINER_multihashmap_remove (h->peers, key, pr));
420 GNUNET_assert (pr->pending_head == NULL);
421 GNUNET_assert (pr->pending_tail == NULL);
422 GNUNET_assert (pr->ch == h); 393 GNUNET_assert (pr->ch == h);
423 GNUNET_assert (pr->queue_size == 0);
424 GNUNET_assert (pr->timeout_task == GNUNET_SCHEDULER_NO_TASK); 394 GNUNET_assert (pr->timeout_task == GNUNET_SCHEDULER_NO_TASK);
425 GNUNET_assert (pr->ntr_task == GNUNET_SCHEDULER_NO_TASK); 395 GNUNET_assert (pr->ntr_task == GNUNET_SCHEDULER_NO_TASK);
426 GNUNET_free (pr); 396 GNUNET_free (pr);
@@ -517,7 +487,8 @@ request_next_transmission (struct PeerRecord *pr)
517 GNUNET_SCHEDULER_cancel (pr->timeout_task); 487 GNUNET_SCHEDULER_cancel (pr->timeout_task);
518 pr->timeout_task = GNUNET_SCHEDULER_NO_TASK; 488 pr->timeout_task = GNUNET_SCHEDULER_NO_TASK;
519 } 489 }
520 if (NULL == (th = pr->pending_head)) 490 th = &pr->th;
491 if (NULL == th->peer)
521 { 492 {
522 trigger_next_request (h, GNUNET_NO); 493 trigger_next_request (h, GNUNET_NO);
523 return; 494 return;
@@ -539,7 +510,7 @@ request_next_transmission (struct PeerRecord *pr)
539 smr->priority = htonl (th->priority); 510 smr->priority = htonl (th->priority);
540 smr->deadline = GNUNET_TIME_absolute_hton (th->timeout); 511 smr->deadline = GNUNET_TIME_absolute_hton (th->timeout);
541 smr->peer = pr->peer; 512 smr->peer = pr->peer;
542 smr->queue_size = htonl (pr->queue_size); 513 smr->reserved = htonl (0);
543 smr->size = htons (th->msize); 514 smr->size = htons (th->msize);
544 smr->smr_id = htons (th->smr_id = pr->smr_id_gen++); 515 smr->smr_id = htons (th->smr_id = pr->smr_id_gen++);
545 GNUNET_CONTAINER_DLL_insert_tail (h->control_pending_head, 516 GNUNET_CONTAINER_DLL_insert_tail (h->control_pending_head,
@@ -566,9 +537,8 @@ transmission_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
566 struct GNUNET_CORE_TransmitHandle *th; 537 struct GNUNET_CORE_TransmitHandle *th;
567 538
568 pr->timeout_task = GNUNET_SCHEDULER_NO_TASK; 539 pr->timeout_task = GNUNET_SCHEDULER_NO_TASK;
569 th = pr->pending_head; 540 th = &pr->th;
570 GNUNET_CONTAINER_DLL_remove (pr->pending_head, pr->pending_tail, th); 541 th->peer = NULL;
571 pr->queue_size--;
572 if ((pr->prev != NULL) || (pr->next != NULL) || (pr == h->ready_peer_head)) 542 if ((pr->prev != NULL) || (pr->next != NULL) || (pr == h->ready_peer_head))
573 { 543 {
574 /* the request that was 'approved' by core was 544 /* the request that was 'approved' by core was
@@ -587,7 +557,6 @@ transmission_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
587 "Signalling timeout of request for transmission to CORE service\n"); 557 "Signalling timeout of request for transmission to CORE service\n");
588 request_next_transmission (pr); 558 request_next_transmission (pr);
589 GNUNET_assert (0 == th->get_message (th->get_message_cls, 0, NULL)); 559 GNUNET_assert (0 == th->get_message (th->get_message_cls, 0, NULL));
590 GNUNET_free (th);
591} 560}
592 561
593 562
@@ -647,16 +616,15 @@ transmit_message (void *cls, size_t size, void *buf)
647 /* now check for 'ready' P2P messages */ 616 /* now check for 'ready' P2P messages */
648 if (NULL != (pr = h->ready_peer_head)) 617 if (NULL != (pr = h->ready_peer_head))
649 { 618 {
650 GNUNET_assert (pr->pending_head != NULL); 619 GNUNET_assert (NULL != pr->th.peer);
651 th = pr->pending_head; 620 th = &pr->th;
652 if (size < th->msize + sizeof (struct SendMessage)) 621 if (size < th->msize + sizeof (struct SendMessage))
653 { 622 {
654 trigger_next_request (h, GNUNET_NO); 623 trigger_next_request (h, GNUNET_NO);
655 return 0; 624 return 0;
656 } 625 }
657 GNUNET_CONTAINER_DLL_remove (h->ready_peer_head, h->ready_peer_tail, pr); 626 GNUNET_CONTAINER_DLL_remove (h->ready_peer_head, h->ready_peer_tail, pr);
658 GNUNET_CONTAINER_DLL_remove (pr->pending_head, pr->pending_tail, th); 627 th->peer = NULL;
659 pr->queue_size--;
660 if (pr->timeout_task != GNUNET_SCHEDULER_NO_TASK) 628 if (pr->timeout_task != GNUNET_SCHEDULER_NO_TASK)
661 { 629 {
662 GNUNET_SCHEDULER_cancel (pr->timeout_task); 630 GNUNET_SCHEDULER_cancel (pr->timeout_task);
@@ -679,7 +647,6 @@ transmit_message (void *cls, size_t size, void *buf)
679 LOG (GNUNET_ERROR_TYPE_DEBUG, 647 LOG (GNUNET_ERROR_TYPE_DEBUG,
680 "Transmitting SEND request to `%s' yielded %u bytes.\n", 648 "Transmitting SEND request to `%s' yielded %u bytes.\n",
681 GNUNET_i2s (&pr->peer), ret); 649 GNUNET_i2s (&pr->peer), ret);
682 GNUNET_free (th);
683 if (0 == ret) 650 if (0 == ret)
684 { 651 {
685 LOG (GNUNET_ERROR_TYPE_DEBUG, 652 LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -738,7 +705,7 @@ trigger_next_request (struct GNUNET_CORE_Handle *h, int ignore_currently_down)
738 control_pending_head[1])->size); 705 control_pending_head[1])->size);
739 else if (h->ready_peer_head != NULL) 706 else if (h->ready_peer_head != NULL)
740 msize = 707 msize =
741 h->ready_peer_head->pending_head->msize + sizeof (struct SendMessage); 708 h->ready_peer_head->th.msize + sizeof (struct SendMessage);
742 else 709 else
743 { 710 {
744 LOG (GNUNET_ERROR_TYPE_DEBUG, 711 LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -782,8 +749,7 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg)
782 if (NULL == msg) 749 if (NULL == msg)
783 { 750 {
784 LOG (GNUNET_ERROR_TYPE_INFO, 751 LOG (GNUNET_ERROR_TYPE_INFO,
785 _ 752 _("Client was disconnected from core service, trying to reconnect.\n"));
786 ("Client was disconnected from core service, trying to reconnect.\n"));
787 reconnect_later (h); 753 reconnect_later (h);
788 return; 754 return;
789 } 755 }
@@ -1032,14 +998,14 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg)
1032 LOG (GNUNET_ERROR_TYPE_DEBUG, 998 LOG (GNUNET_ERROR_TYPE_DEBUG,
1033 "Received notification about transmission readiness to `%s'.\n", 999 "Received notification about transmission readiness to `%s'.\n",
1034 GNUNET_i2s (&smr->peer)); 1000 GNUNET_i2s (&smr->peer));
1035 if (NULL == pr->pending_head) 1001 if (NULL == pr->th.peer)
1036 { 1002 {
1037 /* request must have been cancelled between the original request 1003 /* request must have been cancelled between the original request
1038 * and the response from core, ignore core's readiness */ 1004 * and the response from core, ignore core's readiness */
1039 break; 1005 break;
1040 } 1006 }
1041 1007
1042 th = pr->pending_head; 1008 th = &pr->th;
1043 if (ntohs (smr->smr_id) != th->smr_id) 1009 if (ntohs (smr->smr_id) != th->smr_id)
1044 { 1010 {
1045 /* READY message is for expired or cancelled message, 1011 /* READY message is for expired or cancelled message,
@@ -1191,7 +1157,6 @@ GNUNET_CORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
1191 1157
1192 h = GNUNET_malloc (sizeof (struct GNUNET_CORE_Handle)); 1158 h = GNUNET_malloc (sizeof (struct GNUNET_CORE_Handle));
1193 h->cfg = cfg; 1159 h->cfg = cfg;
1194 h->queue_size = 1; // FIXME: remove entirely...
1195 h->cls = cls; 1160 h->cls = cls;
1196 h->init = init; 1161 h->init = init;
1197 h->connects = connects; 1162 h->connects = connects;
@@ -1318,89 +1283,34 @@ GNUNET_CORE_notify_transmit_ready (struct GNUNET_CORE_Handle *handle, int cork,
1318{ 1283{
1319 struct PeerRecord *pr; 1284 struct PeerRecord *pr;
1320 struct GNUNET_CORE_TransmitHandle *th; 1285 struct GNUNET_CORE_TransmitHandle *th;
1321 struct GNUNET_CORE_TransmitHandle *pos;
1322 struct GNUNET_CORE_TransmitHandle *prev;
1323 struct GNUNET_CORE_TransmitHandle *minp;
1324 1286
1287 GNUNET_assert (NULL != notify);
1325 pr = GNUNET_CONTAINER_multihashmap_get (handle->peers, &target->hashPubKey); 1288 pr = GNUNET_CONTAINER_multihashmap_get (handle->peers, &target->hashPubKey);
1326 if (NULL == pr) 1289 if (NULL == pr)
1327 { 1290 {
1328 /* attempt to send to peer that is not connected */ 1291 /* attempt to send to peer that is not connected */
1329 LOG (GNUNET_ERROR_TYPE_WARNING, 1292 GNUNET_break (0);
1330 "Attempting to send to peer `%s' from peer `%s', but not connected!\n", 1293 return NULL;
1331 GNUNET_i2s (target), GNUNET_h2s (&handle->me.hashPubKey)); 1294 }
1295 if (NULL != pr->th.peer)
1296 {
1297 /* attempting to queue a second request for the same destination */
1332 GNUNET_break (0); 1298 GNUNET_break (0);
1333 return NULL; 1299 return NULL;
1334 } 1300 }
1335 GNUNET_assert (notify_size + sizeof (struct SendMessage) < 1301 GNUNET_assert (notify_size + sizeof (struct SendMessage) <
1336 GNUNET_SERVER_MAX_MESSAGE_SIZE); 1302 GNUNET_SERVER_MAX_MESSAGE_SIZE);
1337 th = GNUNET_malloc (sizeof (struct GNUNET_CORE_TransmitHandle)); 1303 th = &pr->th;
1338 th->peer = pr; 1304 th->peer = pr;
1339 GNUNET_assert (NULL != notify);
1340 th->get_message = notify; 1305 th->get_message = notify;
1341 th->get_message_cls = notify_cls; 1306 th->get_message_cls = notify_cls;
1342 th->timeout = GNUNET_TIME_relative_to_absolute (maxdelay); 1307 th->timeout = GNUNET_TIME_relative_to_absolute (maxdelay);
1343 th->priority = priority; 1308 th->priority = priority;
1344 th->msize = notify_size; 1309 th->msize = notify_size;
1345 th->cork = cork; 1310 th->cork = cork;
1346 /* bound queue size */ 1311 pr->ntr_task =
1347 if (pr->queue_size == handle->queue_size) 1312 GNUNET_SCHEDULER_add_now (&run_request_next_transmission, pr);
1348 {
1349 /* find lowest-priority entry, but skip the head of the list */
1350 minp = pr->pending_head->next;
1351 prev = minp;
1352 while (prev != NULL)
1353 {
1354 if (prev->priority < minp->priority)
1355 minp = prev;
1356 prev = prev->next;
1357 }
1358 if (minp == NULL)
1359 {
1360 GNUNET_break (handle->queue_size != 0);
1361 GNUNET_break (pr->queue_size == 1);
1362 GNUNET_free (th);
1363 LOG (GNUNET_ERROR_TYPE_DEBUG,
1364 "Dropping transmission request: cannot drop queue head and limit is one\n");
1365 return NULL;
1366 }
1367 if (priority <= minp->priority)
1368 {
1369 LOG (GNUNET_ERROR_TYPE_DEBUG,
1370 "Dropping transmission request: priority too low\n");
1371 GNUNET_free (th);
1372 return NULL; /* priority too low */
1373 }
1374 GNUNET_CONTAINER_DLL_remove (pr->pending_head, pr->pending_tail, minp);
1375 pr->queue_size--;
1376 GNUNET_assert (0 == minp->get_message (minp->get_message_cls, 0, NULL));
1377 GNUNET_free (minp);
1378 }
1379
1380 /* Order entries by deadline, but SKIP 'HEAD' (as we may have transmitted
1381 * that request already or might even already be approved to transmit that
1382 * message to core) */
1383 pos = pr->pending_head;
1384 if (pos != NULL)
1385 pos = pos->next; /* skip head */
1386
1387 /* insertion sort */
1388 prev = pos;
1389 while ((NULL != pos) && (pos->timeout.abs_value < th->timeout.abs_value))
1390 {
1391 prev = pos;
1392 pos = pos->next;
1393 }
1394 GNUNET_CONTAINER_DLL_insert_after (pr->pending_head, pr->pending_tail, prev,
1395 th);
1396 pr->queue_size++;
1397 /* was the request queue previously empty? */
1398 LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmission request added to queue\n"); 1313 LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmission request added to queue\n");
1399 if ((pr->pending_head == th) && (pr->ntr_task == GNUNET_SCHEDULER_NO_TASK) &&
1400 (pr->next == NULL) && (pr->prev == NULL) &&
1401 (handle->ready_peer_head != pr))
1402 pr->ntr_task =
1403 GNUNET_SCHEDULER_add_now (&run_request_next_transmission, pr);
1404 return th; 1314 return th;
1405} 1315}
1406 1316
@@ -1414,12 +1324,11 @@ void
1414GNUNET_CORE_notify_transmit_ready_cancel (struct GNUNET_CORE_TransmitHandle *th) 1324GNUNET_CORE_notify_transmit_ready_cancel (struct GNUNET_CORE_TransmitHandle *th)
1415{ 1325{
1416 struct PeerRecord *pr = th->peer; 1326 struct PeerRecord *pr = th->peer;
1417 struct GNUNET_CORE_Handle *h = pr->ch; 1327 struct GNUNET_CORE_Handle *h;
1418 int was_head;
1419 1328
1420 was_head = (pr->pending_head == th); 1329 GNUNET_assert (NULL != pr);
1421 GNUNET_CONTAINER_DLL_remove (pr->pending_head, pr->pending_tail, th); 1330 th->peer = NULL;
1422 pr->queue_size--; 1331 h = pr->ch;
1423 if (NULL != th->cm) 1332 if (NULL != th->cm)
1424 { 1333 {
1425 /* we're currently in the control queue, remove */ 1334 /* we're currently in the control queue, remove */
@@ -1427,18 +1336,12 @@ GNUNET_CORE_notify_transmit_ready_cancel (struct GNUNET_CORE_TransmitHandle *th)
1427 h->control_pending_tail, th->cm); 1336 h->control_pending_tail, th->cm);
1428 GNUNET_free (th->cm); 1337 GNUNET_free (th->cm);
1429 } 1338 }
1430 GNUNET_free (th); 1339 if ((NULL != pr->prev) || (NULL != pr->next) || (pr == h->ready_peer_head))
1431 if (was_head)
1432 { 1340 {
1433 if ((NULL != pr->prev) || (NULL != pr->next) || (pr == h->ready_peer_head)) 1341 /* the request that was 'approved' by core was
1434 { 1342 * canceled before it could be transmitted; remove
1435 /* the request that was 'approved' by core was 1343 * us from the 'ready' list */
1436 * canceled before it could be transmitted; remove 1344 GNUNET_CONTAINER_DLL_remove (h->ready_peer_head, h->ready_peer_tail, pr);
1437 * us from the 'ready' list */
1438 GNUNET_CONTAINER_DLL_remove (h->ready_peer_head, h->ready_peer_tail, pr);
1439 }
1440 if (NULL != h->client)
1441 request_next_transmission (pr);
1442 } 1345 }
1443} 1346}
1444 1347