mirror of
https://github.com/OpenVPN/openvpn.git
synced 2026-06-09 08:59:57 -04:00
Added data channel fragmentation docs
Signed-off-by: Adriaan de Jong <dejong@fox-it.com> Acked-by: James Yonan <james@openvpn.net> Signed-off-by: David Sommerseth <dazo@users.sourceforge.net>
This commit is contained in:
parent
5959e9def6
commit
15bd346ca0
2 changed files with 457 additions and 70 deletions
96
doc_fragmentation.h
Normal file
96
doc_fragmentation.h
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* OpenVPN -- An application to securely tunnel IP networks
|
||||
* over a single TCP/UDP port, with support for SSL/TLS-based
|
||||
* session authentication and key exchange,
|
||||
* packet encryption, packet authentication, and
|
||||
* packet compression.
|
||||
*
|
||||
* Copyright (C) 2010 Fox Crypto B.V. <openvpn@fox-it.com>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program (see the file COPYING included with this
|
||||
* distribution); if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Data Channel Fragmentation module documentation file.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup fragmentation Data Channel Fragmentation module
|
||||
*
|
||||
* The Data Channel Fragmentation module offers fragmentation of data
|
||||
* channel packets.
|
||||
*
|
||||
* @par State structures
|
||||
* The Data Channel Fragmentation module stores its internal state in a \c
|
||||
* fragment_master structure. One such structure is present for each VPN
|
||||
* tunnel, and is stored in \c context.c2.fragment of the \c context
|
||||
* associated with that VPN tunnel.
|
||||
*
|
||||
* @par
|
||||
* The \c fragment_master structure contains one \c fragment_list
|
||||
* structure \c fragment_master.incoming. This is a list of \c fragment
|
||||
* structures, each of which can store the parts of one fragmented packet
|
||||
* while it is being reassembled. The \c fragment_master structure also
|
||||
* contains one \c buffer called \c fragment_master.outgoing, in which a
|
||||
* data channel large packet to be sent to a remote OpenVPN peer can be
|
||||
* broken up into parts to be sent one by one.
|
||||
*
|
||||
* @par Initialization and cleanup
|
||||
* Every time a new \c fragment_master is needed, it must be allocated and
|
||||
* initialized by the \c fragment_init() function. Similarly, every time
|
||||
* a \c fragment_master is no longer needed, it must be cleaned up using
|
||||
* the \c fragment_free() function. These functions take care of the
|
||||
* allocation and freeing of the \c fragment_master structure itself and
|
||||
* all internal memory required for the use of that structure. Note that
|
||||
* this behavior is different from that displayed by the \link compression
|
||||
* Data Channel Compression module\endlink.
|
||||
*
|
||||
* @par
|
||||
* Because of the one-to-one relationship between \c fragment_master
|
||||
* structures and VPN tunnels, the above-mentioned initialization and
|
||||
* cleanup functions are called directly from the \c init_instance() and
|
||||
* \c close_instance() functions, which control the initialization and
|
||||
* cleanup of VPN tunnel instances and their associated \c context
|
||||
* structures.
|
||||
*
|
||||
* @par Packet processing functions
|
||||
* This module receives data channel packets from the \link data_control
|
||||
* Data Channel Control module\endlink and processes them according to the
|
||||
* settings of the packet's VPN tunnel. The \link data_control Data
|
||||
* Channel Control module\endlink uses the following interface functions:
|
||||
* - For packets which will be sent to a remote OpenVPN peer: \c
|
||||
* fragment_outgoing() \n This function inspects data channel packets as
|
||||
* they are being made ready to be sent as VPN tunnel packets to a
|
||||
* remote OpenVPN peer. If a packet's size is larger than its
|
||||
* destination VPN tunnel's maximum transmission unit (MTU), then this
|
||||
* module breaks that packet up into smaller parts, each of which is
|
||||
* smaller than or equal to the VPN tunnel's MTU. See \c
|
||||
* fragment_outgoing() for details.
|
||||
* - For packets which have been received from a remote OpenVPN peer: \c
|
||||
* fragment_incoming() \n This function inspects data channel packets
|
||||
* that have been received from a remote OpenVPN peer through a VPN
|
||||
* tunnel. It reads the fragmentation header of the packet, and
|
||||
* depending on its value performs the appropriate action. See \c
|
||||
* fragment_incoming() for details.
|
||||
*
|
||||
* @par Settings that control this module's activity
|
||||
* Whether the Data Channel Fragmentation module is active or not depends
|
||||
* on the compile-time \c ENABLE_FRAGMENT preprocessor macro and the
|
||||
* runtime flag \c options.fragment, which gets its value from the
|
||||
* process's configuration sources, such as the configuration file and
|
||||
* commandline %options.
|
||||
*/
|
||||
431
fragment.h
431
fragment.h
|
|
@ -25,8 +25,20 @@
|
|||
#ifndef FRAGMENT_H
|
||||
#define FRAGMENT_H
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Data Channel Fragmentation module header file.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef ENABLE_FRAGMENT
|
||||
|
||||
/**
|
||||
* @addtogroup fragmentation
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
#include "common.h"
|
||||
#include "buffer.h"
|
||||
#include "interval.h"
|
||||
|
|
@ -34,143 +46,422 @@
|
|||
#include "shaper.h"
|
||||
#include "error.h"
|
||||
|
||||
#define N_FRAG_BUF 25 /* number of packet buffers */
|
||||
#define FRAG_TTL_SEC 10 /* number of seconds time-to-live for a fragment */
|
||||
#define FRAG_WAKEUP_INTERVAL 5 /* wakeup code called once per n seconds */
|
||||
|
||||
#define N_FRAG_BUF 25
|
||||
/**< Number of packet buffers for
|
||||
* reassembling incoming fragmented
|
||||
* packets. */
|
||||
|
||||
#define FRAG_TTL_SEC 10
|
||||
/**< Time-to-live in seconds for a %fragment. */
|
||||
|
||||
#define FRAG_WAKEUP_INTERVAL 5
|
||||
/**< Interval in seconds between calls to
|
||||
* wakeup code. */
|
||||
|
||||
/**************************************************************************/
|
||||
/**
|
||||
* Structure for reassembling one incoming fragmented packet.
|
||||
*/
|
||||
struct fragment {
|
||||
bool defined;
|
||||
bool defined; /**< Whether reassembly is currently
|
||||
* taking place in this structure. */
|
||||
|
||||
int max_frag_size; /* maximum size of each fragment */
|
||||
int max_frag_size; /**< Maximum size of each %fragment. */
|
||||
|
||||
/*
|
||||
* 32 bit array corresponding to each fragment. A 1 bit in element n means that
|
||||
* the fragment n has been received. Needs to have at least MAX_FRAGS bits.
|
||||
*/
|
||||
# define FRAG_MAP_MASK 0xFFFFFFFF
|
||||
# define MAX_FRAGS 32 /* maximum number of fragments per packet */
|
||||
/**< Mask for reassembly map. */
|
||||
# define MAX_FRAGS 32 /**< Maximum number of fragments per packet. */
|
||||
unsigned int map;
|
||||
/**< Reassembly map for recording which
|
||||
* fragments have been received.
|
||||
*
|
||||
* A bit array where each bit
|
||||
* corresponds to a %fragment. A 1 bit
|
||||
* in element n means that the %fragment
|
||||
* n has been received. Needs to have
|
||||
* at least \c MAX_FRAGS bits. */
|
||||
|
||||
time_t timestamp; /* timestamp for time-to-live purposes */
|
||||
time_t timestamp; /**< Timestamp for time-to-live purposes. */
|
||||
|
||||
struct buffer buf; /* fragment assembly buffer for received datagrams */
|
||||
struct buffer buf; /**< Buffer in which received datagrams
|
||||
* are reassembled. */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* List of fragment structures for reassembling multiple incoming packets
|
||||
* concurrently.
|
||||
*/
|
||||
struct fragment_list {
|
||||
int seq_id;
|
||||
int index;
|
||||
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 \c
|
||||
* fragment_list.fragments array. */
|
||||
|
||||
/** Array of reassembly structures, each can contain one whole packet.
|
||||
*
|
||||
* The fragmentation sequence IDs of the packets being reassembled in
|
||||
* this array are linearly increasing. \c
|
||||
* fragment_list.fragments[fragment_list.index] has an ID of \c
|
||||
* fragment_list.seq_id. This means that one of these \c fragment_list
|
||||
* structures can at any one time contain at most packets with the
|
||||
* fragmentation sequence IDs in the range \c fragment_list.seq_id \c -
|
||||
* \c N_FRAG_BUF \c + \c 1 to \c fragment_list.seq_id, inclusive.
|
||||
*/
|
||||
struct fragment fragments[N_FRAG_BUF];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Fragmentation and reassembly state for one VPN tunnel instance.
|
||||
*
|
||||
* This structure contains all the state necessary for sending and
|
||||
* receiving fragmented data channel packets associated with one VPN
|
||||
* tunnel.
|
||||
*
|
||||
* The fragmented packet currently being sent to a remote OpenVPN peer is
|
||||
* stored in \c fragment_master.outgoing. It is copied into that buffer
|
||||
* by the \c fragment_outgoing() function and the remaining parts to be
|
||||
* sent can be retrieved by successive calls to \c
|
||||
* fragment_ready_to_send().
|
||||
*
|
||||
* The received packets currently being reassembled are stored in the \c
|
||||
* fragment_master.incoming array of \c fragment structures. The \c
|
||||
* fragment_incoming() function adds newly received parts into this array
|
||||
* and returns the whole packets once reassembly is complete.
|
||||
*/
|
||||
struct fragment_master {
|
||||
struct event_timeout wakeup; /* when should main openvpn event loop wake us up */
|
||||
struct event_timeout wakeup; /**< Timeout structure used by the main
|
||||
* event loop to know when to do
|
||||
* fragmentation housekeeping. */
|
||||
bool received_os_mtu_hint; /**< Whether the operating system has
|
||||
* explicitly recommended an MTU value. */
|
||||
# define N_SEQ_ID 256
|
||||
/**< One more than the maximum fragment
|
||||
* sequence ID, above which the IDs wrap
|
||||
* to zero. Should be a power of 2. */
|
||||
int outgoing_seq_id; /**< Fragment sequence ID of the current
|
||||
* fragmented packet waiting to be sent.
|
||||
*
|
||||
* All parts of a fragmented packet
|
||||
* share the same sequence ID, so that
|
||||
* the remote OpenVPN peer can determine
|
||||
* which parts belong to which original
|
||||
* packet. */
|
||||
# define MAX_FRAG_PKT_SIZE 65536
|
||||
/**< (Not used) Maximum packet size before
|
||||
* fragmenting. */
|
||||
int outgoing_frag_size; /**< Size in bytes of each part to be
|
||||
* sent, except for the last part which
|
||||
* may be smaller.
|
||||
*
|
||||
* This value is computed by the \c
|
||||
* optimal_fragment_size() function. Its
|
||||
* value is sent to the remote peer in
|
||||
* the fragmentation header of the last
|
||||
* part (i.e. with %fragment type \c
|
||||
* FRAG_YES_LAST) using the \c
|
||||
* FRAG_SIZE_MASK and \c FRAG_SIZE_SHIFT
|
||||
* bits. */
|
||||
int outgoing_frag_id; /**< The fragment ID of the next part to
|
||||
* be sent. Must have a value between 0
|
||||
* and \c MAX_FRAGS-1. */
|
||||
struct buffer outgoing; /**< Buffer containing the remaining parts
|
||||
* of the fragmented packet being sent. */
|
||||
struct buffer outgoing_return;
|
||||
/**< Buffer used by \c
|
||||
* fragment_ready_to_send() to return a
|
||||
* part to send. */
|
||||
|
||||
/* true if the OS has explicitly recommended an MTU value */
|
||||
bool received_os_mtu_hint;
|
||||
|
||||
/* a sequence ID describes a set of fragments that make up one datagram */
|
||||
# define N_SEQ_ID 256 /* sequence number wraps to 0 at this value (should be a power of 2) */
|
||||
int outgoing_seq_id; /* sent as FRAG_SEQ_ID below */
|
||||
|
||||
/* outgoing packet is possibly sent as a series of fragments */
|
||||
|
||||
# define MAX_FRAG_PKT_SIZE 65536 /* maximum packet size */
|
||||
int outgoing_frag_size; /* sent to peer via FRAG_SIZE when FRAG_YES_LAST set */
|
||||
|
||||
int outgoing_frag_id; /* each fragment in a datagram is numbered 0 to MAX_FRAGS-1 */
|
||||
|
||||
struct buffer outgoing; /* outgoing datagram, free if current_frag_id == 0 */
|
||||
struct buffer outgoing_return; /* buffer to return outgoing fragment */
|
||||
|
||||
/* incoming fragments from remote */
|
||||
struct fragment_list incoming;
|
||||
/**< List of structures for reassembling
|
||||
* incoming packets. */
|
||||
};
|
||||
|
||||
/*
|
||||
* Fragment header sent over the wire.
|
||||
*/
|
||||
|
||||
/**************************************************************************/
|
||||
/** @name Fragment header
|
||||
* @todo Add description of %fragment header format.
|
||||
*//** @{ *//*************************************/
|
||||
|
||||
typedef uint32_t fragment_header_type;
|
||||
/**< Fragmentation information is stored in
|
||||
* a 32-bit packet header. */
|
||||
|
||||
/* convert a fragment_header_type from host to network order */
|
||||
#define hton_fragment_header_type(x) htonl(x)
|
||||
/**< Convert a fragment_header_type from
|
||||
* host to network order. */
|
||||
|
||||
/* convert a fragment_header_type from network to host order */
|
||||
#define ntoh_fragment_header_type(x) ntohl(x)
|
||||
/**< Convert a \c fragment_header_type
|
||||
* from network to host order. */
|
||||
|
||||
/* FRAG_TYPE 2 bits */
|
||||
#define FRAG_TYPE_MASK 0x00000003
|
||||
#define FRAG_TYPE_SHIFT 0
|
||||
/**< Bit mask for %fragment type info. */
|
||||
#define FRAG_TYPE_SHIFT 0 /**< Bit shift for %fragment type info. */
|
||||
|
||||
#define FRAG_WHOLE 0 /* packet is whole, FRAG_N_PACKETS_RECEIVED echoed back to peer */
|
||||
#define FRAG_YES_NOTLAST 1 /* packet is a fragment, but is not the last fragment,
|
||||
FRAG_N_PACKETS_RECEIVED set as above */
|
||||
#define FRAG_YES_LAST 2 /* packet is the last fragment, FRAG_SIZE = size of non-last frags */
|
||||
#define FRAG_TEST 3 /* control packet for establishing MTU size (not implemented yet) */
|
||||
#define FRAG_WHOLE 0 /**< Fragment type indicating packet is
|
||||
* whole. */
|
||||
#define FRAG_YES_NOTLAST 1 /**< Fragment type indicating packet is
|
||||
* part of a fragmented packet, but not
|
||||
* the last part in the sequence. */
|
||||
#define FRAG_YES_LAST 2 /**< Fragment type indicating packet is
|
||||
* the last part in the sequence of
|
||||
* parts. */
|
||||
#define FRAG_TEST 3 /**< Fragment type not implemented yet.
|
||||
* In the future might be used as a
|
||||
* control packet for establishing MTU
|
||||
* size. */
|
||||
|
||||
/* FRAG_SEQ_ID 8 bits */
|
||||
#define FRAG_SEQ_ID_MASK 0x000000ff
|
||||
#define FRAG_SEQ_ID_SHIFT 2
|
||||
/**< Bit mask for %fragment sequence ID. */
|
||||
#define FRAG_SEQ_ID_SHIFT 2 /**< Bit shift for %fragment sequence ID. */
|
||||
|
||||
/* FRAG_ID 5 bits */
|
||||
#define FRAG_ID_MASK 0x0000001f
|
||||
/**< Bit mask for %fragment ID. */
|
||||
#define FRAG_ID_SHIFT 10
|
||||
/**< Bit shift for %fragment ID. */
|
||||
|
||||
/*
|
||||
* FRAG_SIZE 14 bits
|
||||
*
|
||||
* IF FRAG_YES_LAST (FRAG_SIZE):
|
||||
* The max size of a fragment. If a fragment is not the last fragment in the packet,
|
||||
* then the fragment size is guaranteed to be equal to the max fragment size. Therefore,
|
||||
* The max size of a %fragment. If a %fragment is not the last %fragment in the packet,
|
||||
* then the %fragment size is guaranteed to be equal to the max %fragment size. Therefore,
|
||||
* max_frag_size is only sent over the wire if FRAG_LAST is set. Otherwise it is assumed
|
||||
* to be the actual fragment size received.
|
||||
* to be the actual %fragment size received.
|
||||
*/
|
||||
|
||||
/* FRAG_SIZE 14 bits */
|
||||
#define FRAG_SIZE_MASK 0x00003fff
|
||||
/**< Bit mask for %fragment size. */
|
||||
#define FRAG_SIZE_SHIFT 15
|
||||
#define FRAG_SIZE_ROUND_SHIFT 2 /* fragment/datagram sizes represented as multiple of 4 */
|
||||
|
||||
/**< Bit shift for %fragment size. */
|
||||
#define FRAG_SIZE_ROUND_SHIFT 2 /**< Bit shift for %fragment size rounding. */
|
||||
#define FRAG_SIZE_ROUND_MASK ((1 << FRAG_SIZE_ROUND_SHIFT) - 1)
|
||||
/**< Bit mask for %fragment size rounding. */
|
||||
|
||||
/*
|
||||
* FRAG_EXTRA 16 bits
|
||||
*
|
||||
* IF FRAG_WHOLE or FRAG_YES_NOTLAST, these 16 bits are available (not currently used)
|
||||
*/
|
||||
|
||||
/* FRAG_EXTRA 16 bits */
|
||||
#define FRAG_EXTRA_MASK 0x0000ffff
|
||||
/**< Bit mask for extra bits. */
|
||||
#define FRAG_EXTRA_SHIFT 15
|
||||
/**< Bit shift for extra bits. */
|
||||
|
||||
/*
|
||||
* Public functions
|
||||
/** @} name Fragment header *//********************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/** @name Functions for initialization and cleanup *//** @{ *//************/
|
||||
|
||||
/**
|
||||
* Allocate and initialize a \c fragment_master structure.
|
||||
*
|
||||
* This function also modifies the \a frame packet geometry parameters to
|
||||
* include space for the fragmentation header.
|
||||
*
|
||||
* @param frame - The packet geometry parameters for this VPN
|
||||
* tunnel, modified by this function to include the
|
||||
* fragmentation header.
|
||||
*
|
||||
* @return A pointer to the new \c fragment_master structure.
|
||||
*/
|
||||
|
||||
struct fragment_master *fragment_init (struct frame *frame);
|
||||
|
||||
|
||||
/**
|
||||
* Allocate internal packet buffers for a \c fragment_master structure.
|
||||
*
|
||||
* @param f - The \c fragment_master structure for which to
|
||||
* allocate the internal buffers.
|
||||
* @param frame - The packet geometry parameters for this VPN
|
||||
* tunnel, used to determine how much memory to
|
||||
* allocate for each packet buffer.
|
||||
*/
|
||||
void fragment_frame_init (struct fragment_master *f, const struct frame *frame);
|
||||
|
||||
|
||||
/**
|
||||
* Free a \c fragment_master structure and its internal packet buffers.
|
||||
*
|
||||
* @param f - The \c fragment_master structure to free.
|
||||
*/
|
||||
void fragment_free (struct fragment_master *f);
|
||||
|
||||
/** @} name Functions for initialization and cleanup *//*******************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/** @name Functions for processing packets received from a remote OpenVPN peer */
|
||||
/** @{ */
|
||||
|
||||
/**
|
||||
* Process an incoming packet, which may or may not be fragmented.
|
||||
*
|
||||
* This function inspects the fragmentation header of the incoming packet
|
||||
* and processes the packet accordingly. Depending on the %fragment type
|
||||
* bits (\c FRAG_TYPE_MASK and \c FRAG_TYPE_SHIFT) the packet is processed
|
||||
* in the following ways:
|
||||
* - \c FRAG_WHOLE: the packet is not fragmented, and this function does
|
||||
* not modify its contents, except for removing the fragmentation
|
||||
* header.
|
||||
* - \c FRAG_YES_NOTLAST or \c FRAG_YES_LAST: the packet is part of a
|
||||
* fragmented packet. This function copies the packet into an internal
|
||||
* reassembly buffer. If the incoming part completes the packet being
|
||||
* reassembled, the \a buf argument is modified to point to the fully
|
||||
* reassembled packet. If, on the other hand, reassembly is not yet
|
||||
* complete, then the the \a buf buffer is set to empty.
|
||||
* - Any other value: error.
|
||||
*
|
||||
* If an error occurs during processing, an error message is logged and
|
||||
* the length of \a buf is set to zero.
|
||||
*
|
||||
* @param f - The \c fragment_master structure for this VPN
|
||||
* tunnel.
|
||||
* @param buf - A pointer to the buffer structure containing the
|
||||
* incoming packet. This pointer will have been
|
||||
* modified on return either to point to a
|
||||
* completely reassembled packet, or to have length
|
||||
* set to zero if reassembly is not yet complete.
|
||||
* @param frame - The packet geometry parameters for this VPN
|
||||
* tunnel.
|
||||
*
|
||||
* @return Void.\n On return, the \a buf argument will point to a buffer.
|
||||
* The buffer will have nonzero length if the incoming packet passed
|
||||
* to this function was whole and unfragmented, or if it was the final
|
||||
* part of a fragmented packet thereby completing reassembly. On the
|
||||
* other hand, the buffer will have a length of zero if the incoming
|
||||
* packet was part of a fragmented packet and reassembly is not yet
|
||||
* complete. If an error occurs during processing, the buffer length
|
||||
* is also set to zero.
|
||||
*/
|
||||
void fragment_incoming (struct fragment_master *f, struct buffer *buf,
|
||||
const struct frame* frame);
|
||||
|
||||
/** @} name Functions for processing packets received from a VPN tunnel */
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/** @name Functions for processing packets to be sent to a remote OpenVPN peer */
|
||||
/** @{ */
|
||||
|
||||
/**
|
||||
* Process an outgoing packet, which may or may not need to be fragmented.
|
||||
*
|
||||
* This function inspects the outgoing packet, determines whether it needs
|
||||
* to be fragmented, and processes it accordingly.
|
||||
*
|
||||
* Depending on the size of the outgoing packet and the packet geometry
|
||||
* parameters for the VPN tunnel, the packet will or will not be
|
||||
* fragmented.
|
||||
* @li Packet size is less than or equal to the maximum packet size for
|
||||
* this VPN tunnel: fragmentation is not necessary. The \a buf
|
||||
* argument points to a buffer containing the unmodified outgoing
|
||||
* packet with a fragmentation header indicating the packet is whole
|
||||
* (FRAG_WHOLE) prepended.
|
||||
* @li Packet size is greater than the maximum packet size for this VPN
|
||||
* tunnel: fragmentation is necessary. The original outgoing packet
|
||||
* is copied into an internal buffer for fragmentation. The \a buf
|
||||
* argument is modified to point to the first part of the fragmented
|
||||
* packet. The remaining parts remain stored in the internal buffer,
|
||||
* and can be retrieved using the \c fragment_ready_to_send()
|
||||
* function.
|
||||
*
|
||||
* If an error occurs during processing, an error message is logged and
|
||||
* the length of \a buf is set to zero.
|
||||
*
|
||||
* @param f - The \c fragment_master structure for this VPN
|
||||
* tunnel.
|
||||
* @param buf - A pointer to the buffer structure containing the
|
||||
* outgoing packet. This pointer will be modified
|
||||
* to point to a whole unfragmented packet or to the
|
||||
* first part of a fragmented packet on return.
|
||||
* @param frame - The packet geometry parameters for this VPN
|
||||
* tunnel.
|
||||
*
|
||||
* @return Void.\n On return, the \a buf argument will point to a buffer.
|
||||
* This buffer contains either the whole original outgoing packet if
|
||||
* fragmentation was not necessary, or the first part of the
|
||||
* fragmented outgoing packet if fragmentation was necessary. In both
|
||||
* cases a fragmentation header will have been prepended to inform the
|
||||
* remote peer how to handle the packet.
|
||||
*/
|
||||
void fragment_outgoing (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.
|
||||
*
|
||||
* This function checks whether the internal buffer for fragmenting
|
||||
* outgoing packets contains any unsent parts. If it does not, meaning
|
||||
* there is nothing waiting to be sent, it returns false. Otherwise there
|
||||
* are parts ready to be sent, and it returns true. In that case it also
|
||||
* modifies the \a buf argument to point to a buffer containing the next
|
||||
* part to be sent.
|
||||
*
|
||||
* @param f - The \a fragment_master structure for this VPN
|
||||
* tunnel.
|
||||
* @param buf - A pointer to a buffer structure which on return,
|
||||
* if there are parts waiting to be sent, will point
|
||||
* to the next part to be sent.
|
||||
* @param frame - The packet geometry parameters for this VPN
|
||||
* tunnel.
|
||||
*
|
||||
* @return
|
||||
* @li True, if an outgoing packet has been fragmented and not all parts
|
||||
* have been sent yet. In this case this function will modify the \a
|
||||
* buf argument to point to a buffer containing the next part to be
|
||||
* sent.
|
||||
* @li False, if there are no outgoing fragmented parts waiting to be
|
||||
* sent.
|
||||
*/
|
||||
bool fragment_ready_to_send (struct fragment_master *f, struct buffer *buf,
|
||||
const struct frame* frame);
|
||||
|
||||
/*
|
||||
* Private functions.
|
||||
/**
|
||||
* Check whether a \c fragment_master structure contains fragments ready
|
||||
* to be sent.
|
||||
*
|
||||
* @param f - The \c fragment_master structure for this VPN
|
||||
* tunnel.
|
||||
*
|
||||
* @return
|
||||
* @li True, if there are one or more fragments ready to be sent.
|
||||
* @li False, otherwise.
|
||||
*/
|
||||
static inline bool
|
||||
fragment_outgoing_defined (struct fragment_master *f)
|
||||
{
|
||||
return f->outgoing.len > 0;
|
||||
}
|
||||
|
||||
/** @} name Functions for processing packets going out through a VPN tunnel */
|
||||
|
||||
|
||||
void fragment_wakeup (struct fragment_master *f, struct frame *frame);
|
||||
|
||||
/*
|
||||
* Inline functions
|
||||
*/
|
||||
|
||||
/**************************************************************************/
|
||||
/** @name Functions for regular housekeeping *//** @{ *//******************/
|
||||
|
||||
/**
|
||||
* Perform housekeeping of a \c fragment_master structure.
|
||||
*
|
||||
* Housekeeping includes scanning incoming packet reassembly buffers for
|
||||
* packets which have not yet been reassembled completely but are already
|
||||
* older than their time-to-live.
|
||||
*
|
||||
* @param f - The \c fragment_master structure for this VPN
|
||||
* tunnel.
|
||||
* @param frame - The packet geometry parameters for this VPN
|
||||
* tunnel.
|
||||
*/
|
||||
static inline void
|
||||
fragment_housekeeping (struct fragment_master *f, struct frame *frame, struct timeval *tv)
|
||||
{
|
||||
|
|
@ -178,11 +469,11 @@ fragment_housekeeping (struct fragment_master *f, struct frame *frame, struct ti
|
|||
fragment_wakeup (f, frame);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
fragment_outgoing_defined (struct fragment_master *f)
|
||||
{
|
||||
return f->outgoing.len > 0;
|
||||
}
|
||||
/** @} name Functions for regular housekeeping *//*************************/
|
||||
|
||||
|
||||
/** @} addtogroup fragmentation *//****************************************/
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in a new issue