@@ -222,9 +222,75 @@ dco_update_keys(dco_context_t *dco, struct tls_multi *multi)
}
}
+static bool
+dco_check_option_ce(const struct connection_entry *ce, int msglevel)
+{
+ if (ce->fragment)
+ {
+ msg(msglevel, "Note: --fragment disables data channel offload.");
+ return false;
+ }
+
+ if (ce->http_proxy_options)
+ {
+ msg(msglevel, "Note: --http-proxy disables data channel offload.");
+ return false;
+ }
+
+ if (ce->socks_proxy_server)
+ {
+ msg(msglevel, "Note: --socks-proxy disables data channel offload.");
+ return false;
+ }
+
+#if defined(TARGET_FREEBSD)
+ if (!proto_is_udp(ce->proto))
+ {
+ msg(msglevel, "NOTE: TCP transport disables data channel offload on FreeBSD.");
+ return false;
+ }
+#endif
+
+ return true;
+}
+
bool
-dco_check_startup_option_conflict(int msglevel, const struct options *o)
+dco_check_startup_option(int msglevel, const struct options *o)
{
+ /* check if DCO was already disabled by the user or if no dev name was
+ * specified at all. In the latter case, later logic will most likely stop
+ * OpenVPN, so no need to print any message here.
+ */
+ if (!dco_enabled(o) || !o->dev)
+ {
+ return false;
+ }
+
+ if (dev_type_enum(o->dev, o->dev_type) != DEV_TYPE_TUN)
+ {
+ msg(msglevel, "Note: dev-type not tun, disabling data channel offload.");
+ return false;
+ }
+
+ if (o->connection_list)
+ {
+ const struct connection_list *l = o->connection_list;
+ for (int i = 0; i < l->len; ++i)
+ {
+ if (!dco_check_option_ce(l->array[i], msglevel))
+ {
+ return false;
+ }
+ }
+ }
+ else
+ {
+ if (!dco_check_option_ce(&o->ce, msglevel))
+ {
+ return false;
+ }
+ }
+
#if defined(_WIN32)
if (o->mode == MODE_SERVER)
{
@@ -281,59 +347,22 @@ dco_check_startup_option_conflict(int msglevel, const struct options *o)
}
}
#endif /* if defined(HAVE_LIBCAPNG) */
- return true;
-}
-static bool
-dco_check_option_conflict_ce(const struct connection_entry *ce, int msglevel)
-{
- if (ce->fragment)
- {
- msg(msglevel, "Note: --fragment disables data channel offload.");
- return false;
- }
-
- if (ce->http_proxy_options)
- {
- msg(msglevel, "Note: --http-proxy disables data channel offload.");
- return false;
- }
-
- if (ce->socks_proxy_server)
- {
- msg(msglevel, "Note: --socks-proxy disables data channel offload.");
- return false;
- }
-
-#if defined(TARGET_FREEBSD)
- if (!proto_is_udp(ce->proto))
+ if (o->mode == MODE_SERVER && o->topology != TOP_SUBNET)
{
- msg(msglevel, "NOTE: TCP transport disables data channel offload on FreeBSD.");
+ msg(msglevel, "Note: NOT using '--topology subnet' disables data channel offload.");
return false;
}
-#endif
- return true;
+ /* now that all options have been confirmed to be supported, check
+ * if DCO is truly available on the system
+ */
+ return dco_available(msglevel);
}
bool
-dco_check_option_conflict(int msglevel, const struct options *o)
+dco_check_option(int msglevel, const struct options *o)
{
- /* check if DCO was already disabled by the user or if no dev name was
- * specified at all. In the latter case, later logic will most likely stop
- * OpenVPN, so no need to print any message here.
- */
- if (!dco_enabled(o) || !o->dev)
- {
- return false;
- }
-
- if (dev_type_enum(o->dev, o->dev_type) != DEV_TYPE_TUN)
- {
- msg(msglevel, "Note: dev-type not tun, disabling data channel offload.");
- return false;
- }
-
/* At this point the ciphers have already been normalised */
if (o->enable_ncp_fallback
&& !tls_item_in_cipher_list(o->ciphername, dco_get_supported_ciphers()))
@@ -343,31 +372,6 @@ dco_check_option_conflict(int msglevel, const struct options *o)
return false;
}
- if (o->connection_list)
- {
- const struct connection_list *l = o->connection_list;
- for (int i = 0; i < l->len; ++i)
- {
- if (!dco_check_option_conflict_ce(l->array[i], msglevel))
- {
- return false;
- }
- }
- }
- else
- {
- if (!dco_check_option_conflict_ce(&o->ce, msglevel))
- {
- return false;
- }
- }
-
- if (o->mode == MODE_SERVER && o->topology != TOP_SUBNET)
- {
- msg(msglevel, "Note: NOT using '--topology subnet' disables data channel offload.");
- return false;
- }
-
#if defined(USE_COMP)
if (o->comp.alg != COMP_ALG_UNDEF
|| o->comp.flags & COMP_F_ALLOW_ASYM
@@ -400,10 +404,7 @@ dco_check_option_conflict(int msglevel, const struct options *o)
}
gc_free(&gc);
- /* now that all options have been confirmed to be supported, check
- * if DCO is truly available on the system
- */
- return dco_available(msglevel);
+ return true;
}
bool
@@ -67,7 +67,7 @@ bool dco_available(int msglevel);
* @param o the options struct that hold the options
* @return true if no conflict was detected, false otherwise
*/
-bool dco_check_option_conflict(int msglevel, const struct options *o);
+bool dco_check_option(int msglevel, const struct options *o);
/**
* Check whether the options struct has any further option that is not supported
@@ -79,7 +79,7 @@ bool dco_check_option_conflict(int msglevel, const struct options *o);
* @param o the options struct that hold the options
* @return true if no conflict was detected, false otherwise
*/
-bool dco_check_startup_option_conflict(int msglevel, const struct options *o);
+bool dco_check_startup_option(int msglevel, const struct options *o);
/**
* Check whether any of the options pushed by the server is not supported by
@@ -243,13 +243,13 @@ dco_available(int msglevel)
}
static inline bool
-dco_check_option_conflict(int msglevel, const struct options *o)
+dco_check_option(int msglevel, const struct options *o)
{
return false;
}
static inline bool
-dco_check_startup_option_conflict(int msglevel, const struct options *o)
+dco_check_startup_option(int msglevel, const struct options *o)
{
return false;
}
@@ -2719,7 +2719,7 @@ multi_connection_established(struct multi_context *m, struct multi_instance *mi)
/* Check if we have forbidding options in the current mode */
if (dco_enabled(&mi->context.options)
- && !dco_check_option_conflict(D_MULTI_ERRORS, &mi->context.options))
+ && !dco_check_option(D_MULTI_ERRORS, &mi->context.options))
{
msg(D_MULTI_ERRORS, "MULTI: client has been rejected due to incompatible DCO options");
cc_succeeded = false;
@@ -3685,14 +3685,17 @@ options_postprocess_mutate(struct options *o, struct env_set *es)
#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
/* check if any option should force disabling DCO */
- o->tuntap_options.disable_dco = !dco_check_option_conflict(D_DCO, o)
- || !dco_check_startup_option_conflict(D_DCO, o);
+ o->tuntap_options.disable_dco = !dco_check_option(D_DCO, o)
+ || !dco_check_startup_option(D_DCO, o);
#elif defined(_WIN32)
/* in Windows we have no 'fallback to non-DCO' strategy, so if a conflicting
* option is found, we simply bail out by means of M_USAGE
*/
- dco_check_option_conflict(M_USAGE, o);
- dco_check_startup_option_conflict(M_USAGE, o);
+ if (dco_enabled(o))
+ {
+ dco_check_option(M_USAGE, o);
+ dco_check_startup_option(M_USAGE, o);
+ }
#endif
if (dco_enabled(o) && o->dev_node)