📄 fragment.h
字号:
/* * OpenVPN -- An application to securely tunnel IP networks * over a single UDP port, with support for SSL/TLS-based * session authentication and key exchange, * packet encryption, packet authentication, and * packet compression. * * Copyright (C) 2002-2003 James Yonan <jim@yonan.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * 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 */#ifndef FRAGMENT_H#define FRAGMENT_H#ifdef FRAGMENT_ENABLE#include "common.h"#include "buffer.h"#include "interval.h"#include "mtu.h"#include "shaper.h"#include "error.h"#define N_FRAG_BUF 10 /* number of packet buffers, should be <= N_FRAG_ID */#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 */struct fragment { bool defined; 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 */ unsigned int map; time_t timestamp; /* timestamp for time-to-live purposes */ struct buffer buf; /* fragment assembly buffer for received datagrams */};struct fragment_list { int seq_id; int index; struct fragment fragments[N_FRAG_BUF];};struct fragment_master { /* buffer to return "fragmentation needed but DF set" messages? */ struct buffer icmp_buf; struct event_timeout wakeup; /* when should main openvpn event loop wake us up */ /* keep track of largest packet size which was successfully received by peer */ int max_packet_size_received; /* zeroed after send to peer */ int max_packet_size_sent; /* without confirming receipt */ int max_packet_size_sent_sync; /* kept in temporal sync with max_packet_size_sent_confirmed */ int max_packet_size_sent_pending; /* queued but not yet sent */ int max_packet_size_sent_confirmed; /* confirmed by peer */ /* 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 to code in openvpn.c */ /* incoming fragments from remote */ struct fragment_list incoming;};/* * Fragment header sent over the wire. */typedef uint32_t fragment_header_type;/* convert a fragment_header_type from host to network order */#define hton_fragment_header_type(x) htonl(x)/* convert a fragment_header_type from network to host order */#define ntoh_fragment_header_type(x) ntohl(x)/* FRAG_TYPE 2 bits */#define FRAG_TYPE_MASK 0x00000003#define FRAG_TYPE_SHIFT 0#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 *//* FRAG_SEQ_ID 8 bits */#define FRAG_SEQ_ID_MASK 0x000000ff#define FRAG_SEQ_ID_SHIFT 2/* FRAG_ID 5 bits */#define FRAG_ID_MASK 0x0000001f#define FRAG_ID_SHIFT 10/* * 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, * 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. *//* FRAG_SIZE 14 bits */#define FRAG_SIZE_MASK 0x00003fff#define FRAG_SIZE_SHIFT 15#define FRAG_SIZE_ROUND_SHIFT 2 /* fragment/datagram sizes represented as multiple of 4 */#define FRAG_SIZE_ROUND_MASK ((1 << FRAG_SIZE_ROUND_SHIFT) - 1)/* * FRAG_EXTRA 16 bits * * IF FRAG_WHOLE or FRAG_YES_NOTLAST * Max packet size received recently, or 0 if no packets received. * The sender will reset its stored version to 0 after each send. *//* FRAG_EXTRA 16 bits */#define FRAG_EXTRA_MASK 0x0000ffff#define FRAG_EXTRA_SHIFT 15/* * Public functions */struct fragment_master *fragment_init (struct frame *frame);void fragment_frame_init (struct fragment_master *f, const struct frame *frame, bool generate_icmp);void fragment_free (struct fragment_master *f);void fragment_incoming (struct fragment_master *f, struct buffer *buf, const struct frame* frame, const time_t current);void fragment_outgoing (struct fragment_master *f, struct buffer *buf, const struct frame* frame, const time_t current);bool fragment_ready_to_send (struct fragment_master *f, struct buffer *buf, const struct frame* frame);void fragment_check_fragmentability (struct fragment_master *f, struct frame *frame_fragment, struct buffer *buf);/* * Private functions. */void fragment_wakeup (struct fragment_master *f, struct frame *frame, time_t current);/* * Inline functions */static inline voidfragment_housekeeping (struct fragment_master *f, struct frame *frame, time_t current, struct timeval *tv){ if (event_timeout_trigger (&f->wakeup, current)) fragment_wakeup (f, frame, current); event_timeout_wakeup (&f->wakeup, current, tv);}static inline boolfragment_outgoing_defined (struct fragment_master *f){ return f->outgoing.len > 0;}static inline boolfragment_icmp (struct fragment_master *f, struct buffer *buf){ if (f->icmp_buf.len > 0) { *buf = f->icmp_buf; f->icmp_buf.len = 0; return true; } else return false;}static inline voidfragment_post_send (struct fragment_master *f, int len){ f->max_packet_size_sent = max_int (f->max_packet_size_sent, f->max_packet_size_sent_pending);}#endif /* FRAGMENT_ENABLE */#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -