GNUnet  0.10.x
Data Structures | Macros | Functions
fragmentation.c File Reference

library to help fragment messages More...

#include "platform.h"
#include "gnunet_fragmentation_lib.h"
#include "gnunet_protocols.h"
#include "fragmentation.h"
Include dependency graph for fragmentation.c:

Go to the source code of this file.

Data Structures

struct  GNUNET_FRAGMENT_Context
 Fragmentation context. More...


 Absolute minimum delay we impose between sending and expecting ACK to arrive. More...


const char * GNUNET_FRAGMENT_print_ack (const struct GNUNET_MessageHeader *ack)
 Convert an ACK message to a printable format suitable for logging. More...
static void transmit_next (void *cls)
 Transmit the next fragment to the other peer. More...
struct GNUNET_FRAGMENT_ContextGNUNET_FRAGMENT_context_create (struct GNUNET_STATISTICS_Handle *stats, uint16_t mtu, struct GNUNET_BANDWIDTH_Tracker *tracker, struct GNUNET_TIME_Relative msg_delay, struct GNUNET_TIME_Relative ack_delay, const struct GNUNET_MessageHeader *msg, GNUNET_FRAGMENT_MessageProcessor proc, void *proc_cls)
 Create a fragmentation context for the given message. More...
void GNUNET_FRAGMENT_context_transmission_done (struct GNUNET_FRAGMENT_Context *fc)
 Continuation to call from the 'proc' function after the fragment has been transmitted (and hence the next fragment can now be given to proc). More...
int GNUNET_FRAGMENT_process_ack (struct GNUNET_FRAGMENT_Context *fc, const struct GNUNET_MessageHeader *msg)
 Process an acknowledgement message we got from the other side (to control re-transmits). More...
void GNUNET_FRAGMENT_context_destroy (struct GNUNET_FRAGMENT_Context *fc, struct GNUNET_TIME_Relative *msg_delay, struct GNUNET_TIME_Relative *ack_delay)
 Destroy the given fragmentation context (stop calling 'proc', free resources). More...

Detailed Description

library to help fragment messages

Christian Grothoff

Definition in file fragmentation.c.

Macro Definition Documentation


Absolute minimum delay we impose between sending and expecting ACK to arrive.

Definition at line 34 of file fragmentation.c.

Referenced by transmit_next().

Function Documentation

◆ transmit_next()

static void transmit_next ( void *  cls)

Transmit the next fragment to the other peer.

clsthe struct GNUNET_FRAGMENT_Context

Definition at line 170 of file fragmentation.c.

