GNUnet  0.20.0
fragmentation.c File Reference

library to help fragment messages More...

#include "platform.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


One millisecond.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Multiply relative time by a given factor.
Definition: time.c:484

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

Definition at line 33 of file fragmentation.c.

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 171 of file fragmentation.c.

172 {
173  struct GNUNET_FRAGMENT_Context *fc = cls;
174  char msg[fc->mtu];
175  const char *mbuf;
176  struct FragmentHeader *fh;
178  unsigned int bit;
179  size_t size;
180  size_t fsize;
181  int wrap;
183  fc->task = NULL;
185  if (0 == fc->acks)
186  return; /* all done */
187  /* calculate delay */
188  wrap = 0;
189  while (0 == (fc->acks & (1LLU << fc->next_transmission)))
190  {
191  fc->next_transmission = (fc->next_transmission + 1) % 64;
192  wrap |= (0 == fc->next_transmission);
193  }
194  bit = fc->next_transmission;
195  size = ntohs (fc->msg->size);
196  if (bit == size / (fc->mtu - sizeof(struct FragmentHeader)))
197  fsize =
198  (size % (fc->mtu - sizeof(struct FragmentHeader)))
199  + sizeof(struct FragmentHeader);
200  else
201  fsize = fc->mtu;
202  if (NULL != fc->tracker)
204  fsize);
205  else
207  if (delay.rel_value_us > 0)
208  {
210  "Fragmentation logic delays transmission of next fragment by %s\n",
212  GNUNET_YES));
214  &transmit_next,
215  fc);
216  return;
217  }
218  fc->next_transmission = (fc->next_transmission + 1) % 64;
219  wrap |= (0 == fc->next_transmission);
220  while (0 == (fc->acks & (1LLU << fc->next_transmission)))
221  {
222  fc->next_transmission = (fc->next_transmission + 1) % 64;
223  wrap |= (0 == fc->next_transmission);
224  }
226  /* assemble fragmentation message */
227  mbuf = (const char *) &fc[1];
228  fh = (struct FragmentHeader *) msg;
229  fh->header.size = htons (fsize);
230  fh->header.type = htons (GNUNET_MESSAGE_TYPE_FRAGMENT);
231  fh->fragment_id = htonl (fc->fragment_id);
232  fh->total_size = fc->msg->size; /* already in big-endian */
233  fh->offset = htons ((fc->mtu - sizeof(struct FragmentHeader)) * bit);
234  GNUNET_memcpy (&fh[1], &mbuf[bit * (fc->mtu - sizeof(struct FragmentHeader))],
235  fsize - sizeof(struct FragmentHeader));
236  if (NULL != fc->tracker)
239  _ ("# fragments transmitted"),
240  1,
241  GNUNET_NO);
242  if (0 != fc->last_round.abs_value_us)
244  _ ("# fragments retransmitted"),
245  1,
246  GNUNET_NO);
248  /* select next message to calculate delay */
249  bit = fc->next_transmission;
250  size = ntohs (fc->msg->size);
251  if (bit == size / (fc->mtu - sizeof(struct FragmentHeader)))
252  fsize = size % (fc->mtu - sizeof(struct FragmentHeader));
253  else
254  fsize = fc->mtu;
255  if (NULL != fc->tracker)
257  fsize);
258  else
260  if (fc->num_rounds < 64)
263  (fc->msg_delay,
264  (1ULL << fc->num_rounds)));
265  else
267  if (wrap)
268  {
269  /* full round transmitted wait 2x delay for ACK before going again */
270  fc->num_rounds++;
272  /* never use zero, need some time for ACK always */
274  fc->wack = GNUNET_YES;
277  _ ("# fragments wrap arounds"),
278  1,
279  GNUNET_NO);
280  }
281  fc->proc_busy = GNUNET_YES;
283  fc->num_transmissions++;
284  fc->proc (fc->proc_cls,
285  &fh->header);
286 }
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
static void transmit_next(void *cls)
Transmit the next fragment to the other peer.
Absolute minimum delay we impose between sending and expecting ACK to arrive.
Definition: fragmentation.c:33
static struct GNUNET_TIME_Relative delay
When should dkg communication start?
static struct GNUNET_DISK_FileHandle * fh
File handle to STDIN, for reading restart/quit commands.
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:368
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:424
#define GNUNET_log(kind,...)
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
FRAGMENT of a larger message.
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:1272
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
Constant used to specify "forever".
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:531
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:351
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:111
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:316
Relative time zero.
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:569
static unsigned int size
Size of the "table".
Definition: peer.c:68
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
Header for a message fragment.
Definition: fragmentation.h:39
Fragmentation context.
Definition: fragmentation.c:41
struct GNUNET_TIME_Absolute last_round
Time we transmitted the last message of the last round.
Definition: fragmentation.c:70
uint32_t fragment_id
Our fragmentation ID.
int8_t wack
GNUNET_YES if we are waiting for an ACK.
struct GNUNET_TIME_Relative ack_delay
Current expected delay for ACKs.
Definition: fragmentation.c:55
unsigned int next_transmission
Round-robin selector for the next transmission.
GNUNET_FRAGMENT_MessageProcessor proc
Function to call for transmissions.
Definition: fragmentation.c:80
struct GNUNET_TIME_Relative msg_delay
Current expected delay between messages.
Definition: fragmentation.c:60
struct GNUNET_SCHEDULER_Task * task
Task performing work for the fragmenter.
const struct GNUNET_MessageHeader * msg
Message to fragment (allocated at the end of this struct).
Definition: fragmentation.c:75
unsigned int num_rounds
How many rounds of transmission have we completed so far?
int8_t proc_busy
GNUNET_YES if we called proc and are now waiting for GNUNET_FRAGMENT_context_transmission_done()
void * proc_cls
Closure for proc.
Definition: fragmentation.c:85
unsigned int num_transmissions
How many transmission have we completed in this round?
uint16_t mtu
Target fragment size.
struct GNUNET_TIME_Absolute delay_until
Next allowed transmission time.
Definition: fragmentation.c:65
uint64_t acks
Bitfield, set to 1 for each unacknowledged fragment.
Definition: fragmentation.c:90
struct GNUNET_STATISTICS_Handle * stats
Statistics to use.
Definition: fragmentation.c:45
struct GNUNET_BANDWIDTH_Tracker * tracker
Tracker for flow control.
Definition: fragmentation.c:50
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
uint64_t abs_value_us
The actual value.
Time for relative time used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.

References _, GNUNET_TIME_Absolute::abs_value_us, GNUNET_FRAGMENT_Context::ack_delay, GNUNET_FRAGMENT_Context::acks, delay, GNUNET_FRAGMENT_Context::delay_until, fh, 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, GNUNET_FRAGMENT_Context::last_round, MIN_ACK_DELAY, msg, 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, GNUNET_FRAGMENT_Context::proc, GNUNET_FRAGMENT_Context::proc_busy, GNUNET_FRAGMENT_Context::proc_cls, GNUNET_TIME_Relative::rel_value_us, GNUNET_MessageHeader::size, size, GNUNET_FRAGMENT_Context::stats, GNUNET_FRAGMENT_Context::task, GNUNET_FRAGMENT_Context::tracker, and GNUNET_FRAGMENT_Context::wack.

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

Here is the call graph for this function:
Here is the caller graph for this function: