aboutsummaryrefslogtreecommitdiff
path: root/reliable.h
diff options
context:
space:
mode:
Diffstat (limited to 'reliable.h')
-rw-r--r--reliable.h162
1 files changed, 162 insertions, 0 deletions
diff --git a/reliable.h b/reliable.h
new file mode 100644
index 0000000..d498f64
--- /dev/null
+++ b/reliable.h
@@ -0,0 +1,162 @@
+/*
+ * 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-2005 OpenVPN Solutions LLC <info@openvpn.net>
+ *
+ * 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
+ */
+
+/*
+ * This routines implement a reliability layer on top of UDP,
+ * so that TLS can be run over UDP.
+ */
+
+#if defined(USE_CRYPTO) && defined(USE_SSL)
+
+#ifndef RELIABLE_H
+#define RELIABLE_H
+
+#include "basic.h"
+#include "buffer.h"
+#include "packet_id.h"
+#include "session_id.h"
+#include "mtu.h"
+
+/* #define EXPONENTIAL_BACKOFF */
+
+#define RELIABLE_ACK_SIZE 8
+
+struct reliable_ack
+{
+ int len;
+ packet_id_type packet_id[RELIABLE_ACK_SIZE];
+};
+
+/* no active buffers? */
+static inline bool
+reliable_ack_empty (struct reliable_ack *ack)
+{
+ return !ack->len;
+}
+
+/* get a packet_id from buf */
+bool reliable_ack_read_packet_id (struct buffer *buf, packet_id_type *pid);
+
+/* acknowledge a packet_id by adding it to a struct reliable_ack */
+bool reliable_ack_acknowledge_packet_id (struct reliable_ack *ack, packet_id_type pid);
+
+/* read a packet ID acknowledgement record from buf */
+bool reliable_ack_read (struct reliable_ack *ack,
+ struct buffer *buf, const struct session_id *sid);
+
+/* write a packet ID acknowledgement record to buf */
+bool reliable_ack_write (struct reliable_ack *ack,
+ struct buffer *buf,
+ const struct session_id *sid, int max, bool prepend);
+
+/* print a reliable ACK record coming off the wire */
+const char *reliable_ack_print (struct buffer *buf, bool verbose, struct gc_arena *gc);
+
+/* add to extra_frame the maximum number of bytes we will need for reliable_ack_write */
+void reliable_ack_adjust_frame_parameters (struct frame* frame, int max);
+
+void reliable_ack_debug_print (const struct reliable_ack *ack, char *desc);
+
+#define RELIABLE_CAPACITY 8
+
+struct reliable_entry
+{
+ bool active;
+ interval_t timeout;
+ time_t next_try;
+ packet_id_type packet_id;
+ int opcode;
+ struct buffer buf;
+};
+
+struct reliable
+{
+ int size;
+ interval_t initial_timeout;
+ packet_id_type packet_id;
+ int offset;
+ struct reliable_entry array[RELIABLE_CAPACITY];
+};
+
+void reliable_debug_print (const struct reliable *rel, char *desc);
+
+/* set sending timeout (after this time we send again until ACK) */
+static inline void
+reliable_set_timeout (struct reliable *rel, interval_t timeout)
+{
+ rel->initial_timeout = timeout;
+}
+
+void reliable_init (struct reliable *rel, int buf_size, int offset, int array_size);
+
+void reliable_free (struct reliable *rel);
+
+/* no active buffers? */
+bool reliable_empty (const struct reliable *rel);
+
+/* in how many seconds should we wake up to check for timeout */
+interval_t reliable_send_timeout (const struct reliable *rel);
+
+/* del acknowledged items from send buf */
+void reliable_send_purge (struct reliable *rel, struct reliable_ack *ack);
+
+/* true if at least one free buffer available */
+bool reliable_can_get (const struct reliable *rel);
+
+/* make sure that incoming packet ID isn't a replay */
+bool reliable_not_replay (const struct reliable *rel, packet_id_type id);
+
+/* make sure that incoming packet ID won't deadlock the receive buffer */
+bool reliable_wont_break_sequentiality (const struct reliable *rel, packet_id_type id);
+
+/* grab a free buffer */
+struct buffer *reliable_get_buf (struct reliable *rel);
+
+/* grab a free buffer, fail if buffer clogged by unacknowledged low packet IDs */
+struct buffer *reliable_get_buf_output_sequenced (struct reliable *rel);
+
+/* get active buffer for next sequentially increasing key ID */
+struct buffer *reliable_get_buf_sequenced (struct reliable *rel);
+
+/* return true if reliable_send would return a non-NULL result */
+bool reliable_can_send (const struct reliable *rel);
+
+/* return next buffer to send to remote */
+struct buffer *reliable_send (struct reliable *rel, int *opcode);
+
+/* schedule all pending packets for immediate retransmit */
+void reliable_schedule_now (struct reliable *rel);
+
+/* enable an incoming buffer previously returned by a get function as active */
+void reliable_mark_active_incoming (struct reliable *rel, struct buffer *buf,
+ packet_id_type pid, int opcode);
+
+/* enable an outgoing buffer previously returned by a get function as active. */
+void reliable_mark_active_outgoing (struct reliable *rel, struct buffer *buf, int opcode);
+
+/* delete a buffer previously activated by reliable_mark_active() */
+void reliable_mark_deleted (struct reliable *rel, struct buffer *buf, bool inc_pid);
+
+#endif /* RELIABLE_H */
+#endif /* USE_CRYPTO && USE_SSL */