GNUnet 0.21.1
gnunet-service-fs_cadet_client.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2012, 2013 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
30#include "platform.h"
31#include "gnunet_constants.h"
32#include "gnunet_util_lib.h"
34#include "gnunet_protocols.h"
35#include "gnunet_applications.h"
36#include "gnunet-service-fs.h"
39
40
44#define CLIENT_RETRY_TIMEOUT \
45 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
46
47
51struct CadetHandle;
52
53
58{
63
68
72 struct CadetHandle *mh;
73
78
82 void *proc_cls;
83
88
93
99};
100
101
106{
111
116
122
127
132
139
146};
147
148
153
159
160
161/* ********************* client-side code ************************* */
162
163
169static void
170transmit_pending (void *cls);
171
172
182static int
183move_to_pending (void *cls, const struct GNUNET_HashCode *key, void *value)
184{
185 struct CadetHandle *mh = cls;
186 struct GSF_CadetRequest *sr = value;
187
189 GNUNET_YES ==
191 GNUNET_CONTAINER_DLL_insert (mh->pending_head, mh->pending_tail, sr);
193 return GNUNET_YES;
194}
195
196
205static int
206check_reply (void *cls, const struct CadetReplyMessage *srm)
207{
208 /* We check later... */
209 return GNUNET_OK;
210}
211
212
218static void
219reset_cadet_task (void *cls);
220
221
228static void
230{
231 if (NULL != mh->reset_task)
232 GNUNET_SCHEDULER_cancel (mh->reset_task);
234}
235
236
241{
245 const void *data;
246
251
255 size_t data_size;
256
261
265 int found;
266};
267
268
278static int
279process_reply (void *cls, const struct GNUNET_HashCode *key, void *value)
280{
281 struct HandleReplyClosure *hrc = cls;
282 struct GSF_CadetRequest *sr = value;
283
284 sr->proc (sr->proc_cls,
285 hrc->type,
286 hrc->expiration,
287 hrc->data_size,
288 hrc->data);
289 sr->proc = NULL;
291 hrc->found = GNUNET_YES;
292 return GNUNET_YES;
293}
294
295
306static int
307free_waiting_entry (void *cls, const struct GNUNET_HashCode *key, void *value)
308{
309 struct GSF_CadetRequest *sr = value;
310
312 return GNUNET_YES;
313}
314
315
323static void
324handle_reply (void *cls, const struct CadetReplyMessage *srm)
325{
326 struct CadetHandle *mh = cls;
327 struct HandleReplyClosure hrc;
328 uint16_t msize;
330 struct GNUNET_HashCode query;
331
332 msize = ntohs (srm->header.size) - sizeof(struct CadetReplyMessage);
333 type = (enum GNUNET_BLOCK_Type) ntohl (srm->type);
334 if (GNUNET_YES !=
335 GNUNET_BLOCK_get_key (GSF_block_ctx, type, &srm[1], msize, &query))
336 {
337 GNUNET_break_op (0);
338 GNUNET_log (
340 "Received bogus reply of type %u with %u bytes via cadet from peer %s\n",
341 type,
342 msize,
343 GNUNET_i2s (&mh->target));
345 return;
346 }
348 "Received reply `%s' via cadet from peer %s\n",
349 GNUNET_h2s (&query),
350 GNUNET_i2s (&mh->target));
351 GNUNET_CADET_receive_done (mh->channel);
353 gettext_noop ("# replies received via cadet"),
354 1,
355 GNUNET_NO);
356 hrc.data = &srm[1];
357 hrc.data_size = msize;
359 hrc.type = type;
360 hrc.found = GNUNET_NO;
362 &query,
364 &hrc);
365 if (GNUNET_NO == hrc.found)
366 {
369 "# replies received via cadet dropped"),
370 1,
371 GNUNET_NO);
372 }
373}
374
375
383static void
384disconnect_cb (void *cls, const struct GNUNET_CADET_Channel *channel)
385{
386 struct CadetHandle *mh = cls;
387 struct GSF_CadetRequest *sr;
388
389 if (NULL == mh->channel)
390 return; /* being destroyed elsewhere */
391 GNUNET_assert (channel == mh->channel);
392 mh->channel = NULL;
393 while (NULL != (sr = mh->pending_head))
395 /* first remove `mh` from the `cadet_map`, so that if the
396 callback from `free_waiting_entry()` happens to re-issue
397 the request, we don't immediately have it back in the
398 `waiting_map`. */
400 &mh->target,
401 mh));
404 mh);
405 if (NULL != mh->timeout_task)
406 GNUNET_SCHEDULER_cancel (mh->timeout_task);
407 if (NULL != mh->reset_task)
408 GNUNET_SCHEDULER_cancel (mh->reset_task);
411 GNUNET_free (mh);
412}
413
414
429static void
431 const struct GNUNET_CADET_Channel *channel,
432 int window_size)
433{
434 /* FIXME: for flow control, implement? */
435#if 0
436 /* Something like this instead of the GNUNET_MQ_notify_sent() in
437 transmit_pending() might be good (once the window change CB works...) */
438 if (0 < window_size) /* test needed? */
440#endif
441}
442
443
449static void
451{
453 "Resetting cadet channel to %s\n",
454 GNUNET_i2s (&mh->target));
455 if (NULL != mh->channel)
456 {
458 mh->channel = NULL;
459 }
461 {
463 { GNUNET_MQ_hd_var_size (reply,
465 struct CadetReplyMessage,
466 mh),
468 struct GNUNET_HashCode port;
469
472 &port);
474 mh,
475 &mh->target,
476 &port,
479 handlers);
480 }
482}
483
484
490static void
491cadet_timeout (void *cls)
492{
493 struct CadetHandle *mh = cls;
494 struct GNUNET_CADET_Channel *tun;
495
497 "Timeout on cadet channel to %s\n",
498 GNUNET_i2s (&mh->target));
499 mh->timeout_task = NULL;
500 tun = mh->channel;
501 mh->channel = NULL;
502 if (NULL != tun)
504}
505
506
512static void
514{
515 struct CadetHandle *mh = cls;
516
517 mh->reset_task = NULL;
518 reset_cadet (mh);
519}
520
521
527static void
529{
530 struct CadetHandle *mh = cls;
531 struct GNUNET_MQ_Handle *mq = GNUNET_CADET_get_mq (mh->channel);
532 struct GSF_CadetRequest *sr;
533 struct GNUNET_MQ_Envelope *env;
534 struct CadetQueryMessage *sqm;
535
536 if ((0 != GNUNET_MQ_get_length (mq)) || (NULL == (sr = mh->pending_head)))
537 return;
538 GNUNET_CONTAINER_DLL_remove (mh->pending_head, mh->pending_tail, sr);
540 mh->waiting_map,
541 &sr->query,
542 sr,
546 "Sending query for %s via cadet to %s\n",
547 GNUNET_h2s (&sr->query),
548 GNUNET_i2s (&mh->target));
554 sqm->type = htonl (sr->type);
555 sqm->query = sr->query;
558}
559
560
566static struct CadetHandle *
568{
569 struct CadetHandle *mh;
570
572 if (NULL != mh)
573 {
574 if (NULL != mh->timeout_task)
575 {
576 GNUNET_SCHEDULER_cancel (mh->timeout_task);
577 mh->timeout_task = NULL;
578 }
579 return mh;
580 }
582 "Creating cadet channel to %s\n",
584 mh = GNUNET_new (struct CadetHandle);
585 mh->reset_task =
588 mh->target = *target;
591 cadet_map,
592 &mh->target,
593 mh,
595 {
597 { GNUNET_MQ_hd_var_size (reply,
599 struct CadetReplyMessage,
600 mh),
602 struct GNUNET_HashCode port;
603
606 &port);
608 mh,
609 &mh->target,
610 &port,
613 handlers);
614 }
615 return mh;
616}
617
618
629struct GSF_CadetRequest *
631 const struct GNUNET_HashCode *query,
634 void *proc_cls)
635{
636 struct CadetHandle *mh;
637 struct GSF_CadetRequest *sr;
638
640 "Preparing to send query for %s via cadet to %s\n",
642 GNUNET_i2s (target));
643 mh = get_cadet (target);
644 sr = GNUNET_new (struct GSF_CadetRequest);
645 sr->mh = mh;
646 sr->proc = proc;
647 sr->proc_cls = proc_cls;
648 sr->type = type;
649 sr->query = *query;
650 GNUNET_CONTAINER_DLL_insert (mh->pending_head, mh->pending_tail, sr);
652 return sr;
653}
654
655
662void
664{
665 struct CadetHandle *mh = sr->mh;
667
668 p = sr->proc;
669 sr->proc = NULL;
670 if (NULL != p)
671 {
672 /* signal failure / cancellation to callback */
674 }
676 "Cancelled query for %s via cadet to %s\n",
677 GNUNET_h2s (&sr->query),
678 GNUNET_i2s (&sr->mh->target));
679 if (GNUNET_YES == sr->was_transmitted)
681 GNUNET_OK ==
682 GNUNET_CONTAINER_multihashmap_remove (mh->waiting_map, &sr->query, sr));
683 else
684 GNUNET_CONTAINER_DLL_remove (mh->pending_head, mh->pending_tail, sr);
685 GNUNET_free (sr);
686 if ((0 == GNUNET_CONTAINER_multihashmap_size (mh->waiting_map)) &&
687 (NULL == mh->pending_head))
690 mh);
691}
692
693
702int
704 const struct GNUNET_PeerIdentity *key,
705 void *value)
706{
707 struct CadetHandle *mh = value;
708
710 "Timeout on cadet channel to %s\n",
711 GNUNET_i2s (&mh->target));
712 if (NULL != mh->channel)
713 {
714 struct GNUNET_CADET_Channel *channel = mh->channel;
715
716 mh->channel = NULL;
718 }
719 if (NULL != mh->reset_task)
720 {
721 GNUNET_SCHEDULER_cancel (mh->reset_task);
722 mh->reset_task = NULL;
723 }
724 return GNUNET_YES;
725}
726
727
728/* end of gnunet-service-fs_cadet_client.c */
struct GNUNET_MQ_MessageHandlers handlers[]
Definition: 003.c:1
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
#define gettext_noop(String)
Definition: gettext.h:70
static uint16_t port
Port number.
Definition: gnunet-bcd.c:147
static struct GNUNET_CADET_Handle * mh
Cadet handle.
Definition: gnunet-cadet.c:92
struct GNUNET_HashCode key
The key used in the DHT.
static char * value
Value of the record to add/remove.
static uint32_t type
Type string converted to DNS type value.
struct GNUNET_BLOCK_Context * GSF_block_ctx
Our block context.
struct GNUNET_STATISTICS_Handle * GSF_stats
Handle for reporting statistics.
shared data structures of gnunet-service-fs.c
non-anonymous file-transfer
void(* GSF_CadetReplyProcessor)(void *cls, enum GNUNET_BLOCK_Type type, struct GNUNET_TIME_Absolute expiration, size_t data_size, const void *data)
Function called with a reply from the cadet.
static void disconnect_cb(void *cls, const struct GNUNET_CADET_Channel *channel)
Function called by cadet when a client disconnects.
struct GSF_CadetRequest * GSF_cadet_query(const struct GNUNET_PeerIdentity *target, const struct GNUNET_HashCode *query, enum GNUNET_BLOCK_Type type, GSF_CadetReplyProcessor proc, void *proc_cls)
Look for a block by directly contacting a particular peer.
static void handle_reply(void *cls, const struct CadetReplyMessage *srm)
Functions with this signature are called whenever a complete reply is received.
static void transmit_pending(void *cls)
Transmit pending requests via the cadet.
static void window_change_cb(void *cls, const struct GNUNET_CADET_Channel *channel, int window_size)
Function called whenever an MQ-channel's transmission window size changes.
struct GNUNET_CONTAINER_MultiPeerMap * cadet_map
Map from peer identities to 'struct CadetHandles' with cadet channels to those peers.
void GSF_cadet_query_cancel(struct GSF_CadetRequest *sr)
Cancel an active request; must not be called after 'proc' was called.
static struct CadetHandle * get_cadet(const struct GNUNET_PeerIdentity *target)
Get (or create) a cadet to talk to the given peer.
static int check_reply(void *cls, const struct CadetReplyMessage *srm)
Functions with this signature are called whenever a complete reply is received.
static void reset_cadet_task(void *cls)
Task called when it is time to reset an cadet.
int GSF_cadet_release_clients(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Function called on each active cadets to shut them down.
static void reset_cadet(struct CadetHandle *mh)
We had a serious error, tear down and re-create cadet from scratch.
struct GNUNET_CADET_Handle * cadet_handle
Cadet channel for creating outbound channels.
static int process_reply(void *cls, const struct GNUNET_HashCode *key, void *value)
Iterator called on each entry in a waiting map to process a result.
static void reset_cadet_async(struct CadetHandle *mh)
We had a serious error, tear down and re-create cadet from scratch, but do so asynchronously.
#define CLIENT_RETRY_TIMEOUT
After how long do we reset connections without replies?
static int free_waiting_entry(void *cls, const struct GNUNET_HashCode *key, void *value)
Iterator called on each entry in a waiting map to call the 'proc' continuation and release associated...
static int move_to_pending(void *cls, const struct GNUNET_HashCode *key, void *value)
Iterator called on each entry in a waiting map to move it back to the pending list.
static void cadet_timeout(void *cls)
Task called when it is time to destroy an inactive cadet channel.
indexing for the file-sharing service
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-uri.c:38
Constants for network applications operating on top of the CADET service.
CADET service; establish channels to distant peers.
Constants for network protocols.
#define GNUNET_APPLICATION_PORT_FS_BLOCK_TRANSFER
Transfer of blocks for non-anonymmous file-sharing.
enum GNUNET_GenericReturnValue GNUNET_BLOCK_get_key(struct GNUNET_BLOCK_Context *ctx, enum GNUNET_BLOCK_Type type, const void *block, size_t block_size, struct GNUNET_HashCode *key)
Function called to obtain the key for a block.
Definition: block.c:276
void GNUNET_CADET_receive_done(struct GNUNET_CADET_Channel *channel)
Indicate readiness to receive the next message on a channel.
Definition: cadet_api.c:872
void GNUNET_CADET_channel_destroy(struct GNUNET_CADET_Channel *channel)
Destroy an existing channel.
Definition: cadet_api.c:830
struct GNUNET_MQ_Handle * GNUNET_CADET_get_mq(const struct GNUNET_CADET_Channel *channel)
Obtain the message queue for a connected channel.
Definition: cadet_api.c:1066
struct GNUNET_CADET_Channel * GNUNET_CADET_channel_create(struct GNUNET_CADET_Handle *h, void *channel_cls, const struct GNUNET_PeerIdentity *destination, const struct GNUNET_HashCode *port, GNUNET_CADET_WindowSizeEventHandler window_changes, GNUNET_CADET_DisconnectEventHandler disconnects, const struct GNUNET_MQ_MessageHandler *handlers)
Create a new channel towards a remote peer.
Definition: cadet_api.c:1015
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41
void * GNUNET_CONTAINER_multipeermap_get(const struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key)
Given a key find a value in the map matching the key.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
unsigned int GNUNET_CONTAINER_multihashmap_size(const struct GNUNET_CONTAINER_MultiHashMap *map)
Get the number of key-value pairs in the map.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_get_multiple(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map that match a particular key.
int GNUNET_CONTAINER_multipeermap_put(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multipeermap_remove(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, const void *value)
Remove the given key-value pair from the map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE
Allow multiple values with the same key.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY
There must only be one value per key; storing a value should fail if a value under the same key alrea...
#define GNUNET_log(kind,...)
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_MQ_env_set_options(struct GNUNET_MQ_Envelope *env, enum GNUNET_MQ_PriorityPreferences pp)
Set application-specific options for this envelope.
Definition: mq.c:830
unsigned int GNUNET_MQ_get_length(struct GNUNET_MQ_Handle *mq)
Obtain the current length of the message queue.
Definition: mq.c:293
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:304
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:78
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
void GNUNET_MQ_notify_sent(struct GNUNET_MQ_Envelope *ev, GNUNET_SCHEDULER_TaskCallback cb, void *cb_cls)
Call a callback once the envelope has been sent, that is, sending it can not be canceled anymore.
Definition: mq.c:638
@ GNUNET_MQ_PREF_OUT_OF_ORDER
Flag to indicate that out-of-order delivery is OK.
@ GNUNET_MQ_PREF_CORK_ALLOWED
Flag to indicate that CORKing is acceptable.
@ GNUNET_MQ_PREF_GOODPUT
Flag to indicate that high bandwidth is desired.
#define GNUNET_MESSAGE_TYPE_FS_CADET_QUERY
P2P request for content (one FS to another via a cadet).
#define GNUNET_MESSAGE_TYPE_FS_CADET_REPLY
P2P answer for content (one FS to another via a cadet).
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:981
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1305
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1278
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
#define GNUNET_TIME_UNIT_SECONDS
One second.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:737
#define GNUNET_TIME_UNIT_ZERO_ABS
Absolute time zero.
GNUNET_BLOCK_Type
WARNING: This header is generated! In order to add DHT block types, you must register them in GANA,...
@ GNUNET_BLOCK_TYPE_ANY
Identifier for any block.
Handle for a cadet to another peer.
struct GNUNET_SCHEDULER_Task * reset_task
Task to reset cadets that had errors (asynchronously, as we may not be able to do it immediately duri...
struct GNUNET_CONTAINER_MultiHashMap * waiting_map
Map from query to struct GSF_CadetRequests waiting for a reply.
struct GNUNET_SCHEDULER_Task * timeout_task
Task to kill inactive cadets (we keep them around for a few seconds to give the application a chance ...
struct GSF_CadetRequest * pending_head
Head of DLL of pending requests on this cadet.
struct GNUNET_CADET_Channel * channel
Channel to the other peer.
struct GNUNET_PeerIdentity target
Which peer does this cadet go to?
struct GSF_CadetRequest * pending_tail
Tail of DLL of pending requests on this cadet.
Query from one peer, asking the other for CHK-data.
struct GNUNET_HashCode query
Query hash from CHK (hash of encrypted block).
uint32_t type
Block type must be DBLOCK or IBLOCK.
Reply to a CadetQueryMessage.
struct GNUNET_TIME_AbsoluteNBO expiration
Expiration time for the block.
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_FS_CADET_REPLY.
uint32_t type
Block type must be DBLOCK or IBLOCK.
Opaque handle to a channel.
Definition: cadet.h:116
Opaque handle to the service.
Definition: cadet_api.c:39
Internal representation of the hash map.
Internal representation of the hash map.
A 512-bit hashcode.
Handle to a message queue.
Definition: mq.c:87
Message handler for a specific message type.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
The identity of the host (wraps the signing key of the peer).
Entry in list of pending tasks.
Definition: scheduler.c:136
Time for absolute times used by GNUnet, in microseconds.
Handle for a request that is going out via cadet API.
void * proc_cls
Closure for proc.
enum GNUNET_BLOCK_Type type
Desired type for the reply.
struct CadetHandle * mh
Which cadet is this request associated with?
int was_transmitted
Did we transmit this request already? GNUNET_YES if we are in the 'waiting_map', GNUNET_NO if we are ...
GSF_CadetReplyProcessor proc
Function to call with the result.
struct GSF_CadetRequest * next
DLL.
struct GSF_CadetRequest * prev
DLL.
struct GNUNET_HashCode query
Query to transmit to the other peer.
Closure for handle_reply().
enum GNUNET_BLOCK_Type type
Type of the block.
const void * data
Reply payload.
int found
Did we have a matching query?
size_t data_size
Number of bytes in data.
struct GNUNET_TIME_Absolute expiration
Expiration time for the block.