GNUnet  0.11.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...
 

Macros

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

Functions

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

Author
Christian Grothoff

Definition in file fragmentation.c.

Macro Definition Documentation

◆ MIN_ACK_DELAY

#define MIN_ACK_DELAY
Value:
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:442
#define GNUNET_TIME_UNIT_MILLISECONDS
One millisecond.

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)
static

Transmit the next fragment to the other peer.

Parameters
clsthe struct GNUNET_FRAGMENT_Context

Definition at line 172 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().

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;
183 
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  }
226 
227  /* assemble fragmentation message */
228  mbuf = (const char *) &fc[1];
229  fh = (struct FragmentHeader *) msg;
230  fh->header.size = htons (fsize);
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);
248 
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 }
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:91
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_MessageHeader header
Message header.
Definition: fragmentation.h:41
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:46
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:71
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:46
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:61
GNUNET_FRAGMENT_MessageProcessor proc
Function to call for transmissions.
Definition: fragmentation.c:81
#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:51
#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:51
void * proc_cls
Closure for proc.
Definition: fragmentation.c:86
#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:41
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:1253
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:687
static void transmit_next(void *cls)
Transmit the next fragment to the other peer.
#define GNUNET_TIME_UNIT_FOREVER_REL
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:76
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:67
uint16_t offset
Absolute offset (in bytes) of this fragment in the original message.
Definition: fragmentation.h:57
static struct GNUNET_TIME_Relative delay
When should dkg communication start?
#define GNUNET_TIME_UNIT_ZERO
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:56
#define GNUNET_YES
Definition: gnunet_common.h:77
#define MIN_ACK_DELAY
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.
#define GNUNET_MESSAGE_TYPE_FRAGMENT
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:501
struct GNUNET_TIME_Absolute delay_until
Next allowed transmission time.
Definition: fragmentation.c:66
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: