GNUnet  0.17.6
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


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:483

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

Definition at line 34 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 172 of file fragmentation.c.

173 {
174  struct GNUNET_FRAGMENT_Context *fc = cls;
175  char msg[fc->mtu];
176  const char *mbuf;
177  struct FragmentHeader *fh;
179  unsigned int bit;
180  size_t size;
181  size_t fsize;
182  int wrap;
184  fc->task = NULL;
186  if (0 == fc->acks)
187  return; /* all done */
188  /* calculate delay */
189  wrap = 0;
190  while (0 == (fc->acks & (1LLU << fc->next_transmission)))
191  {
192  fc->next_transmission = (fc->next_transmission + 1) % 64;
193  wrap |= (0 == fc->next_transmission);
194  }
195  bit = fc->next_transmission;
196  size = ntohs (fc->msg->size);
197  if (bit == size / (fc->mtu - sizeof(struct FragmentHeader)))
198  fsize =
199  (size % (fc->mtu - sizeof(struct FragmentHeader)))
200  + sizeof(struct FragmentHeader);
201  else
202  fsize = fc->mtu;
203  if (NULL != fc->tracker)
205  fsize);
206  else
208  if (delay.rel_value_us > 0)
209  {
211  "Fragmentation logic delays transmission of next fragment by %s\n",
213  GNUNET_YES));
215  &transmit_next,
216  fc);
217  return;
218  }
219  fc->next_transmission = (fc->next_transmission + 1) % 64;
220  wrap |= (0 == fc->next_transmission);
221  while (0 == (fc->acks & (1LLU << fc->next_transmission)))
222  {
223  fc->next_transmission = (fc->next_transmission + 1) % 64;
224  wrap |= (0 == fc->next_transmission);
225  }
227  /* assemble fragmentation message */
228  mbuf = (const char *) &fc[1];
229  fh = (struct FragmentHeader *) msg;
230  fh->header.size = htons (fsize);
231  fh->header.type = htons (GNUNET_MESSAGE_TYPE_FRAGMENT);
232  fh->fragment_id = htonl (fc->fragment_id);
233  fh->total_size = fc->msg->size; /* already in big-endian */
234  fh->offset = htons ((fc->mtu - sizeof(struct FragmentHeader)) * bit);
235  GNUNET_memcpy (&fh[1], &mbuf[bit * (fc->mtu - sizeof(struct FragmentHeader))],
236  fsize - sizeof(struct FragmentHeader));
237  if (NULL != fc->tracker)
240  _ ("# fragments transmitted"),
241  1,
242  GNUNET_NO);
243  if (0 != fc->last_round.abs_value_us)
245  _ ("# fragments retransmitted"),
246  1,
247  GNUNET_NO);
249  /* select next message to calculate delay */
250  bit = fc->next_transmission;
251  size = ntohs (fc->msg->size);
252  if (bit == size / (fc->mtu - sizeof(struct FragmentHeader)))
253  fsize = size % (fc->mtu - sizeof(struct FragmentHeader));
254  else
255  fsize = fc->mtu;
256  if (NULL != fc->tracker)
258  fsize);
259  else
261  if (fc->num_rounds < 64)
264  (fc->msg_delay,
265  (1ULL << fc->num_rounds)));
266  else
268  if (wrap)
269  {
270  /* full round transmitted wait 2x delay for ACK before going again */
271  fc->num_rounds++;
273  /* never use zero, need some time for ACK always */
275  fc->wack = GNUNET_YES;
278  _ ("# fragments wrap arounds"),
279  1,
280  GNUNET_NO);
281  }
282  fc->proc_busy = GNUNET_YES;
284  fc->num_transmissions++;
285  fc->proc (fc->proc_cls,
286  &fh->header);
287 }
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:34
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:367
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:423
#define GNUNET_log(kind,...)
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
Definition: gnunet_common.h:98
#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:1254
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:530
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:350
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:110
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:315
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:570
static unsigned int size
Size of the "table".
Definition: peer.c:67
#define _(String)
GNU gettext support macro.
Definition: platform.h:177
Header for a message fragment.
Definition: fragmentation.h:37
Fragmentation context.
Definition: fragmentation.c:42
struct GNUNET_TIME_Absolute last_round
Time we transmitted the last message of the last round.
Definition: fragmentation.c:71
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:56
unsigned int next_transmission
Round-robin selector for the next transmission.
GNUNET_FRAGMENT_MessageProcessor proc
Function to call for transmissions.
Definition: fragmentation.c:81
struct GNUNET_TIME_Relative msg_delay
Current expected delay between messages.
Definition: fragmentation.c:61
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:76
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:86
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:66
uint64_t acks
Bitfield, set to 1 for each unacknowledged fragment.
Definition: fragmentation.c:91
struct GNUNET_STATISTICS_Handle * stats
Statistics to use.
Definition: fragmentation.c:46
struct GNUNET_BANDWIDTH_Tracker * tracker
Tracker for flow control.
Definition: fragmentation.c:51
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: