238 while (NULL != (
mc =
dc->head))
242 if (NULL !=
mc->ack_task)
272 _ (
"# acknowledgements sent for fragment"),
287 gsl_fit_mul (
const double *x,
const size_t xstride,
const double *y,
288 const size_t ystride,
const size_t n,
double *c1,
double *cov_11,
291 double m_x = 0, m_y = 0, m_dx2 = 0, m_dxdy = 0;
295 for (i = 0; i < n; i++)
297 m_x += (x[i * xstride] - m_x) / (i + 1.0);
298 m_y += (y[i * ystride] - m_y) / (i + 1.0);
301 for (i = 0; i < n; i++)
303 const double dx = x[i * xstride] - m_x;
304 const double dy = y[i * ystride] - m_y;
306 m_dx2 += (dx * dx - m_dx2) / (i + 1.0);
307 m_dxdy += (dx * dy - m_dxdy) / (i + 1.0);
313 double s2 = 0, d2 = 0;
314 double b = (m_x * m_y + m_dxdy) / (m_x * m_x + m_dx2);
320 for (i = 0; i < n; i++)
322 const double dx = x[i * xstride] - m_x;
323 const double dy = y[i * ystride] - m_y;
324 const double d = (m_y - b * m_x) + dy - b * dx;
331 *cov_11 = s2 * 1.0 / (n * (m_x * m_x + m_dx2));
349 size_t total =
mc->frag_times_write_offset -
mc->frag_times_start_offset;
358 first = &
mc->frag_times[
mc->frag_times_start_offset];
360 for (i = 0; i < total; i++)
363 y[i] = (double) (first[i].time.abs_value_us - first[0].time.abs_value_us);
365 gsl_fit_mul (x, 1, y, 1, total, &c1, &cov11, &sumsq);
367 ret.rel_value_us = (uint64_t) c1;
368 if (0 ==
ret.rel_value_us)
431 unsigned int num_fragments;
446 msize = ntohs (
fh->total_size);
452 fid = ntohl (
fh->fragment_id);
453 foff = ntohs (
fh->offset);
465 _ (
"# fragments received"),
471 for (
mc =
dc->head; NULL !=
mc;
mc =
mc->next)
472 if (
mc->fragment_id > fid)
476 while ((NULL !=
mc) && (fid !=
mc->fragment_id))
486 if ((NULL !=
mc) && (msize !=
mc->total_size))
498 mc->total_size = msize;
499 mc->fragment_id = fid;
500 mc->last_update = now;
505 mc->bits = UINT64_MAX;
507 mc->bits = (1LLU << n) - 1;
508 if (
dc->list_size >=
dc->num_msgs)
517 if (0 != (
mc->bits & (1LLU << bit)))
519 mc->bits -= 1LLU << bit;
520 mbuf = (
char *) &
mc[1];
524 mc->last_update = now;
525 if (bit < mc->last_bit)
526 mc->frag_times_start_offset =
mc->frag_times_write_offset;
528 mc->frag_times[
mc->frag_times_write_offset].time = now;
529 mc->frag_times[
mc->frag_times_write_offset].bit = bit;
530 mc->frag_times_write_offset++;
537 _ (
"# duplicate fragments received"),
544 for (b = bit; b < 64; b++)
545 if (0 != (
mc->bits & (1LLU << b)))
555 _ (
"# messages defragmented"),
559 dc->proc (
dc->cls,
mc->msg);
562 if (
mc->frag_times_write_offset -
mc->frag_times_start_offset > 1)
568 if ((last + fid == num_fragments) ||
576 if (NULL !=
mc->ack_task)
struct GNUNET_MessageHeader * msg
static void discard_oldest_mc(struct GNUNET_DEFRAGMENT_Context *dc)
Discard the message context that was inactive for the longest time.
static void send_ack(void *cls)
Send acknowledgement to the other peer now.
static void gsl_fit_mul(const double *x, const size_t xstride, const double *y, const size_t ystride, const size_t n, double *c1, double *cov_11, double *sumsq)
This function is from the GNU Scientific Library, linear/fit.c, Copyright (C) 2000 Brian Gough.
static struct GNUNET_TIME_Relative estimate_latency(struct MessageContext *mc)
Estimate the latency between messages based on the most recent message time stamps.
library to help fragment messages
static int ret
Return value of the commandline.
static struct GNUNET_FS_DownloadContext * dc
static struct GNUNET_TESTBED_Controller * mc
Handle to the master controller.
static struct GNUNET_TIME_Relative delay
When should dkg communication start?
struct GNUNET_STATISTICS_Handle * stats
Handle to the statistics service.
static struct GNUNET_DISK_FileHandle * fh
File handle to STDIN, for reading restart/quit commands.
Library to help fragment messages.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
int GNUNET_DEFRAGMENT_process_fragment(struct GNUNET_DEFRAGMENT_Context *dc, const struct GNUNET_MessageHeader *msg)
We have received a fragment.
void GNUNET_DEFRAGMENT_context_destroy(struct GNUNET_DEFRAGMENT_Context *dc)
Destroy the given defragmentation context.
struct GNUNET_DEFRAGMENT_Context * GNUNET_DEFRAGMENT_context_create(struct GNUNET_STATISTICS_Handle *stats, uint16_t mtu, unsigned int num_msgs, void *cls, GNUNET_FRAGMENT_MessageProcessor proc, GNUNET_DEFRAGMENT_AckProcessor ackp)
Create a defragmentation context.
void(* GNUNET_FRAGMENT_MessageProcessor)(void *cls, const struct GNUNET_MessageHeader *msg)
Function that is called with messages created by the fragmentation module.
void(* GNUNET_DEFRAGMENT_AckProcessor)(void *cls, uint32_t id, const struct GNUNET_MessageHeader *msg)
Function that is called with acknowledgement messages created by the fragmentation module.
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_MESSAGE_TYPE_FRAGMENT_ACK
Acknowledgement of a FRAGMENT of a larger message.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
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.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
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.
#define GNUNET_TIME_UNIT_SECONDS
One second.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
#define GNUNET_TIME_UNIT_ZERO
Relative time zero.
#define GNUNET_TIME_UNIT_MICROSECONDS
One microsecond, our basic time unit.
Timestamps for fragments.
struct GNUNET_TIME_Absolute time
The time the fragment was received.
unsigned int bit
Number of the bit for the fragment (in [0,..,63]).
Message fragment acknowledgement.
uint32_t fragment_id
Unique fragment ID.
uint64_t bits
Bits that are being acknowledged, in big-endian.
struct GNUNET_MessageHeader header
Message header.
Defragmentation context (one per connection).
struct MessageContext * tail
Tail of list of messages we're defragmenting.
uint16_t mtu
Maximum message size for each fragment.
GNUNET_DEFRAGMENT_AckProcessor ackp
Function to call with acknowledgements.
struct GNUNET_STATISTICS_Handle * stats
For statistics.
GNUNET_FRAGMENT_MessageProcessor proc
Function to call with defragmented messages.
unsigned int num_msgs
num_msgs how many fragmented messages to we defragment at most at the same time?
void * cls
Closure for proc and ackp.
struct GNUNET_TIME_Relative latency
Running average of the latency (delay between messages) for this connection.
unsigned int list_size
Current number of messages in the 'struct MessageContext' DLL (smaller or equal to 'num_msgs').
struct MessageContext * head
Head of list of messages we're defragmenting.
Entry in list of pending tasks.
Time for absolute times used by GNUnet, in microseconds.
uint64_t abs_value_us
The actual value.
Time for relative time used by GNUnet, in microseconds.
Information we keep for one message that is being assembled.
struct FragTimes frag_times[64]
When did we receive which fragment? Used to calculate the time we should send the ACK.
unsigned int last_bit
Which 'bit' did the last fragment we received correspond to?
unsigned int frag_times_write_offset
Which offset would we write the next frag value into in the frag_times array? All smaller entries are...
uint64_t bits
Which fragments have we gotten yet? bits that are 1 indicate missing fragments.
struct GNUNET_DEFRAGMENT_Context * dc
Associated defragmentation context.
unsigned int frag_times_start_offset
For the current ACK round, which is the first relevant offset in frag_times?
struct GNUNET_TIME_Absolute last_update
Last time we received any update for this message (least-recently updated message will be discarded i...
struct MessageContext * next
This is a DLL.
struct MessageContext * prev
This is a DLL.
uint32_t fragment_id
Unique ID for this message.
const struct GNUNET_MessageHeader * msg
Pointer to the assembled message, allocated at the end of this struct.
struct GNUNET_SCHEDULER_Task * ack_task
Task scheduled for transmitting the next ACK to the other peer.
int16_t last_duplicate
Was the last fragment we got a duplicate?
uint16_t total_size
Total size of the message that we are assembling.