2 * OpenVPN -- An application to securely tunnel IP networks
3 * over a single UDP port, with support for SSL/TLS-based
4 * session authentication and key exchange,
5 * packet encryption, packet authentication, and
8 * Copyright (C) 2002-2009 OpenVPN Technologies, Inc. <sales@openvpn.net>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program (see the file COPYING included with this
21 * distribution); if not, write to the Free Software Foundation, Inc.,
22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #ifdef ENABLE_FRAGMENT
37 #define N_FRAG_BUF 25 /* number of packet buffers */
38 #define FRAG_TTL_SEC 10 /* number of seconds time-to-live for a fragment */
39 #define FRAG_WAKEUP_INTERVAL 5 /* wakeup code called once per n seconds */
44 int max_frag_size
; /* maximum size of each fragment */
47 * 32 bit array corresponding to each fragment. A 1 bit in element n means that
48 * the fragment n has been received. Needs to have at least MAX_FRAGS bits.
50 # define FRAG_MAP_MASK 0xFFFFFFFF
51 # define MAX_FRAGS 32 /* maximum number of fragments per packet */
54 time_t timestamp
; /* timestamp for time-to-live purposes */
56 struct buffer buf
; /* fragment assembly buffer for received datagrams */
59 struct fragment_list
{
62 struct fragment fragments
[N_FRAG_BUF
];
65 struct fragment_master
{
66 struct event_timeout wakeup
; /* when should main openvpn event loop wake us up */
68 /* true if the OS has explicitly recommended an MTU value */
69 bool received_os_mtu_hint
;
71 /* a sequence ID describes a set of fragments that make up one datagram */
72 # define N_SEQ_ID 256 /* sequence number wraps to 0 at this value (should be a power of 2) */
73 int outgoing_seq_id
; /* sent as FRAG_SEQ_ID below */
75 /* outgoing packet is possibly sent as a series of fragments */
77 # define MAX_FRAG_PKT_SIZE 65536 /* maximum packet size */
78 int outgoing_frag_size
; /* sent to peer via FRAG_SIZE when FRAG_YES_LAST set */
80 int outgoing_frag_id
; /* each fragment in a datagram is numbered 0 to MAX_FRAGS-1 */
82 struct buffer outgoing
; /* outgoing datagram, free if current_frag_id == 0 */
83 struct buffer outgoing_return
; /* buffer to return outgoing fragment */
85 /* incoming fragments from remote */
86 struct fragment_list incoming
;
90 * Fragment header sent over the wire.
93 typedef uint32_t fragment_header_type
;
95 /* convert a fragment_header_type from host to network order */
96 #define hton_fragment_header_type(x) htonl(x)
98 /* convert a fragment_header_type from network to host order */
99 #define ntoh_fragment_header_type(x) ntohl(x)
101 /* FRAG_TYPE 2 bits */
102 #define FRAG_TYPE_MASK 0x00000003
103 #define FRAG_TYPE_SHIFT 0
105 #define FRAG_WHOLE 0 /* packet is whole, FRAG_N_PACKETS_RECEIVED echoed back to peer */
106 #define FRAG_YES_NOTLAST 1 /* packet is a fragment, but is not the last fragment,
107 FRAG_N_PACKETS_RECEIVED set as above */
108 #define FRAG_YES_LAST 2 /* packet is the last fragment, FRAG_SIZE = size of non-last frags */
109 #define FRAG_TEST 3 /* control packet for establishing MTU size (not implemented yet) */
111 /* FRAG_SEQ_ID 8 bits */
112 #define FRAG_SEQ_ID_MASK 0x000000ff
113 #define FRAG_SEQ_ID_SHIFT 2
116 #define FRAG_ID_MASK 0x0000001f
117 #define FRAG_ID_SHIFT 10
122 * IF FRAG_YES_LAST (FRAG_SIZE):
123 * The max size of a fragment. If a fragment is not the last fragment in the packet,
124 * then the fragment size is guaranteed to be equal to the max fragment size. Therefore,
125 * max_frag_size is only sent over the wire if FRAG_LAST is set. Otherwise it is assumed
126 * to be the actual fragment size received.
129 /* FRAG_SIZE 14 bits */
130 #define FRAG_SIZE_MASK 0x00003fff
131 #define FRAG_SIZE_SHIFT 15
132 #define FRAG_SIZE_ROUND_SHIFT 2 /* fragment/datagram sizes represented as multiple of 4 */
134 #define FRAG_SIZE_ROUND_MASK ((1 << FRAG_SIZE_ROUND_SHIFT) - 1)
139 * IF FRAG_WHOLE or FRAG_YES_NOTLAST, these 16 bits are available (not currently used)
142 /* FRAG_EXTRA 16 bits */
143 #define FRAG_EXTRA_MASK 0x0000ffff
144 #define FRAG_EXTRA_SHIFT 15
150 struct fragment_master
*fragment_init (struct frame
*frame
);
152 void fragment_frame_init (struct fragment_master
*f
, const struct frame
*frame
);
154 void fragment_free (struct fragment_master
*f
);
156 void fragment_incoming (struct fragment_master
*f
, struct buffer
*buf
,
157 const struct frame
* frame
);
159 void fragment_outgoing (struct fragment_master
*f
, struct buffer
*buf
,
160 const struct frame
* frame
);
162 bool fragment_ready_to_send (struct fragment_master
*f
, struct buffer
*buf
,
163 const struct frame
* frame
);
168 void fragment_wakeup (struct fragment_master
*f
, struct frame
*frame
);
175 fragment_housekeeping (struct fragment_master
*f
, struct frame
*frame
, struct timeval
*tv
)
177 if (event_timeout_trigger (&f
->wakeup
, tv
, ETT_DEFAULT
))
178 fragment_wakeup (f
, frame
);
182 fragment_outgoing_defined (struct fragment_master
*f
)
184 return f
->outgoing
.len
> 0;