References _, GNUNET_TIME_Absolute::abs_value_us, GNUNET_FRAGMENT_Context::ack_delay, GNUNET_FRAGMENT_Context::acks, GNUNET_FRAGMENT_Context::delay_until, fh, FragmentHeader::fragment_id, GNUNET_FRAGMENT_Context::fragment_id, GNUNET_assert, GNUNET_BANDWIDTH_tracker_consume(), GNUNET_BANDWIDTH_tracker_get_delay(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_FRAGMENT, GNUNET_NO, GNUNET_SCHEDULER_add_delayed(), GNUNET_STATISTICS_update(), GNUNET_STRINGS_relative_time_to_string(), GNUNET_TIME_absolute_get(), GNUNET_TIME_relative_max(), GNUNET_TIME_relative_saturating_multiply(), GNUNET_TIME_relative_to_absolute(), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_TIME_UNIT_ZERO, GNUNET_YES, FragmentHeader::header, GNUNET_FRAGMENT_Context::last_round, MIN_ACK_DELAY, GNUNET_FRAGMENT_Context::msg, GNUNET_FRAGMENT_Context::msg_delay, GNUNET_FRAGMENT_Context::mtu, GNUNET_FRAGMENT_Context::next_transmission, GNUNET_FRAGMENT_Context::num_rounds, GNUNET_FRAGMENT_Context::num_transmissions, FragmentHeader::offset, GNUNET_FRAGMENT_Context::proc, GNUNET_FRAGMENT_Context::proc_busy, GNUNET_FRAGMENT_Context::proc_cls, GNUNET_TIME_Relative::rel_value_us, size, GNUNET_MessageHeader::size, GNUNET_FRAGMENT_Context::stats, GNUNET_FRAGMENT_Context::task, FragmentHeader::total_size, GNUNET_FRAGMENT_Context::tracker, GNUNET_MessageHeader::type, and GNUNET_FRAGMENT_Context::wack.

Referenced by GNUNET_FRAGMENT_context_create(), GNUNET_FRAGMENT_context_transmission_done(), and GNUNET_FRAGMENT_process_ack().

171 {
172  struct GNUNET_FRAGMENT_Context *fc = cls;
173  char msg[fc->mtu];
174  const char *mbuf;
175  struct FragmentHeader *fh;
177  unsigned int bit;
178  size_t size;
179  size_t fsize;
180  int wrap;
182  fc->task = NULL;
184  if (0 == fc->acks)
185  return; /* all done */
186  /* calculate delay */
187  wrap = 0;
188  while (0 == (fc->acks & (1LLU << fc->next_transmission)))
189  {
190  fc->next_transmission = (fc->next_transmission + 1) % 64;
191  wrap |= (0 == fc->next_transmission);
192  }
193  bit = fc->next_transmission;
194  size = ntohs(fc->msg->size);
195  if (bit == size / (fc->mtu - sizeof(struct FragmentHeader)))
196  fsize =
197  (size % (fc->mtu - sizeof(struct FragmentHeader))) +
198  sizeof(struct FragmentHeader);
199  else
200  fsize = fc->mtu;
201  if (NULL != fc->tracker)
203  fsize);
204  else
206  if (delay.rel_value_us > 0)
207  {
209  "Fragmentation logic delays transmission of next fragment by %s\n",
211  GNUNET_YES));
213  &transmit_next,
214  fc);
215  return;
216  }
217  fc->next_transmission = (fc->next_transmission + 1) % 64;
218  wrap |= (0 == fc->next_transmission);
219  while (0 == (fc->acks & (1LLU << fc->next_transmission)))
220  {
221  fc->next_transmission = (fc->next_transmission + 1) % 64;
222  wrap |= (0 == fc->next_transmission);
223  }
225  /* assemble fragmentation message */
226  mbuf = (const char *)&fc[1];
227  fh = (struct FragmentHeader *)msg;
228  fh->header.size = htons(fsize);
230  fh->fragment_id = htonl(fc->fragment_id);
231  fh->total_size = fc->msg->size; /* already in big-endian */
232  fh->offset = htons((fc->mtu - sizeof(struct FragmentHeader)) * bit);
233  GNUNET_memcpy(&fh[1], &mbuf[bit * (fc->mtu - sizeof(struct FragmentHeader))],
234  fsize - sizeof(struct FragmentHeader));
235  if (NULL != fc->tracker)
238  _("# fragments transmitted"),
239  1,
240  GNUNET_NO);
241  if (0 != fc->last_round.abs_value_us)
243  _("# fragments retransmitted"),
244  1,
245  GNUNET_NO);
247  /* select next message to calculate delay */
248  bit = fc->next_transmission;
249  size = ntohs(fc->msg->size);
250  if (bit == size / (fc->mtu - sizeof(struct FragmentHeader)))
251  fsize = size % (fc->mtu - sizeof(struct FragmentHeader));
252  else
253  fsize = fc->mtu;
254  if (NULL != fc->tracker)
256  fsize);
257  else
259  if (fc->num_rounds < 64)
262  (fc->msg_delay,
263  (1ULL << fc->num_rounds)));
264  else
266  if (wrap)
267  {
268  /* full round transmitted wait 2x delay for ACK before going again */
269  fc->num_rounds++;
271  /* never use zero, need some time for ACK always */
273  fc->wack = GNUNET_YES;
276  _("# fragments wrap arounds"),
277  1,
278  GNUNET_NO);
279  }
280  fc->proc_busy = GNUNET_YES;
282  fc->num_transmissions++;
283  fc->proc(fc->proc_cls,
284  &fh->header);
285 }
unsigned int num_rounds
How many rounds of transmission have we completed so far?
uint64_t acks
Bitfield, set to 1 for each unacknowledged fragment.
Definition: fragmentation.c:89
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_MessageHeader header
Message header.
Definition: fragmentation.h:40
int GNUNET_BANDWIDTH_tracker_consume(struct GNUNET_BANDWIDTH_Tracker *av, ssize_t size)
Notify the tracker that a certain number of bytes of bandwidth have been consumed.
Definition: bandwidth.c:402
uint32_t fragment_id
Unique fragment ID.
Definition: fragmentation.h:45
struct GNUNET_SCHEDULER_Task * task
Task performing work for the fragmenter.
uint64_t rel_value_us
The actual value.
struct GNUNET_TIME_Absolute last_round
Time we transmitted the last message of the last round.
Definition: fragmentation.c:69
struct GNUNET_TIME_Relative GNUNET_TIME_relative_max(struct GNUNET_TIME_Relative t1, struct GNUNET_TIME_Relative t2)
Return the maximum of two relative time values.
Definition: time.c:287
struct GNUNET_STATISTICS_Handle * stats
Statistics to use.
Definition: fragmentation.c:44
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:246
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_TIME_Relative msg_delay
Current expected delay between messages.
Definition: fragmentation.c:59
GNUNET_FRAGMENT_MessageProcessor proc
Function to call for transmissions.
Definition: fragmentation.c:79
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
uint16_t total_size
Total message size of the original message.
Definition: fragmentation.h:50
#define GNUNET_NO
Definition: gnunet_common.h:78
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
uint64_t abs_value_us
The actual value.
int8_t proc_busy
GNUNET_YES if we called proc and are now waiting for GNUNET_FRAGMENT_context_transmission_done() ...
struct GNUNET_BANDWIDTH_Tracker * tracker
Tracker for flow control.
Definition: fragmentation.c:49
void * proc_cls
Closure for proc.
Definition: fragmentation.c:84
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
uint16_t mtu
Target fragment size.
uint32_t fragment_id
Our fragmentation ID.
Fragmentation context.
Definition: fragmentation.c:40
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:1237
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
unsigned int num_transmissions
How many transmission have we completed in this round?
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:686
static void transmit_next(void *cls)
Transmit the next fragment to the other peer.
Constant used to specify "forever".
static int fh
Handle to the unique file.
const struct GNUNET_MessageHeader * msg
Message to fragment (allocated at the end of this struct).
Definition: fragmentation.c:74
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
struct GNUNET_TIME_Relative GNUNET_BANDWIDTH_tracker_get_delay(struct GNUNET_BANDWIDTH_Tracker *av, size_t size)
Compute how long we should wait until consuming size bytes of bandwidth in order to stay within the g...
Definition: bandwidth.c:458
static unsigned int size
Size of the "table".
Definition: peer.c:66
uint16_t offset
Absolute offset (in bytes) of this fragment in the original message.
Definition: fragmentation.h:56
static struct GNUNET_TIME_Relative delay
When should dkg communication start?
Relative time zero.
int8_t wack
GNUNET_YES if we are waiting for an ACK.
#define GNUNET_log(kind,...)
struct GNUNET_TIME_Relative ack_delay
Current expected delay for ACKs.
Definition: fragmentation.c:54
#define GNUNET_YES
Definition: gnunet_common.h:77
Absolute minimum delay we impose between sending and expecting ACK to arrive.
Definition: fragmentation.c:34
unsigned int next_transmission
Round-robin selector for the next transmission.
FRAGMENT of a larger message.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_saturating_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Saturating multiply relative time by a given factor.
Definition: time.c:499
struct GNUNET_TIME_Absolute delay_until
Next allowed transmission time.
Definition: fragmentation.c:64
Time for relative time used by GNUnet, in microseconds.
Header for a message fragment.
Definition: fragmentation.h:36
Here is the call graph for this function:
Here is the caller graph for this function: