38#define FRAG_ERR(s) { errmsg = s; goto error; }
139 const char *errmsg = NULL;
146 if (!
buf_read(buf, &flags,
sizeof(flags)))
148 FRAG_ERR(
"flags not found in packet");
169 "FRAG_IN buf->len=%d type=FRAG_WHOLE flags="
176 FRAG_ERR(
"spurious FRAG_WHOLE flags");
191 "FRAG_IN len=%d type=%d seq_id=%d frag_id=%d size=%d flags="
218 FRAG_ERR(
"fragment buffer overflow");
240 FRAG_ERR(
"FRAG_TEST not implemented");
278 "FRAG_OUT len=%d type=%d seq_id=%d frag_id=%d frag_size=%d flags="
280 buf->
len, type, seq_id, frag_id, frag_size, flags);
287 "FRAG_OUT len=%d type=%d seq_id=%d frag_id=%d frag_size=%d flags="
289 buf->
len, type, seq_id, frag_id, frag_size, flags);
304 const int mfs_aligned = (
max_frag_size & ~FRAG_SIZE_ROUND_MASK);
305 const int div = len / mfs_aligned;
306 const int mod = len % mfs_aligned;
308 if (div > 0 && mod > 0 && mod < mfs_aligned * 3 / 4)
324 const char *errmsg = NULL;
331 buf->
len, f->outgoing.len);
341 FRAG_ERR(
"too many fragments would be required to send datagram");
346 f->outgoing_frag_id = 0;
382 int size = f->outgoing_frag_size;
384 if (f->outgoing.len <= size)
386 size = f->outgoing.len;
391 *
buf = f->outgoing_return;
399 f->outgoing_frag_id++,
400 f->outgoing_frag_size);
402 ASSERT(!last || !f->outgoing.len);
418 struct fragment *frag = &f->incoming.fragments[i];
void free_buf(struct buffer *buf)
struct buffer alloc_buf(size_t size)
static bool buf_copy(struct buffer *dest, const struct buffer *src)
static bool buf_write_prepend(struct buffer *dest, const void *src, int size)
static bool buf_copy_n(struct buffer *dest, struct buffer *src, int n)
static bool buf_read(struct buffer *src, void *dest, int size)
static bool buf_copy_range(struct buffer *dest, int dest_index, const struct buffer *src, int src_index, int src_len)
#define ALLOC_OBJ_CLEAR(dptr, type)
#define buf_init(buf, offset)
#define fragment_header_format
long int get_random(void)
Data Channel Cryptography Module.
static void fragment_ttl_reap(struct fragment_master *f)
static void fragment_prepend_flags(struct buffer *buf, int type, int seq_id, int frag_id, int frag_size)
static struct fragment * fragment_list_get_buf(struct fragment_list *list, int seq_id)
static int optimal_fragment_size(int len, int max_frag_size)
static void fragment_list_buf_free(struct fragment_list *list)
static void fragment_list_buf_init(struct fragment_list *list, const struct frame *frame)
Data Channel Fragmentation module header file.
#define MAX_FRAGS
Maximum number of fragments per packet.
#define N_SEQ_ID
One more than the maximum fragment sequence ID, above which the IDs wrap to zero.
#define FRAG_MAP_MASK
Mask for reassembly map.
#define FRAG_SIZE_MASK
Bit mask for fragment size.
#define hton_fragment_header_type(x)
Convert a fragment_header_type from host to network order.
#define FRAG_TTL_SEC
Time-to-live in seconds for a fragment.
#define FRAG_SEQ_ID_SHIFT
Bit shift for fragment sequence ID.
#define FRAG_SEQ_ID_MASK
Bit mask for fragment sequence ID.
#define FRAG_SIZE_ROUND_MASK
Bit mask for fragment size rounding.
uint32_t fragment_header_type
Fragmentation information is stored in a 32-bit packet header.
#define FRAG_TYPE_SHIFT
Bit shift for fragment type info.
void fragment_frame_init(struct fragment_master *f, const struct frame *frame)
Allocate internal packet buffers for a fragment_master structure.
#define FRAG_TEST
Fragment type not implemented yet.
static bool fragment_outgoing_defined(struct fragment_master *f)
Check whether a fragment_master structure contains fragments ready to be sent.
void fragment_outgoing(struct fragment_master *f, struct buffer *buf, const struct frame *frame)
Process an outgoing packet, which may or may not need to be fragmented.
#define FRAG_YES_LAST
Fragment type indicating packet is the last part in the sequence of parts.
void fragment_incoming(struct fragment_master *f, struct buffer *buf, const struct frame *frame)
Process an incoming packet, which may or may not be fragmented.
#define FRAG_WHOLE
Fragment type indicating packet is whole.
#define FRAG_ID_SHIFT
Bit shift for fragment ID.
#define FRAG_SIZE_ROUND_SHIFT
Bit shift for fragment size rounding.
#define FRAG_TYPE_MASK
Bit mask for fragment type info.
#define N_FRAG_BUF
Number of packet buffers for reassembling incoming fragmented packets.
#define FRAG_WAKEUP_INTERVAL
Interval in seconds between calls to wakeup code.
void fragment_wakeup(struct fragment_master *f, struct frame *frame)
struct fragment_master * fragment_init(struct frame *frame)
Allocate and initialize a fragment_master structure.
#define FRAG_YES_NOTLAST
Fragment type indicating packet is part of a fragmented packet, but not the last part in the sequence...
void fragment_free(struct fragment_master *f)
Free a fragment_master structure and its internal packet buffers.
#define ntoh_fragment_header_type(x)
Convert a fragment_header_type from network to host order.
#define FRAG_ID_MASK
Bit mask for fragment ID.
#define FRAG_SIZE_SHIFT
Bit shift for fragment size.
bool fragment_ready_to_send(struct fragment_master *f, struct buffer *buf, const struct frame *frame)
Check whether outgoing fragments are ready to be send, and if so make one available.
static int min_int(int x, int y)
static int modulo_subtract(int x, int y, int mod)
static int modulo_add(int x, int y, int mod)
static void event_timeout_init(struct event_timeout *et, interval_t n, const time_t last)
Initialises a timer struct.
Wrapper structure for dynamically allocated memory.
int len
Length in bytes of the actual content within the allocated memory.
List of fragment structures for reassembling multiple incoming packets concurrently.
int seq_id
Highest fragmentation sequence ID of the packets currently being reassembled.
int index
Index of the packet being reassembled with the highest fragmentation sequence ID into the fragment_li...
struct fragment fragments[N_FRAG_BUF]
Array of reassembly structures, each can contain one whole packet.
Fragmentation and reassembly state for one VPN tunnel instance.
struct event_timeout wakeup
Timeout structure used by the main event loop to know when to do fragmentation housekeeping.
int outgoing_seq_id
Fragment sequence ID of the current fragmented packet waiting to be sent.
Structure for reassembling one incoming fragmented packet.
int max_frag_size
Maximum size of each fragment.
unsigned int map
Reassembly map for recording which fragments have been received.
bool defined
Whether reassembly is currently taking place in this structure.
time_t timestamp
Timestamp for time-to-live purposes.
struct buffer buf
Buffer in which received datagrams are reassembled.
Packet geometry parameters.
int headroom
the headroom in the buffer, this is choosen to allow all potential header to be added before the pack...
int max_fragment_size
The maximum size of a fragment.