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 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;
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);
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 }
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:90
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_MessageHeader header
Message header.
Definition: fragmentation.h:42
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:47
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:70
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:286
struct GNUNET_STATISTICS_Handle * stats
Statistics to use.
Definition: fragmentation.c:45
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:245
#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:60
GNUNET_FRAGMENT_MessageProcessor proc
Function to call for transmissions.
Definition: fragmentation.c:80
uint16_t total_size
Total message size of the original message.
Definition: fragmentation.h:52
#define GNUNET_NO
Definition: gnunet_common.h:81
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:50
void * proc_cls
Closure for proc.
Definition: fragmentation.c:85
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
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:1246
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_memcpy(dst, src, n)
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:727
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:75
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:58
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:55
#define GNUNET_YES
Definition: gnunet_common.h:80
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:65
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: