Go to the documentation of this file.
30 #ifdef ENABLE_FRAGMENT
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);
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;
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];
#define N_SEQ_ID
One more than the maximum fragment sequence ID, above which the IDs wrap to zero.
static bool buf_copy_range(struct buffer *dest, int dest_index, const struct buffer *src, int src_index, int src_len)
void fragment_frame_init(struct fragment_master *f, const struct frame *frame)
Allocate internal packet buffers for a fragment_master structure.
static bool buf_read(struct buffer *src, void *dest, int size)
struct fragment_master * fragment_init(struct frame *frame)
Allocate and initialize a fragment_master structure.
void fragment_free(struct fragment_master *f)
Free a fragment_master structure and its internal packet buffers.
int len
Length in bytes of the actual content within the allocated memory.
Fragmentation and reassembly state for one VPN tunnel instance.
#define FRAG_WAKEUP_INTERVAL
Interval in seconds between calls to wakeup code.
int outgoing_seq_id
Fragment sequence ID of the current fragmented packet waiting to be sent.
#define fragment_header_format
#define buf_init(buf, offset)
#define FRAG_ID_MASK
Bit mask for fragment ID.
long int get_random(void)
#define FRAG_SIZE_ROUND_SHIFT
Bit shift for fragment size rounding.
bool defined
Whether reassembly is currently taking place in this structure.
#define FRAG_YES_LAST
Fragment type indicating packet is the last part in the sequence of parts.
Structure for reassembling one incoming fragmented packet.
#define FRAG_SEQ_ID_SHIFT
Bit shift for fragment sequence ID.
static bool buf_copy(struct buffer *dest, const struct buffer *src)
static void event_timeout_init(struct event_timeout *et, interval_t n, const time_t last)
Initialises a timer struct.
Packet geometry parameters.
static int modulo_add(int x, int y, int mod)
static void fragment_list_buf_free(struct fragment_list *list)
static int optimal_fragment_size(int len, int max_frag_size)
#define FRAG_YES_NOTLAST
Fragment type indicating packet is part of a fragmented packet, but not the last part in the sequence...
struct fragment fragments[N_FRAG_BUF]
Array of reassembly structures, each can contain one whole packet.
#define FRAG_ID_SHIFT
Bit shift for fragment ID.
#define FRAG_TYPE_SHIFT
Bit shift for fragment type info.
static bool buf_write_prepend(struct buffer *dest, const void *src, int size)
#define FRAG_TTL_SEC
Time-to-live in seconds for a fragment.
static void fragment_prepend_flags(struct buffer *buf, int type, int seq_id, int frag_id, int frag_size)
#define FRAG_SIZE_MASK
Bit mask for fragment size.
List of fragment structures for reassembling multiple incoming packets concurrently.
int seq_id
Highest fragmentation sequence ID of the packets currently being reassembled.
#define FRAG_TEST
Fragment type not implemented yet.
struct event_timeout wakeup
Timeout structure used by the main event loop to know when to do fragmentation housekeeping.
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.
unsigned int map
Reassembly map for recording which fragments have been received.
Wrapper structure for dynamically allocated memory.
#define FRAG_WHOLE
Fragment type indicating packet is whole.
void fragment_wakeup(struct fragment_master *f, struct frame *frame)
int max_frag_size
Maximum size of each fragment.
#define FRAG_SIZE_SHIFT
Bit shift for fragment size.
int max_fragment_size
The maximum size of a fragment.
#define ntoh_fragment_header_type(x)
Convert a fragment_header_type from network to host order.
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.
uint32_t fragment_header_type
Fragmentation information is stored in a 32-bit packet header.
struct buffer buf
Buffer in which received datagrams are reassembled.
#define FRAG_SIZE_ROUND_MASK
Bit mask for fragment size rounding.
#define FRAG_SEQ_ID_MASK
Bit mask for fragment sequence ID.
void free_buf(struct buffer *buf)
#define MAX_FRAGS
Maximum number of fragments per packet.
static struct fragment * fragment_list_get_buf(struct fragment_list *list, int seq_id)
#define FRAG_MAP_MASK
Mask for reassembly map.
static void fragment_list_buf_init(struct fragment_list *list, const struct frame *frame)
static int min_int(int x, int y)
#define hton_fragment_header_type(x)
Convert a fragment_header_type from host to network order.
#define ALLOC_OBJ_CLEAR(dptr, type)
static void fragment_ttl_reap(struct fragment_master *f)
#define FRAG_TYPE_MASK
Bit mask for fragment type info.
int index
Index of the packet being reassembled with the highest fragmentation sequence ID into the fragment_li...
#define N_FRAG_BUF
Number of packet buffers for reassembling incoming fragmented packets.
struct buffer alloc_buf(size_t size)
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.
int headroom
the headroom in the buffer, this is choosen to allow all potential header to be added before the pack...
static int modulo_subtract(int x, int y, int mod)
static bool buf_copy_n(struct buffer *dest, struct buffer *src, int n)
time_t timestamp
Timestamp for time-to-live purposes.
static bool fragment_outgoing_defined(struct fragment_master *f)
Check whether a fragment_master structure contains fragments ready to be sent.