http-proxy-user-pass too.
+Improved control channel packet size control (``max-packet-size``)
+ The size of control channel is no longer tied to
+ ``--link-mtu``/``--tun-mtu`` and can be set using ``--max-packet-size``.
+ Sending large control channel frames is also optimised by allowing 6
+ outstanding packets instead of just 4. ``max-packet-size`` will also set
+ ``mssfix`` to try to limit data-channel packets as well.
+
Deprecated features
-------------------
``inetd`` has been removed
- :code:`link_mtu` parameter is removed from environment or replaced with 0 when scripts are
called with parameters. This parameter is unreliable and no longer internally calculated.
+- control channel packet maximum size is no longer influenced by
+ ``--link-mtu``/``--tun-mtu`` and must be set by ``--max-packet-size`` now.
+ The default is 1250 for the control channel size.
+
- In point-to-point OpenVPN setups (no ``--server``), using
``--explict-exit-notiy`` on one end would terminate the other side at
session end. This is considered a no longer useful default and has
the first place, and if big packets come through anyhow (from protocols
other than TCP), ``--fragment`` will internally fragment them.
- Both ``--fragment`` and ``--mssfix`` are designed to work around cases
- where Path MTU discovery is broken on the network path between OpenVPN
- peers.
+ ``--max-packet-size``, ``--fragment``, and ``--mssfix`` are designed to
+ work around cases where Path MTU discovery is broken on the network path
+ between OpenVPN peers.
The usual symptom of such a breakdown is an OpenVPN connection which
successfully starts, but then stalls during active usage.
--tun-mtu 1500 --fragment 1300 --mssfix
+ If the ``max-packet-size size`` option is used in the configuration
+ it will also act as if ``mssfix size mtu`` was specified in the
+ configuration.
+
--mtu-disc type
Should we do Path MTU discovery on TCP/UDP channel? Only supported on
OSes such as Linux that supports the necessary system call to set.
if mode server:
socket-flags TCP_NODELAY
push "socket-flags TCP_NODELAY"
+
+--max-packet-size size
+ This option will instruct OpenVPN to try to limit the maximum on-write packet
+ size by restricting the control channel packet size and setting ``--mssfix``.
+
+ OpenVPN will try to keep its control channel messages below this size but
+ due to some constraints in the protocol this is not always possible. If the
+ option is not set, the control packet maximum size defaults to 1250.
+ The control channel packet size will be restricted to values between
+ 154 and 2048. The maximum packet size includes encapsulation overhead like
+ UDP and IP.
+
+ In terms of ``--mssfix`` it will expand to:
+ ::
+
+ mssfix size mtu
+
+ If you need to set ``--mssfix`` for data channel and control channel maximum
+ packet size independently, use ``--max-packet-size`` first, followed by a
+ ``--mssfix`` in the configuration.
+
+ In general the default size of 1250 should work almost universally apart
+ from specific corner cases, especially since IPv6 requires a MTU of 1280
+ or larger.
*/
#define TLS_CHANNEL_BUF_SIZE 2048
+/* TLS control buffer minimum size
+ *
+ * A control frame might have IPv6 header (40 byte),
+ * UDP (8 byte), opcode (1), session id (8),
+ * ACK array with 4 ACKs in non-ACK_V1 packets (25 bytes)
+ * tls-crypt(56) or tls-auth(up to 72). To allow secure
+ * renegotiation (dynamic tls-crypt), we set this minimum
+ * to 154, which only allows 16 byte of payload and should
+ * be considered an absolute minimum and not a good value to
+ * set
+ */
+#define TLS_CHANNEL_MTU_MIN 154
+
/*
* This parameter controls the maximum size of a bundle
* of pushed options.
* space */
size_t payload_size = max_int(1500, frame->tun_mtu);
+ /* we need to be also large enough to hold larger control channel packets
+ * if configured */
+ payload_size = max_int(payload_size, o->ce.tls_mtu);
+
/* The extra tun needs to be added to the payload size */
if (o->ce.tun_mtu_defined)
{
options->ce.tls_crypt_v2_file,
options->ce.tls_crypt_v2_file_inline);
}
+ /* We have to ensure that the loaded tls-crypt key is small enough
+ * to fit into the initial hard reset v3 packet */
+ int wkc_len = buf_len(&c->c1.ks.tls_crypt_v2_wkc);
+
+ /* empty ACK/message id, tls-crypt, Opcode, UDP, ipv6 */
+ int required_size = 5 + wkc_len + tls_crypt_buf_overhead() + 1 + 8 + 40;
+
+ if (required_size > c->options.ce.tls_mtu)
+ {
+ msg(M_WARN, "ERROR: tls-crypt-v2 client key too large to work with "
+ "requested --max-packet-size %d, requires at least "
+ "--max-packet-size %d. Packets will ignore requested "
+ "maximum packet size", c->options.ce.tls_mtu,
+ required_size);
+ }
}
{
if (c->c2.tls_multi)
{
- tls_multi_init_finalize(c->c2.tls_multi, &c->c2.frame);
+ tls_multi_init_finalize(c->c2.tls_multi, c->options.ce.tls_mtu);
ASSERT(c->c2.tls_multi->opt.frame.buf.payload_size <=
c->c2.frame.buf.payload_size);
frame_print(&c->c2.tls_multi->opt.frame, D_MTU_INFO,
}
if (c->c2.tls_auth_standalone)
{
- tls_init_control_channel_frame_parameters(&c->c2.frame, &c->c2.tls_auth_standalone->frame);
+ tls_init_control_channel_frame_parameters(&c->c2.tls_auth_standalone->frame, c->options.ce.tls_mtu);
frame_print(&c->c2.tls_auth_standalone->frame, D_MTU_INFO,
"TLS-Auth MTU parms");
c->c2.tls_auth_standalone->tls_wrap.work = alloc_buf_gc(BUF_SIZE(&c->c2.frame), &c->c2.gc);
*/
#define MSSFIX_DEFAULT 1492
+/*
+ * Default maximum size of control channel packets
+ */
+#define TLS_MTU_DEFAULT 1250
+
/*
* Alignment of payload data such as IP packet or
* ethernet frame.
o->ce.bind_local = true;
o->ce.tun_mtu = TUN_MTU_DEFAULT;
o->ce.link_mtu = LINK_MTU_DEFAULT;
+ o->ce.tls_mtu = TLS_MTU_DEFAULT;
o->ce.mtu_discover_type = -1;
o->ce.mssfix = 0;
o->ce.mssfix_default = true;
SHOW_BOOL(link_mtu_defined);
SHOW_INT(tun_mtu_extra);
SHOW_BOOL(tun_mtu_extra_defined);
+ SHOW_INT(tls_mtu);
SHOW_INT(mtu_discover_type);
options->ce.tun_mtu_extra = positive_atoi(p[1]);
options->ce.tun_mtu_extra_defined = true;
}
+ else if (streq(p[0], "max-packet-size") && p[1] && !p[2])
+ {
+ VERIFY_PERMISSION(OPT_P_MTU|OPT_P_CONNECTION);
+ int maxmtu = positive_atoi(p[1]);
+ options->ce.tls_mtu = constrain_int(maxmtu, TLS_CHANNEL_MTU_MIN, TLS_CHANNEL_BUF_SIZE);
+
+ if (maxmtu < TLS_CHANNEL_MTU_MIN || maxmtu > TLS_CHANNEL_BUF_SIZE)
+ {
+ msg(M_WARN, "Note: max-packet-size value outside of allowed "
+ "control channel packet size (%d to %d), will use %d "
+ "instead.", TLS_CHANNEL_MTU_MIN, TLS_CHANNEL_BUF_SIZE,
+ options->ce.tls_mtu);
+ }
+
+ /* also set mssfix maxmtu mtu */
+ options->ce.mssfix = maxmtu;
+ options->ce.mssfix_default = false;
+ options->ce.mssfix_encap = true;
+ }
#ifdef ENABLE_FRAGMENT
else if (streq(p[0], "mtu-dynamic"))
{
bool tun_mtu_extra_defined;
int link_mtu; /* MTU of device over which tunnel packets pass via TCP/UDP */
bool link_mtu_defined; /* true if user overriding parm with command line option */
+ int tls_mtu; /* Maximum MTU for the control channel messages */
/* Advanced MTU negotiation and datagram fragmentation options */
int mtu_discover_type; /* used if OS supports setting Path MTU discovery options on socket */
}
void
-tls_init_control_channel_frame_parameters(const struct frame *data_channel_frame,
- struct frame *frame)
+tls_init_control_channel_frame_parameters(struct frame *frame, int tls_mtu)
{
/*
* frame->extra_frame is already initialized with tls_auth buffer requirements,
/* Previous OpenVPN version calculated the maximum size and buffer of a
* control frame depending on the overhead of the data channel frame
- * overhead and limited its maximum size to 1250. We always allocate the
- * TLS_CHANNEL_BUF_SIZE buffer size since a lot of code blindly assumes
- * a large buffer (e.g. PUSH_BUNDLE_SIZE) and also our peer might have
- * a higher size configured and we still want to be able to receive the
- * packets. frame->mtu_mtu is set as suggestion for the maximum packet
- * size */
- frame->buf.payload_size = 1250 + overhead;
+ * overhead and limited its maximum size to 1250. Since control frames
+ * also need to fit into data channel buffer we have the same
+ * default of 1500 + 100 as data channel buffers have. Increasing
+ * control channel mtu beyond this limit also increases the data channel
+ * buffers */
+ frame->buf.payload_size = max_int(1500, tls_mtu) + 100;
frame->buf.headroom = overhead;
frame->buf.tailroom = overhead;
- frame->tun_mtu = min_int(data_channel_frame->tun_mtu, 1250);
+ frame->tun_mtu = tls_mtu;
+
+ /* Ensure the tun-mtu stays in a valid range */
+ frame->tun_mtu = min_int(frame->tun_mtu, TLS_CHANNEL_BUF_SIZE);
+ frame->tun_mtu = max_int(frame->tun_mtu, TLS_CHANNEL_MTU_MIN);
}
/**
}
void
-tls_multi_init_finalize(struct tls_multi *multi, const struct frame *frame)
+tls_multi_init_finalize(struct tls_multi *multi, int tls_mtu)
{
- tls_init_control_channel_frame_parameters(frame, &multi->opt.frame);
+ tls_init_control_channel_frame_parameters(&multi->opt.frame, tls_mtu);
/* initialize the active and untrusted sessions */
tls_session_init(multi, &multi->session[TM_ACTIVE]);
*
* @param multi - The \c tls_multi structure of which to finalize
* initialization.
- * @param frame - The data channel's \c frame structure.
+ * @param tls_mtu - maximum allowed size for control channel packets
*/
-void tls_multi_init_finalize(struct tls_multi *multi,
- const struct frame *frame);
+void tls_multi_init_finalize(struct tls_multi *multi, int tls_mtu);
/*
* Initialize a standalone tls-auth verification object.
* Setups the control channel frame size parameters from the data channel
* parameters
*/
-void tls_init_control_channel_frame_parameters(const struct frame *data_channel_frame,
- struct frame *frame);
+void tls_init_control_channel_frame_parameters(struct frame *frame, int tls_mtu);
/*
* Set local and remote option compatibility strings.