diff options
author | Christian Grothoff <christian@grothoff.org> | 2015-10-25 23:47:39 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2015-10-25 23:47:39 +0000 |
commit | 7c55f94e78c72d3b78a5c6007e3658ae30e1f64b (patch) | |
tree | 77cb53d80cbb79053a68c71a270586e6e0dcb1ef | |
parent | 124f3e77a5e022f5f7ab49df49023d0080bcbbb4 (diff) | |
download | gnunet-7c55f94e78c72d3b78a5c6007e3658ae30e1f64b.tar.gz gnunet-7c55f94e78c72d3b78a5c6007e3658ae30e1f64b.zip |
-use hash in prd query to reduce memory consumption of CP request_map
-rw-r--r-- | src/fs/gnunet-service-fs_cp.c | 27 | ||||
-rw-r--r-- | src/fs/gnunet-service-fs_pe.c | 69 | ||||
-rw-r--r-- | src/fs/gnunet-service-fs_pr.c | 11 | ||||
-rw-r--r-- | src/fs/gnunet-service-fs_pr.h | 27 |
4 files changed, 83 insertions, 51 deletions
diff --git a/src/fs/gnunet-service-fs_cp.c b/src/fs/gnunet-service-fs_cp.c index 7066b0698..1d52f28f9 100644 --- a/src/fs/gnunet-service-fs_cp.c +++ b/src/fs/gnunet-service-fs_cp.c | |||
@@ -250,7 +250,7 @@ struct GSF_ConnectedPeer | |||
250 | struct GNUNET_SCHEDULER_Task *rc_delay_task; | 250 | struct GNUNET_SCHEDULER_Task *rc_delay_task; |
251 | 251 | ||
252 | /** | 252 | /** |
253 | * Active requests from this neighbour, map of query to 'struct PeerRequest'. | 253 | * Active requests from this neighbour, map of query to `struct PeerRequest`. |
254 | */ | 254 | */ |
255 | struct GNUNET_CONTAINER_MultiHashMap *request_map; | 255 | struct GNUNET_CONTAINER_MultiHashMap *request_map; |
256 | 256 | ||
@@ -646,7 +646,8 @@ GSF_peer_connect_handler_ (const struct GNUNET_PeerIdentity *peer, | |||
646 | cp->rc = | 646 | cp->rc = |
647 | GNUNET_ATS_reserve_bandwidth (GSF_ats, peer, DBLOCK_SIZE, | 647 | GNUNET_ATS_reserve_bandwidth (GSF_ats, peer, DBLOCK_SIZE, |
648 | &ats_reserve_callback, cp); | 648 | &ats_reserve_callback, cp); |
649 | cp->request_map = GNUNET_CONTAINER_multihashmap_create (128, GNUNET_NO); | 649 | cp->request_map = GNUNET_CONTAINER_multihashmap_create (128, |
650 | GNUNET_YES); | ||
650 | GNUNET_break (GNUNET_OK == | 651 | GNUNET_break (GNUNET_OK == |
651 | GNUNET_CONTAINER_multipeermap_put (cp_map, | 652 | GNUNET_CONTAINER_multipeermap_put (cp_map, |
652 | GSF_connected_peer_get_identity2_ (cp), | 653 | GSF_connected_peer_get_identity2_ (cp), |
@@ -811,8 +812,10 @@ free_pending_request (struct PeerRequest *peerreq, | |||
811 | GNUNET_SCHEDULER_cancel (peerreq->kill_task); | 812 | GNUNET_SCHEDULER_cancel (peerreq->kill_task); |
812 | peerreq->kill_task = NULL; | 813 | peerreq->kill_task = NULL; |
813 | } | 814 | } |
814 | GNUNET_STATISTICS_update (GSF_stats, gettext_noop ("# P2P searches active"), | 815 | GNUNET_STATISTICS_update (GSF_stats, |
815 | -1, GNUNET_NO); | 816 | gettext_noop ("# P2P searches active"), |
817 | -1, | ||
818 | GNUNET_NO); | ||
816 | GNUNET_break (GNUNET_YES == | 819 | GNUNET_break (GNUNET_YES == |
817 | GNUNET_CONTAINER_multihashmap_remove (cp->request_map, | 820 | GNUNET_CONTAINER_multihashmap_remove (cp->request_map, |
818 | query, | 821 | query, |
@@ -1288,6 +1291,7 @@ GSF_handle_p2p_query_ (const struct GNUNET_PeerIdentity *other, | |||
1288 | uint32_t ttl_decrement; | 1291 | uint32_t ttl_decrement; |
1289 | struct TestExistClosure tec; | 1292 | struct TestExistClosure tec; |
1290 | GNUNET_PEER_Id spid; | 1293 | GNUNET_PEER_Id spid; |
1294 | const struct GSF_PendingRequestData *prd; | ||
1291 | 1295 | ||
1292 | msize = ntohs (message->size); | 1296 | msize = ntohs (message->size); |
1293 | if (msize < sizeof (struct GetMessage)) | 1297 | if (msize < sizeof (struct GetMessage)) |
@@ -1452,20 +1456,25 @@ GSF_handle_p2p_query_ (const struct GNUNET_PeerIdentity *other, | |||
1452 | spid, | 1456 | spid, |
1453 | GNUNET_PEER_intern (other), | 1457 | GNUNET_PEER_intern (other), |
1454 | NULL, 0, /* replies_seen */ | 1458 | NULL, 0, /* replies_seen */ |
1455 | &handle_p2p_reply, peerreq); | 1459 | &handle_p2p_reply, |
1460 | peerreq); | ||
1456 | GNUNET_assert (NULL != pr); | 1461 | GNUNET_assert (NULL != pr); |
1462 | prd = GSF_pending_request_get_data_ (pr); | ||
1457 | peerreq->pr = pr; | 1463 | peerreq->pr = pr; |
1458 | GNUNET_break (GNUNET_OK == | 1464 | GNUNET_break (GNUNET_OK == |
1459 | GNUNET_CONTAINER_multihashmap_put (cp->request_map, | 1465 | GNUNET_CONTAINER_multihashmap_put (cp->request_map, |
1460 | &gm->query, | 1466 | &prd->query, |
1461 | peerreq, | 1467 | peerreq, |
1462 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); | 1468 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); |
1463 | GNUNET_STATISTICS_update (GSF_stats, | 1469 | GNUNET_STATISTICS_update (GSF_stats, |
1464 | gettext_noop | 1470 | gettext_noop |
1465 | ("# P2P query messages received and processed"), 1, | 1471 | ("# P2P query messages received and processed"), |
1472 | 1, | ||
1473 | GNUNET_NO); | ||
1474 | GNUNET_STATISTICS_update (GSF_stats, | ||
1475 | gettext_noop ("# P2P searches active"), | ||
1476 | 1, | ||
1466 | GNUNET_NO); | 1477 | GNUNET_NO); |
1467 | GNUNET_STATISTICS_update (GSF_stats, gettext_noop ("# P2P searches active"), | ||
1468 | 1, GNUNET_NO); | ||
1469 | return pr; | 1478 | return pr; |
1470 | } | 1479 | } |
1471 | 1480 | ||
diff --git a/src/fs/gnunet-service-fs_pe.c b/src/fs/gnunet-service-fs_pe.c index ede109c2d..9743d1cb2 100644 --- a/src/fs/gnunet-service-fs_pe.c +++ b/src/fs/gnunet-service-fs_pe.c | |||
@@ -59,7 +59,7 @@ struct PeerPlan; | |||
59 | * to a given plan entry.) | 59 | * to a given plan entry.) |
60 | * | 60 | * |
61 | * Similarly head and tail of the "PR" MDLL are stored | 61 | * Similarly head and tail of the "PR" MDLL are stored |
62 | * with the 'struct GSF_PendingRequest'. (We need | 62 | * with the `struct GSF_PendingRequest`. (We need |
63 | * to be able to lookup all plan entries corresponding | 63 | * to be able to lookup all plan entries corresponding |
64 | * to a given pending request.) | 64 | * to a given pending request.) |
65 | */ | 65 | */ |
@@ -87,12 +87,14 @@ struct GSF_PendingRequestPlanBijection | |||
87 | struct GSF_PendingRequestPlanBijection *prev_PE; | 87 | struct GSF_PendingRequestPlanBijection *prev_PE; |
88 | 88 | ||
89 | /** | 89 | /** |
90 | * Associated request plan. | 90 | * Associated request plan (tells us one of the peers that |
91 | * we plan to forward the request to). | ||
91 | */ | 92 | */ |
92 | struct GSF_RequestPlan *rp; | 93 | struct GSF_RequestPlan *rp; |
93 | 94 | ||
94 | /** | 95 | /** |
95 | * Associated pending request. | 96 | * Associated pending request (identifies request details |
97 | * and one of the origins of the request). | ||
96 | */ | 98 | */ |
97 | struct GSF_PendingRequest *pr; | 99 | struct GSF_PendingRequest *pr; |
98 | 100 | ||
@@ -101,8 +103,8 @@ struct GSF_PendingRequestPlanBijection | |||
101 | 103 | ||
102 | /** | 104 | /** |
103 | * Information we keep per request per peer. This is a doubly-linked | 105 | * Information we keep per request per peer. This is a doubly-linked |
104 | * list (with head and tail in the 'struct GSF_PendingRequestData') | 106 | * list (with head and tail in the `struct GSF_PendingRequestData`) |
105 | * with one entry in each heap of each 'struct PeerPlan'. Each | 107 | * with one entry in each heap of each `struct PeerPlan`. Each |
106 | * entry tracks information relevant for this request and this peer. | 108 | * entry tracks information relevant for this request and this peer. |
107 | */ | 109 | */ |
108 | struct GSF_RequestPlan | 110 | struct GSF_RequestPlan |
@@ -129,7 +131,9 @@ struct GSF_RequestPlan | |||
129 | struct PeerPlan *pp; | 131 | struct PeerPlan *pp; |
130 | 132 | ||
131 | /** | 133 | /** |
132 | * Head of list of associated pending requests. | 134 | * Head of list of associated pending requests. This tells us |
135 | * which incoming requests from other peers this plan entry | ||
136 | * corresponds to. | ||
133 | */ | 137 | */ |
134 | struct GSF_PendingRequestPlanBijection *pe_head; | 138 | struct GSF_PendingRequestPlanBijection *pe_head; |
135 | 139 | ||
@@ -167,19 +171,20 @@ struct GSF_RequestPlan | |||
167 | struct PeerPlan | 171 | struct PeerPlan |
168 | { | 172 | { |
169 | /** | 173 | /** |
170 | * Heap with pending queries (struct GSF_RequestPlan), higher weights mean higher priority. | 174 | * Heap with pending queries (`struct GSF_RequestPlan`), higher weights mean higher priority. |
171 | */ | 175 | */ |
172 | struct GNUNET_CONTAINER_Heap *priority_heap; | 176 | struct GNUNET_CONTAINER_Heap *priority_heap; |
173 | 177 | ||
174 | /** | 178 | /** |
175 | * Heap with pending queries (struct GSF_RequestPlan), by transmission time, lowest first. | 179 | * Heap with pending queries (`struct GSF_RequestPlan`), by transmission time, lowest first. |
176 | */ | 180 | */ |
177 | struct GNUNET_CONTAINER_Heap *delay_heap; | 181 | struct GNUNET_CONTAINER_Heap *delay_heap; |
178 | 182 | ||
179 | /** | 183 | /** |
180 | * Map of queries to plan entries. All entries in the priority_heap or delay_heap | 184 | * Map of queries to plan entries. All entries in the @e priority_heap |
181 | * should be in the plan map. Note that it IS possible for the plan map to have | 185 | * or @e delay_heap should be in the @e plan_map. Note that it is |
182 | * multiple entries for the same query. | 186 | * possible for the @e plan_map to have multiple entries for the same |
187 | * query. | ||
183 | */ | 188 | */ |
184 | struct GNUNET_CONTAINER_MultiHashMap *plan_map; | 189 | struct GNUNET_CONTAINER_MultiHashMap *plan_map; |
185 | 190 | ||
@@ -196,7 +201,7 @@ struct PeerPlan | |||
196 | /** | 201 | /** |
197 | * Current task for executing the plan. | 202 | * Current task for executing the plan. |
198 | */ | 203 | */ |
199 | struct GNUNET_SCHEDULER_Task * task; | 204 | struct GNUNET_SCHEDULER_Task *task; |
200 | }; | 205 | }; |
201 | 206 | ||
202 | 207 | ||
@@ -222,7 +227,7 @@ static unsigned long long plan_count; | |||
222 | * requests for the same key and we just return _one_ of them; this | 227 | * requests for the same key and we just return _one_ of them; this |
223 | * particular one might complete while another one might still be | 228 | * particular one might complete while another one might still be |
224 | * active, hence the lifetime of the returned hash code is NOT | 229 | * active, hence the lifetime of the returned hash code is NOT |
225 | * necessarily identical to that of the 'struct GSF_RequestPlan' | 230 | * necessarily identical to that of the `struct GSF_RequestPlan` |
226 | * given. | 231 | * given. |
227 | * | 232 | * |
228 | * @param rp a request plan | 233 | * @param rp a request plan |
@@ -253,7 +258,8 @@ schedule_peer_transmission (void *cls, | |||
253 | * @param rp request to plan | 258 | * @param rp request to plan |
254 | */ | 259 | */ |
255 | static void | 260 | static void |
256 | plan (struct PeerPlan *pp, struct GSF_RequestPlan *rp) | 261 | plan (struct PeerPlan *pp, |
262 | struct GSF_RequestPlan *rp) | ||
257 | { | 263 | { |
258 | #define N ((double)128.0) | 264 | #define N ((double)128.0) |
259 | /** | 265 | /** |
@@ -366,8 +372,7 @@ get_latest (const struct GSF_RequestPlan *rp) | |||
366 | for (bi = bi->next_PE; NULL != bi; bi = bi->next_PE) | 372 | for (bi = bi->next_PE; NULL != bi; bi = bi->next_PE) |
367 | { | 373 | { |
368 | prd = GSF_pending_request_get_data_ (bi->pr); | 374 | prd = GSF_pending_request_get_data_ (bi->pr); |
369 | if (prd->ttl.abs_value_us > | 375 | if (prd->ttl.abs_value_us > rprd->ttl.abs_value_us) |
370 | rprd->ttl.abs_value_us) | ||
371 | { | 376 | { |
372 | ret = bi->pr; | 377 | ret = bi->pr; |
373 | rprd = prd; | 378 | rprd = prd; |
@@ -383,10 +388,12 @@ get_latest (const struct GSF_RequestPlan *rp) | |||
383 | * @param cls closure | 388 | * @param cls closure |
384 | * @param buf_size number of bytes available in @a buf | 389 | * @param buf_size number of bytes available in @a buf |
385 | * @param buf where to copy the message, NULL on error (peer disconnect) | 390 | * @param buf where to copy the message, NULL on error (peer disconnect) |
386 | * @return number of bytes copied to 'buf', can be 0 (without indicating an error) | 391 | * @return number of bytes copied to @a buf, can be 0 (without indicating an error) |
387 | */ | 392 | */ |
388 | static size_t | 393 | static size_t |
389 | transmit_message_callback (void *cls, size_t buf_size, void *buf) | 394 | transmit_message_callback (void *cls, |
395 | size_t buf_size, | ||
396 | void *buf) | ||
390 | { | 397 | { |
391 | struct PeerPlan *pp = cls; | 398 | struct PeerPlan *pp = cls; |
392 | struct GSF_RequestPlan *rp; | 399 | struct GSF_RequestPlan *rp; |
@@ -414,7 +421,9 @@ transmit_message_callback (void *cls, size_t buf_size, void *buf) | |||
414 | pp->task = GNUNET_SCHEDULER_add_now (&schedule_peer_transmission, pp); | 421 | pp->task = GNUNET_SCHEDULER_add_now (&schedule_peer_transmission, pp); |
415 | return 0; | 422 | return 0; |
416 | } | 423 | } |
417 | msize = GSF_pending_request_get_message_ (get_latest (rp), buf_size, buf); | 424 | msize = GSF_pending_request_get_message_ (get_latest (rp), |
425 | buf_size, | ||
426 | buf); | ||
418 | if (msize > buf_size) | 427 | if (msize > buf_size) |
419 | { | 428 | { |
420 | if (NULL != pp->task) | 429 | if (NULL != pp->task) |
@@ -476,7 +485,8 @@ schedule_peer_transmission (void *cls, | |||
476 | rp = GNUNET_CONTAINER_heap_peek (pp->delay_heap); | 485 | rp = GNUNET_CONTAINER_heap_peek (pp->delay_heap); |
477 | if (NULL == rp) | 486 | if (NULL == rp) |
478 | { | 487 | { |
479 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No active requests for plan %p.\n", | 488 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
489 | "No active requests for plan %p.\n", | ||
480 | pp); | 490 | pp); |
481 | return; /* both queues empty */ | 491 | return; /* both queues empty */ |
482 | } | 492 | } |
@@ -486,11 +496,14 @@ schedule_peer_transmission (void *cls, | |||
486 | GNUNET_STRINGS_relative_time_to_string (delay, | 496 | GNUNET_STRINGS_relative_time_to_string (delay, |
487 | GNUNET_YES), | 497 | GNUNET_YES), |
488 | pp); | 498 | pp); |
489 | GNUNET_STATISTICS_set (GSF_stats, gettext_noop ("# delay heap timeout (ms)"), | 499 | GNUNET_STATISTICS_set (GSF_stats, |
500 | gettext_noop ("# delay heap timeout (ms)"), | ||
490 | delay.rel_value_us / 1000LL, GNUNET_NO); | 501 | delay.rel_value_us / 1000LL, GNUNET_NO); |
491 | 502 | ||
492 | pp->task = | 503 | pp->task = |
493 | GNUNET_SCHEDULER_add_delayed (delay, &schedule_peer_transmission, pp); | 504 | GNUNET_SCHEDULER_add_delayed (delay, |
505 | &schedule_peer_transmission, | ||
506 | pp); | ||
494 | return; | 507 | return; |
495 | } | 508 | } |
496 | #if INSANE_STATISTICS | 509 | #if INSANE_STATISTICS |
@@ -503,8 +516,10 @@ schedule_peer_transmission (void *cls, | |||
503 | GNUNET_assert (NULL != rp); | 516 | GNUNET_assert (NULL != rp); |
504 | msize = GSF_pending_request_get_message_ (get_latest (rp), 0, NULL); | 517 | msize = GSF_pending_request_get_message_ (get_latest (rp), 0, NULL); |
505 | pp->pth = | 518 | pp->pth = |
506 | GSF_peer_transmit_ (pp->cp, GNUNET_YES, rp->priority, | 519 | GSF_peer_transmit_ (pp->cp, GNUNET_YES, |
507 | GNUNET_TIME_UNIT_FOREVER_REL, msize, | 520 | rp->priority, |
521 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
522 | msize, | ||
508 | &transmit_message_callback, pp); | 523 | &transmit_message_callback, pp); |
509 | GNUNET_assert (NULL != pp->pth); | 524 | GNUNET_assert (NULL != pp->pth); |
510 | } | 525 | } |
@@ -516,8 +531,14 @@ schedule_peer_transmission (void *cls, | |||
516 | struct MergeContext | 531 | struct MergeContext |
517 | { | 532 | { |
518 | 533 | ||
534 | /** | ||
535 | * Request we are trying to merge. | ||
536 | */ | ||
519 | struct GSF_PendingRequest *pr; | 537 | struct GSF_PendingRequest *pr; |
520 | 538 | ||
539 | /** | ||
540 | * Set to #GNUNET_YES if we succeeded to merge. | ||
541 | */ | ||
521 | int merged; | 542 | int merged; |
522 | 543 | ||
523 | }; | 544 | }; |
diff --git a/src/fs/gnunet-service-fs_pr.c b/src/fs/gnunet-service-fs_pr.c index b507992b4..21b00e80e 100644 --- a/src/fs/gnunet-service-fs_pr.c +++ b/src/fs/gnunet-service-fs_pr.c | |||
@@ -289,7 +289,8 @@ GSF_pending_request_create_ (enum GSF_PendingRequestOptions options, | |||
289 | enum GNUNET_BLOCK_Type type, | 289 | enum GNUNET_BLOCK_Type type, |
290 | const struct GNUNET_HashCode *query, | 290 | const struct GNUNET_HashCode *query, |
291 | const struct GNUNET_PeerIdentity *target, | 291 | const struct GNUNET_PeerIdentity *target, |
292 | const char *bf_data, size_t bf_size, | 292 | const char *bf_data, |
293 | size_t bf_size, | ||
293 | uint32_t mingle, | 294 | uint32_t mingle, |
294 | uint32_t anonymity_level, | 295 | uint32_t anonymity_level, |
295 | uint32_t priority, | 296 | uint32_t priority, |
@@ -325,7 +326,9 @@ GSF_pending_request_create_ (enum GSF_PendingRequestOptions options, | |||
325 | if (NULL != target) | 326 | if (NULL != target) |
326 | { | 327 | { |
327 | pr->public_data.target = (struct GNUNET_PeerIdentity *) eptr; | 328 | pr->public_data.target = (struct GNUNET_PeerIdentity *) eptr; |
328 | memcpy (eptr, target, sizeof (struct GNUNET_PeerIdentity)); | 329 | memcpy (eptr, |
330 | target, | ||
331 | sizeof (struct GNUNET_PeerIdentity)); | ||
329 | } | 332 | } |
330 | pr->public_data.anonymity_level = anonymity_level; | 333 | pr->public_data.anonymity_level = anonymity_level; |
331 | pr->public_data.priority = priority; | 334 | pr->public_data.priority = priority; |
@@ -397,7 +400,9 @@ GSF_pending_request_create_ (enum GSF_PendingRequestOptions options, | |||
397 | UINT32_MAX, | 400 | UINT32_MAX, |
398 | GNUNET_TIME_UNIT_FOREVER_ABS, | 401 | GNUNET_TIME_UNIT_FOREVER_ABS, |
399 | GNUNET_TIME_UNIT_FOREVER_ABS, | 402 | GNUNET_TIME_UNIT_FOREVER_ABS, |
400 | GNUNET_BLOCK_TYPE_ANY, NULL, 0); | 403 | GNUNET_BLOCK_TYPE_ANY, |
404 | NULL, | ||
405 | 0); | ||
401 | GSF_pending_request_cancel_ (dpr, | 406 | GSF_pending_request_cancel_ (dpr, |
402 | GNUNET_YES); | 407 | GNUNET_YES); |
403 | } | 408 | } |
diff --git a/src/fs/gnunet-service-fs_pr.h b/src/fs/gnunet-service-fs_pr.h index d022d8640..547595b67 100644 --- a/src/fs/gnunet-service-fs_pr.h +++ b/src/fs/gnunet-service-fs_pr.h | |||
@@ -179,25 +179,22 @@ struct GSF_PendingRequestData | |||
179 | * @param eval evaluation of the result | 179 | * @param eval evaluation of the result |
180 | * @param pr handle to the original pending request | 180 | * @param pr handle to the original pending request |
181 | * @param reply_anonymity_level anonymity level for the reply, UINT32_MAX for "unknown" | 181 | * @param reply_anonymity_level anonymity level for the reply, UINT32_MAX for "unknown" |
182 | * @param expiration when does 'data' expire? | 182 | * @param expiration when does @a data expire? |
183 | * @param last_transmission the last time we've tried to get this block (FOREVER if unknown) | 183 | * @param last_transmission the last time we've tried to get this block (FOREVER if unknown) |
184 | * @param type type of the block | 184 | * @param type type of the block |
185 | * @param data response data, NULL on request expiration | 185 | * @param data response data, NULL on request expiration |
186 | * @param data_len number of bytes in data | 186 | * @param data_len number of bytes in @a data |
187 | */ | 187 | */ |
188 | typedef void (*GSF_PendingRequestReplyHandler) (void *cls, | 188 | typedef void |
189 | enum | 189 | (*GSF_PendingRequestReplyHandler) (void *cls, |
190 | GNUNET_BLOCK_EvaluationResult | 190 | enum GNUNET_BLOCK_EvaluationResult eval, |
191 | eval, | 191 | struct GSF_PendingRequest *pr, |
192 | struct GSF_PendingRequest * pr, | 192 | uint32_t reply_anonymity_level, |
193 | uint32_t reply_anonymity_level, | 193 | struct GNUNET_TIME_Absolute expiration, |
194 | struct GNUNET_TIME_Absolute | 194 | struct GNUNET_TIME_Absolute last_transmission, |
195 | expiration, | 195 | enum GNUNET_BLOCK_Type type, |
196 | struct GNUNET_TIME_Absolute | 196 | const void *data, |
197 | last_transmission, | 197 | size_t data_len); |
198 | enum GNUNET_BLOCK_Type type, | ||
199 | const void *data, | ||
200 | size_t data_len); | ||
201 | 198 | ||
202 | 199 | ||
203 | /** | 200 | /** |