Attention is currently required from: plaisthos.
Hello plaisthos,
I'd like you to do a code review.
Please visit
http://gerrit.openvpn.net/c/openvpn/+/1741?usp=email
to review the following change.
Change subject: oob: Add control message TLV encoding (P_CONTROL_OOB_V1)
......................................................................
oob: Add control message TLV encoding (P_CONTROL_OOB_V1)
Reserve opcode 12 (P_CONTROL_OOB_V1) for out-of-band control messages and
add encoding/decoding for the SERVER_PROBE / PROBE_REPLY TLVs used for
server latency checks:
- probe_parameter (0x200): client timestamp + capability flags
- probe_reply (0x201): echoed session id, DNS-SRV style priority and
weight, connect_lifetime and behaviour flags
Each TLV has a 4-byte header (15-bit type plus an optional flag, then a
16-bit value length). Readers enforce the minimum value length and skip
trailing bytes they do not understand, so the format stays forward
compatible and multi-TLV framing resynchronises.
P_LAST_OPCODE is deliberately left at 11: opcode 12 is not yet accepted by
tls_pre_decrypt(). The legal-opcode range is widened together with the
receive handler in a follow-up, which also wires oob.c into the openvpn
build. For now the codec is exercised only by the unit tests.
See the OOB control message section of the OpenVPN wire protocol
specification (openvpn-rfc PR #30).
Change-Id: I1c8d302ac57c5603d622a7be14be369437388268
Signed-off-by: Lev Stipakov <[email protected]>
---
M CMakeLists.txt
A src/openvpn/oob.c
A src/openvpn/oob.h
M src/openvpn/ssl_pkt.h
M tests/unit_tests/openvpn/Makefile.am
A tests/unit_tests/openvpn/test_oob.c
6 files changed, 524 insertions(+), 0 deletions(-)
git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/41/1741/1
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8de836a..d2b88c0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -665,6 +665,7 @@
"test_mbuf"
"test_misc"
"test_ncp"
+ "test_oob"
"test_options_parse"
"test_packet_id"
"test_pkt"
@@ -855,6 +856,12 @@
src/openvpn/session_id.c
)
+ target_sources(test_oob PRIVATE
+ tests/unit_tests/openvpn/mock_get_random.c
+ src/openvpn/oob.c
+ src/openvpn/session_id.c
+ )
+
target_sources(test_pkt PRIVATE
tests/unit_tests/openvpn/mock_win32_execve.c
src/openvpn/argv.c
diff --git a/src/openvpn/oob.c b/src/openvpn/oob.c
new file mode 100644
index 0000000..9f123e2
--- /dev/null
+++ b/src/openvpn/oob.c
@@ -0,0 +1,154 @@
+/*
+ * 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) 2002-2026 OpenVPN Inc <[email protected]>
+ *
+ * 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; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "syshead.h"
+
+#include "oob.h"
+
+/* Consume @p value_len bytes of TLV value, of which @p consumed have already
+ * been read, ignoring (skipping) any trailing bytes that this version does not
+ * understand. Fails if fewer than @p consumed bytes were declared. */
+static bool
+oob_skip_trailing(struct buffer *buf, uint16_t value_len, int consumed)
+{
+ if (value_len < consumed)
+ {
+ return false;
+ }
+ return buf_advance(buf, value_len - consumed);
+}
+
+bool
+oob_msg_write_header(struct buffer *buf, uint16_t msg_type)
+{
+ return buf_write_u16(buf, msg_type);
+}
+
+bool
+oob_msg_read_header(struct buffer *buf, uint16_t expected_msg_type)
+{
+ int msg_type = buf_read_u16(buf);
+ return msg_type >= 0 && (uint16_t)msg_type == expected_msg_type;
+}
+
+bool
+oob_tlv_write_header(struct buffer *buf, uint16_t type, bool optional,
uint16_t value_len)
+{
+ uint16_t field = type & OOB_TLV_TYPE_MASK;
+ if (optional)
+ {
+ field |= OOB_TLV_OPTIONAL_FLAG;
+ }
+ return buf_write_u16(buf, field) && buf_write_u16(buf, value_len);
+}
+
+bool
+oob_tlv_read_header(struct buffer *buf, uint16_t *type, bool *optional,
uint16_t *value_len)
+{
+ int field = buf_read_u16(buf);
+ if (field < 0)
+ {
+ return false;
+ }
+ int len = buf_read_u16(buf);
+ if (len < 0)
+ {
+ return false;
+ }
+ *type = (uint16_t)(field & OOB_TLV_TYPE_MASK);
+ *optional = (field & OOB_TLV_OPTIONAL_FLAG) != 0;
+ *value_len = (uint16_t)len;
+ return true;
+}
+
+bool
+oob_probe_parameter_write(struct buffer *buf, const struct oob_probe_parameter
*p)
+{
+ return oob_tlv_write_header(buf, OOB_TLV_PROBE_PARAMETER, false,
OOB_PROBE_PARAMETER_LEN)
+ && buf_write_u64(buf, p->timestamp)
+ && buf_write_u32(buf, p->flags);
+}
+
+bool
+oob_probe_parameter_read(struct buffer *buf, struct oob_probe_parameter *p,
uint16_t value_len)
+{
+ if (value_len < OOB_PROBE_PARAMETER_LEN)
+ {
+ return false;
+ }
+ bool ok = true;
+ p->timestamp = buf_read_u64(buf, &ok);
+ p->flags = buf_read_u32(buf, &ok);
+ if (!ok)
+ {
+ return false;
+ }
+ return oob_skip_trailing(buf, value_len, OOB_PROBE_PARAMETER_LEN);
+}
+
+bool
+oob_probe_reply_write(struct buffer *buf, const struct oob_probe_reply *r)
+{
+ return oob_tlv_write_header(buf, OOB_TLV_PROBE_REPLY, false,
OOB_PROBE_REPLY_LEN)
+ && session_id_write(&r->peer_session_id, buf)
+ && buf_write_u16(buf, r->priority)
+ && buf_write_u16(buf, r->weight)
+ && buf_write_u16(buf, r->connect_lifetime)
+ && buf_write_u32(buf, r->flags)
+ && buf_write_u16(buf, r->max_latency_diff);
+}
+
+bool
+oob_probe_reply_read(struct buffer *buf, struct oob_probe_reply *r, uint16_t
value_len)
+{
+ if (value_len < OOB_PROBE_REPLY_LEN)
+ {
+ return false;
+ }
+ if (!session_id_read(&r->peer_session_id, buf))
+ {
+ return false;
+ }
+ int priority = buf_read_u16(buf);
+ int weight = buf_read_u16(buf);
+ int connect_lifetime = buf_read_u16(buf);
+ if (priority < 0 || weight < 0 || connect_lifetime < 0)
+ {
+ return false;
+ }
+ bool ok = true;
+ r->flags = buf_read_u32(buf, &ok);
+ int max_latency_diff = buf_read_u16(buf);
+ if (!ok || max_latency_diff < 0)
+ {
+ return false;
+ }
+ r->priority = (uint16_t)priority;
+ r->weight = (uint16_t)weight;
+ r->connect_lifetime = (uint16_t)connect_lifetime;
+ r->max_latency_diff = (uint16_t)max_latency_diff;
+ return oob_skip_trailing(buf, value_len, OOB_PROBE_REPLY_LEN);
+}
diff --git a/src/openvpn/oob.h b/src/openvpn/oob.h
new file mode 100644
index 0000000..c32a7db
--- /dev/null
+++ b/src/openvpn/oob.h
@@ -0,0 +1,147 @@
+/*
+ * 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) 2002-2026 OpenVPN Inc <[email protected]>
+ *
+ * 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; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+/**
+ * @file
+ * Encoding/decoding of out-of-band (P_CONTROL_OOB_V1) control messages.
+ *
+ * An OOB message payload starts with a 16-bit message type (the 0x1xx space:
+ * SERVER_PROBE, PROBE_REPLY, ...) followed by a sequence of TLV entries.
+ *
+ * Each TLV starts with a 4-byte header: a 16-bit field whose most significant
+ * bit is the "optional" flag and whose remaining 15 bits are the type (the
+ * 0x2xx space), followed by a 16-bit length giving the size of the value that
+ * follows the header.
+ *
+ * This slice implements the SERVER_PROBE / PROBE_REPLY pair used for server
+ * latency checks. Other message/TLV types are added as the feature grows.
+ */
+
+#ifndef OOB_H
+#define OOB_H
+
+#include "buffer.h"
+#include "session_id.h"
+
+/* OOB message types: the 16-bit value at the start of an OOB payload, before
+ * its TLV entries. Distinct from the TLV-type space (0x2xx); see the
"Messages"
+ * table in the OOB section of the wire protocol spec. */
+#define OOB_MSG_SERVER_PROBE 0x100
+#define OOB_MSG_PROBE_REPLY 0x101
+
+/* TLV header bit layout of the first 16-bit field */
+#define OOB_TLV_OPTIONAL_FLAG 0x8000
+#define OOB_TLV_TYPE_MASK 0x7fff
+
+/* TLV types (see the OOB control message section of the wire protocol spec) */
+#define OOB_TLV_PROBE_PARAMETER 0x200
+#define OOB_TLV_PROBE_REPLY 0x201
+
+/* Minimum on-wire value length (excluding the 4-byte TLV header) of each TLV.
+ * The value may be longer for forward compatibility; trailing bytes that are
+ * not understood are ignored on read. */
+#define OOB_PROBE_PARAMETER_LEN 12
+#define OOB_PROBE_REPLY_LEN 20
+
+/* probe parameter TLV (sent by the client in a SERVER_PROBE) */
+struct oob_probe_parameter
+{
+ uint64_t timestamp; /**< client clock as a UNIX timestamp */
+ uint32_t flags; /**< client capability flags, currently must be 0 */
+};
+
+/* probe reply TLV (sent by the server in a PROBE_REPLY) */
+struct oob_probe_reply
+{
+ struct session_id peer_session_id; /**< echoes the session id of the
request */
+ uint16_t priority; /**< DNS-SRV style priority (lower is
preferred) */
+ uint16_t weight; /**< DNS-SRV style weight */
+ uint16_t connect_lifetime; /**< seconds the probe stays valid as a
handshake shortcut */
+ uint32_t flags; /**< server behaviour flags */
+ uint16_t max_latency_diff; /**< advertised candidate-band margin
in ms;
+ * 0 means "defer to the client's
setting" */
+};
+
+/**
+ * Write an OOB message-type header (the 16-bit message type preceding the
+ * TLVs) to @p buf.
+ *
+ * @return true on success, false if @p buf has insufficient space.
+ */
+bool oob_msg_write_header(struct buffer *buf, uint16_t msg_type);
+
+/**
+ * Read and verify an OOB message-type header from @p buf, advancing past it.
+ *
+ * @param expected_msg_type the message type the payload must carry
+ * @return true if a message type was read and equals @p expected_msg_type,
+ * false on a short buffer or a mismatching type.
+ */
+bool oob_msg_read_header(struct buffer *buf, uint16_t expected_msg_type);
+
+/**
+ * Write a TLV header (type + optional flag + value length) to @p buf.
+ *
+ * @return true on success, false if @p buf has insufficient space.
+ */
+bool oob_tlv_write_header(struct buffer *buf, uint16_t type, bool optional,
uint16_t value_len);
+
+/**
+ * Read a TLV header from @p buf, advancing past it.
+ *
+ * @param type set to the 15-bit TLV type
+ * @param optional set to the value of the optional flag
+ * @param value_len set to the declared value length
+ * @return true on success, false if there are not enough bytes for a header.
+ */
+bool oob_tlv_read_header(struct buffer *buf, uint16_t *type, bool *optional,
uint16_t *value_len);
+
+/**
+ * Write a complete probe parameter TLV (header + value) to @p buf.
+ */
+bool oob_probe_parameter_write(struct buffer *buf, const struct
oob_probe_parameter *p);
+
+/**
+ * Read a probe parameter TLV value of @p value_len bytes from @p buf.
+ *
+ * The TLV header must already have been consumed (e.g. via
+ * oob_tlv_read_header()). @p value_len bytes are always consumed on success,
+ * including any trailing bytes beyond the fields understood here.
+ *
+ * @return true on success, false if @p value_len is too short or @p buf is
+ * truncated.
+ */
+bool oob_probe_parameter_read(struct buffer *buf, struct oob_probe_parameter
*p,
+ uint16_t value_len);
+
+/**
+ * Write a complete probe reply TLV (header + value) to @p buf.
+ */
+bool oob_probe_reply_write(struct buffer *buf, const struct oob_probe_reply
*r);
+
+/**
+ * Read a probe reply TLV value of @p value_len bytes from @p buf. See
+ * oob_probe_parameter_read() for the calling convention.
+ */
+bool oob_probe_reply_read(struct buffer *buf, struct oob_probe_reply *r,
uint16_t value_len);
+
+#endif /* OOB_H */
diff --git a/src/openvpn/ssl_pkt.h b/src/openvpn/ssl_pkt.h
index ac9d4be..0dab524 100644
--- a/src/openvpn/ssl_pkt.h
+++ b/src/openvpn/ssl_pkt.h
@@ -58,6 +58,17 @@
* like P_CONTROL_HARD_RESET_CLIENT_V3 */
#define P_CONTROL_WKC_V1 11
+/* Out-of-band control message that does not belong to an established
+ * control channel session (e.g. a server probe). Inherently unreliable:
+ * there is no protocol-level retransmission.
+ *
+ * NOTE: intentionally not yet included in the P_FIRST_OPCODE..P_LAST_OPCODE
+ * legal range. The range acts as an acceptance gate in tls_pre_decrypt();
+ * widening it before an OOB receive handler exists would let OOB packets
+ * be misparsed as established-session control packets. Bump P_LAST_OPCODE
+ * to 12 in the same change that adds the handler. */
+#define P_CONTROL_OOB_V1 12
+
/* define the range of legal opcodes
* Since we do no longer support key-method 1 we consider
* the v1 op codes invalid */
@@ -266,6 +277,9 @@
case P_CONTROL_WKC_V1:
return "P_CONTROL_WKC_V1";
+ case P_CONTROL_OOB_V1:
+ return "P_CONTROL_OOB_V1";
+
case P_ACK_V1:
return "P_ACK_V1";
diff --git a/tests/unit_tests/openvpn/Makefile.am
b/tests/unit_tests/openvpn/Makefile.am
index 1128eb4..7174aa8 100644
--- a/tests/unit_tests/openvpn/Makefile.am
+++ b/tests/unit_tests/openvpn/Makefile.am
@@ -14,6 +14,7 @@
ncp_testdriver \
mbuf_testdriver \
misc_testdriver \
+ oob_testdriver \
options_parse_testdriver \
packet_id_testdriver \
pkt_testdriver \
@@ -149,6 +150,19 @@
$(top_srcdir)/src/openvpn/win32-util.c \
$(top_srcdir)/src/openvpn/session_id.c
+oob_testdriver_CFLAGS = \
+ -I$(top_srcdir)/include -I$(top_srcdir)/src/compat
-I$(top_srcdir)/src/openvpn \
+ @TEST_CFLAGS@
+oob_testdriver_LDFLAGS = @TEST_LDFLAGS@
+oob_testdriver_SOURCES = test_oob.c \
+ mock_msg.c mock_msg.h test_common.h \
+ mock_get_random.c \
+ $(top_srcdir)/src/openvpn/buffer.c \
+ $(top_srcdir)/src/openvpn/oob.c \
+ $(top_srcdir)/src/openvpn/platform.c \
+ $(top_srcdir)/src/openvpn/session_id.c \
+ $(top_srcdir)/src/openvpn/win32-util.c
+
pkt_testdriver_CFLAGS = \
-I$(top_srcdir)/include -I$(top_srcdir)/src/compat
-I$(top_srcdir)/src/openvpn \
@TEST_CFLAGS@
diff --git a/tests/unit_tests/openvpn/test_oob.c
b/tests/unit_tests/openvpn/test_oob.c
new file mode 100644
index 0000000..40dcaf9
--- /dev/null
+++ b/tests/unit_tests/openvpn/test_oob.c
@@ -0,0 +1,188 @@
+/*
+ * 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) 2002-2026 OpenVPN Inc <[email protected]>
+ *
+ * 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; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "syshead.h"
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include "oob.h"
+#include "test_common.h"
+
+/* Write a probe parameter TLV and read it back; fields must survive the
+ * round trip and the whole buffer must be consumed. */
+static void
+test_probe_parameter_roundtrip(void **state)
+{
+ struct gc_arena gc = gc_new();
+ struct buffer buf = alloc_buf_gc(128, &gc);
+
+ const struct oob_probe_parameter in = {
+ .timestamp = 0x0123456789abcdefULL,
+ .flags = 0,
+ };
+ assert_true(oob_probe_parameter_write(&buf, &in));
+ /* header (4) + value (12) */
+ assert_int_equal(BLEN(&buf), 4 + OOB_PROBE_PARAMETER_LEN);
+
+ uint16_t type;
+ bool optional;
+ uint16_t value_len;
+ assert_true(oob_tlv_read_header(&buf, &type, &optional, &value_len));
+ assert_int_equal(type, OOB_TLV_PROBE_PARAMETER);
+ assert_false(optional);
+ assert_int_equal(value_len, OOB_PROBE_PARAMETER_LEN);
+
+ struct oob_probe_parameter out = { 0 };
+ assert_true(oob_probe_parameter_read(&buf, &out, value_len));
+ assert_true(in.timestamp == out.timestamp);
+ assert_int_equal(in.flags, out.flags);
+ assert_int_equal(BLEN(&buf), 0);
+
+ gc_free(&gc);
+}
+
+/* Write a probe reply TLV and read it back. */
+static void
+test_probe_reply_roundtrip(void **state)
+{
+ struct gc_arena gc = gc_new();
+ struct buffer buf = alloc_buf_gc(128, &gc);
+
+ struct oob_probe_reply in = {
+ .priority = 10,
+ .weight = 100,
+ .connect_lifetime = 30,
+ .flags = 1,
+ .max_latency_diff = 25,
+ };
+ memcpy(in.peer_session_id.id, "ABCDEFGH", SID_SIZE);
+
+ assert_true(oob_probe_reply_write(&buf, &in));
+ assert_int_equal(BLEN(&buf), 4 + OOB_PROBE_REPLY_LEN);
+
+ uint16_t type;
+ bool optional;
+ uint16_t value_len;
+ assert_true(oob_tlv_read_header(&buf, &type, &optional, &value_len));
+ assert_int_equal(type, OOB_TLV_PROBE_REPLY);
+ assert_int_equal(value_len, OOB_PROBE_REPLY_LEN);
+
+ struct oob_probe_reply out = { 0 };
+ assert_true(oob_probe_reply_read(&buf, &out, value_len));
+ assert_memory_equal(in.peer_session_id.id, out.peer_session_id.id,
SID_SIZE);
+ assert_int_equal(in.priority, out.priority);
+ assert_int_equal(in.weight, out.weight);
+ assert_int_equal(in.connect_lifetime, out.connect_lifetime);
+ assert_int_equal(in.flags, out.flags);
+ assert_int_equal(in.max_latency_diff, out.max_latency_diff);
+ assert_int_equal(BLEN(&buf), 0);
+
+ gc_free(&gc);
+}
+
+/* A TLV with a longer-than-known value must still parse: the known fields are
+ * read and the trailing bytes are skipped (forward compatibility). */
+static void
+test_probe_parameter_forward_compat(void **state)
+{
+ struct gc_arena gc = gc_new();
+ struct buffer buf = alloc_buf_gc(128, &gc);
+
+ const uint16_t extended_len = OOB_PROBE_PARAMETER_LEN + 4;
+ assert_true(oob_tlv_write_header(&buf, OOB_TLV_PROBE_PARAMETER, false,
extended_len));
+ assert_true(buf_write_u32(&buf, 0)); /* timestamp high */
+ assert_true(buf_write_u32(&buf, 0xdeadbeef)); /* timestamp low */
+ assert_true(buf_write_u32(&buf, 0)); /* flags */
+ assert_true(buf_write_u32(&buf, 0x11223344)); /* unknown trailing field */
+
+ uint16_t type;
+ bool optional;
+ uint16_t value_len;
+ assert_true(oob_tlv_read_header(&buf, &type, &optional, &value_len));
+ assert_int_equal(value_len, extended_len);
+
+ struct oob_probe_parameter out = { 0 };
+ assert_true(oob_probe_parameter_read(&buf, &out, value_len));
+ assert_true(out.timestamp == 0xdeadbeefULL);
+ assert_int_equal(out.flags, 0);
+ /* the unknown trailing field must have been consumed */
+ assert_int_equal(BLEN(&buf), 0);
+
+ gc_free(&gc);
+}
+
+/* A declared value length shorter than the mandatory minimum must be
rejected. */
+static void
+test_probe_parameter_too_short(void **state)
+{
+ struct gc_arena gc = gc_new();
+ struct buffer buf = alloc_buf_gc(128, &gc);
+
+ struct oob_probe_parameter out = { 0 };
+ assert_false(oob_probe_parameter_read(&buf, &out, OOB_PROBE_PARAMETER_LEN
- 1));
+
+ gc_free(&gc);
+}
+
+/* Reading a header from a buffer that is too small must fail rather than read
+ * past the end. */
+static void
+test_tlv_header_truncated(void **state)
+{
+ struct gc_arena gc = gc_new();
+ struct buffer buf = alloc_buf_gc(128, &gc);
+
+ uint16_t type;
+ bool optional;
+ uint16_t value_len;
+
+ /* empty buffer */
+ assert_false(oob_tlv_read_header(&buf, &type, &optional, &value_len));
+
+ /* only the type field present, no length */
+ assert_true(buf_write_u16(&buf, OOB_TLV_PROBE_PARAMETER));
+ assert_false(oob_tlv_read_header(&buf, &type, &optional, &value_len));
+
+ gc_free(&gc);
+}
+
+int
+main(void)
+{
+ openvpn_unit_test_setup();
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test(test_probe_parameter_roundtrip),
+ cmocka_unit_test(test_probe_reply_roundtrip),
+ cmocka_unit_test(test_probe_parameter_forward_compat),
+ cmocka_unit_test(test_probe_parameter_too_short),
+ cmocka_unit_test(test_tlv_header_truncated),
+ };
+
+ return cmocka_run_group_tests_name("oob tests", tests, NULL, NULL);
+}
--
To view, visit http://gerrit.openvpn.net/c/openvpn/+/1741?usp=email
To unsubscribe, or for help writing mail filters, visit
http://gerrit.openvpn.net/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: openvpn
Gerrit-Branch: master
Gerrit-Change-Id: I1c8d302ac57c5603d622a7be14be369437388268
Gerrit-Change-Number: 1741
Gerrit-PatchSet: 1
Gerrit-Owner: stipa <[email protected]>
Gerrit-Reviewer: plaisthos <[email protected]>
Gerrit-CC: openvpn-devel <[email protected]>
Gerrit-Attention: plaisthos <[email protected]>
_______________________________________________
Openvpn-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openvpn-devel