@@ -1638,7 +1638,6 @@ static void
multi_client_connect_post(struct multi_context *m,
struct multi_instance *mi,
const char *dc_file,
- unsigned int option_permissions_mask,
unsigned int *option_types_found)
{
/* Did script generate a dynamic config file? */
@@ -1647,7 +1646,7 @@ multi_client_connect_post(struct multi_context *m,
options_server_import(&mi->context.options,
dc_file,
D_IMPORT_ERRORS|M_OPTERR,
- option_permissions_mask,
+ CLIENT_CONNECT_OPT_MASK,
option_types_found,
mi->context.c2.es);
@@ -1671,7 +1670,6 @@ static void
multi_client_connect_post_plugin(struct multi_context *m,
struct multi_instance *mi,
const struct plugin_return *pr,
- unsigned int option_permissions_mask,
unsigned int *option_types_found)
{
struct plugin_return config;
@@ -1689,7 +1687,7 @@ multi_client_connect_post_plugin(struct multi_context *m,
options_string_import(&mi->context.options,
config.list[i]->value,
D_IMPORT_ERRORS|M_OPTERR,
- option_permissions_mask,
+ CLIENT_CONNECT_OPT_MASK,
option_types_found,
mi->context.c2.es);
}
@@ -1716,21 +1714,19 @@ multi_client_connect_post_plugin(struct multi_context *m,
static void
multi_client_connect_mda(struct multi_context *m,
struct multi_instance *mi,
- const struct buffer_list *config,
- unsigned int option_permissions_mask,
unsigned int *option_types_found)
{
- if (config)
+ if (mi->cc_config)
{
struct buffer_entry *be;
- for (be = config->head; be != NULL; be = be->next)
+ for (be = mi->cc_config->head; be != NULL; be = be->next)
{
const char *opt = BSTR(&be->buf);
options_string_import(&mi->context.options,
opt,
D_IMPORT_ERRORS|M_OPTERR,
- option_permissions_mask,
+ CLIENT_CONNECT_OPT_MASK,
option_types_found,
mi->context.c2.es);
}
@@ -1773,215 +1769,387 @@ multi_client_connect_setenv(struct multi_context *m,
gc_free(&gc);
}
-/*
- * Called as soon as the SSL/TLS connection authenticates.
- *
- * Instance-specific directives to be processed:
- *
- * iroute start-ip end-ip
- * ifconfig-push local remote-netmask
- * push
- */
static void
-multi_connection_established(struct multi_context *m, struct multi_instance *mi)
+multi_client_connect_call_plugin_v1(struct multi_context *m,
+ struct multi_instance *mi,
+ unsigned int *option_types_found,
+ int *cc_succeeded,
+ int *cc_succeeded_count)
{
- if (tls_authentication_status(mi->context.c2.tls_multi, 0) == TLS_AUTHENTICATION_SUCCEEDED)
+#ifdef ENABLE_PLUGIN
+ ASSERT(m);
+ ASSERT(mi);
+ ASSERT(option_types_found);
+ ASSERT(cc_succeeded);
+ ASSERT(cc_succeeded_count);
+
+ /* deprecated callback, use a file for passing back return info */
+ if (plugin_defined(mi->context.plugins, OPENVPN_PLUGIN_CLIENT_CONNECT))
{
+ struct argv argv = argv_new();
struct gc_arena gc = gc_new();
- unsigned int option_types_found = 0;
+ const char *dc_file =
+ platform_create_temp_file(mi->context.options.tmp_dir, "cc", &gc);
- const unsigned int option_permissions_mask =
- OPT_P_INSTANCE
- | OPT_P_INHERIT
- | OPT_P_PUSH
- | OPT_P_TIMER
- | OPT_P_CONFIG
- | OPT_P_ECHO
- | OPT_P_COMP
- | OPT_P_SOCKFLAGS;
+ if (!dc_file)
+ {
+ cc_succeeded = false;
+ goto cleanup;
+ }
- int cc_succeeded = true; /* client connect script status */
- int cc_succeeded_count = 0;
+ argv_printf(&argv, "%s", dc_file);
+ if (plugin_call(mi->context.plugins, OPENVPN_PLUGIN_CLIENT_CONNECT,
+ &argv, NULL, mi->context.c2.es)
+ != OPENVPN_PLUGIN_FUNC_SUCCESS)
+ {
+ msg(M_WARN, "WARNING: client-connect plugin call failed");
+ *cc_succeeded = false;
+ }
+ else
+ {
+ multi_client_connect_post(m, mi, dc_file, option_types_found);
+ (*cc_succeeded_count)++;
+ }
+
+ if (!platform_unlink(dc_file))
+ {
+ msg(D_MULTI_ERRORS, "MULTI: problem deleting temporary file: %s",
+ dc_file);
+ }
+
+ cleanup:
+ argv_reset(&argv);
+ gc_free(&gc);
+ }
+#endif /* ifdef ENABLE_PLUGIN */
+}
- ASSERT(mi->context.c1.tuntap);
+static void
+multi_client_connect_call_plugin_v2(struct multi_context *m,
+ struct multi_instance *mi,
+ unsigned int *option_types_found,
+ int *cc_succeeded,
+ int *cc_succeeded_count)
+{
+#ifdef ENABLE_PLUGIN
+ ASSERT(m);
+ ASSERT(mi);
+ ASSERT(option_types_found);
+ ASSERT(cc_succeeded);
+ ASSERT(cc_succeeded_count);
- /* lock down the common name and cert hashes so they can't change during future TLS renegotiations */
- tls_lock_common_name(mi->context.c2.tls_multi);
- tls_lock_cert_hash_set(mi->context.c2.tls_multi);
+ /* V2 callback, use a plugin_return struct for passing back return info */
+ if (plugin_defined(mi->context.plugins, OPENVPN_PLUGIN_CLIENT_CONNECT_V2))
+ {
+ struct plugin_return pr;
- /* generate a msg() prefix for this client instance */
- generate_prefix(mi);
+ plugin_return_init(&pr);
- /* delete instances of previous clients with same common-name */
- if (!mi->context.options.duplicate_cn)
+ if (plugin_call(mi->context.plugins, OPENVPN_PLUGIN_CLIENT_CONNECT_V2,
+ NULL, &pr, mi->context.c2.es)
+ != OPENVPN_PLUGIN_FUNC_SUCCESS)
{
- multi_delete_dup(m, mi);
+ msg(M_WARN, "WARNING: client-connect-v2 plugin call failed");
+ *cc_succeeded = false;
+ }
+ else
+ {
+ multi_client_connect_post_plugin(m, mi, &pr, option_types_found);
+ (*cc_succeeded_count)++;
}
- /* reset pool handle to null */
- mi->vaddr_handle = -1;
+ plugin_return_free(&pr);
+ }
+#endif /* ifdef ENABLE_PLUGIN */
+}
- /*
- * Try to source a dynamic config file from the
- * --client-config-dir directory.
- */
- if (mi->context.options.client_config_dir)
+
+
+/**
+ * Runs the --client-connect script if one is defined.
+ */
+static void
+multi_client_connect_call_script(struct multi_context *m,
+ struct multi_instance *mi,
+ unsigned int *option_types_found,
+ int *cc_succeeded,
+ int *cc_succeeded_count)
+{
+ if (mi->context.options.client_connect_script)
+ {
+ struct argv argv = argv_new();
+ struct gc_arena gc = gc_new();
+ const char *dc_file = NULL;
+
+ setenv_str(mi->context.c2.es, "script_type", "client-connect");
+
+ dc_file = platform_create_temp_file(mi->context.options.tmp_dir,
+ "cc", &gc);
+ if (!dc_file)
{
- const char *ccd_file;
+ *cc_succeeded = false;
+ goto cleanup;
+ }
- ccd_file = platform_gen_path(mi->context.options.client_config_dir,
- tls_common_name(mi->context.c2.tls_multi,
- false),
- &gc);
+ argv_parse_cmd(&argv, mi->context.options.client_connect_script);
+ argv_printf_cat(&argv, "%s", dc_file);
- /* try common-name file */
- if (platform_test_file(ccd_file))
- {
- options_server_import(&mi->context.options,
- ccd_file,
- D_IMPORT_ERRORS|M_OPTERR,
- option_permissions_mask,
- &option_types_found,
- mi->context.c2.es);
- }
- else /* try default file */
- {
- ccd_file = platform_gen_path(mi->context.options.client_config_dir,
- CCD_DEFAULT,
- &gc);
+ if (openvpn_run_script(&argv, mi->context.c2.es, 0, "--client-connect"))
+ {
+ multi_client_connect_post(m, mi, dc_file, option_types_found);
+ (*cc_succeeded_count)++;
+ }
+ else
+ {
+ *cc_succeeded = false;
+ }
- if (platform_test_file(ccd_file))
- {
- options_server_import(&mi->context.options,
- ccd_file,
- D_IMPORT_ERRORS|M_OPTERR,
- option_permissions_mask,
- &option_types_found,
- mi->context.c2.es);
- }
- }
+ if (!platform_unlink(dc_file))
+ {
+ msg(D_MULTI_ERRORS, "MULTI: problem deleting temporary file: %s",
+ dc_file);
}
+ cleanup:
+ argv_reset(&argv);
+ gc_free(&gc);
+ }
+}
- /*
- * Select a virtual address from either --ifconfig-push in --client-config-dir file
- * or --ifconfig-pool.
- */
- multi_select_virtual_addr(m, mi);
+static void
+multi_client_connect_late_setup(struct multi_context *m,
+ struct multi_instance *mi,
+ const unsigned int option_types_found)
+{
+ struct gc_arena gc = gc_new();
+ /*
+ * Process sourced options.
+ */
+ do_deferred_options(&mi->context, option_types_found);
- /* do --client-connect setenvs */
- multi_client_connect_setenv(m, mi);
+ /*
+ * make sure we got ifconfig settings from somewhere
+ */
+ if (!mi->context.c2.push_ifconfig_defined)
+ {
+ msg(D_MULTI_ERRORS, "MULTI: no dynamic or static remote"
+ "--ifconfig address is available for %s",
+ multi_instance_string(mi, false, &gc));
+ }
+
+ /*
+ * make sure that ifconfig settings comply with constraints
+ */
+ if (!ifconfig_push_constraint_satisfied(&mi->context))
+ {
+ const char* ifconfig_constraint_network =
+ print_in_addr_t(mi->context.options.push_ifconfig_constraint_network, 0, &gc);
+ const char* ifconfig_constraint_netmask =
+ print_in_addr_t(mi->context.options.push_ifconfig_constraint_netmask, 0, &gc);
+
+ /* JYFIXME -- this should cause the connection to fail */
+ msg(D_MULTI_ERRORS, "MULTI ERROR: primary virtual IP for %s (%s)"
+ "violates tunnel network/netmask constraint (%s/%s)",
+ multi_instance_string(mi, false, &gc),
+ print_in_addr_t(mi->context.c2.push_ifconfig_local, 0, &gc),
+ ifconfig_constraint_network, ifconfig_constraint_netmask);
+ }
+
+ /*
+ * For routed tunnels, set up internal route to endpoint
+ * plus add all iroute routes.
+ */
+ if (TUNNEL_TYPE(mi->context.c1.tuntap) == DEV_TYPE_TUN)
+ {
+ if (mi->context.c2.push_ifconfig_defined)
+ {
+ multi_learn_in_addr_t(m, mi,
+ mi->context.c2.push_ifconfig_local,
+ -1, true);
+ msg(D_MULTI_LOW, "MULTI: primary virtual IP for %s: %s",
+ multi_instance_string(mi, false, &gc),
+ print_in_addr_t(mi->context.c2.push_ifconfig_local, 0, &gc));
+ }
+
+ if (mi->context.c2.push_ifconfig_ipv6_defined)
+ {
+ multi_learn_in6_addr(m, mi,
+ mi->context.c2.push_ifconfig_ipv6_local,
+ -1, true);
+ /* TODO: find out where addresses are "unlearned"!! */
+ const char* ifconfig_local_ipv6 =
+ print_in6_addr(mi->context.c2.push_ifconfig_ipv6_local, 0, &gc);
+ msg(D_MULTI_LOW, "MULTI: primary virtual IPv6 for %s: %s",
+ multi_instance_string(mi, false, &gc),
+ ifconfig_local_ipv6);
+ }
+
+ /* add routes locally, pointing to new client, if
+ * --iroute options have been specified */
+ multi_add_iroutes(m, mi);
-#ifdef ENABLE_PLUGIN
/*
- * Call client-connect plug-in.
+ * iroutes represent subnets which are "owned" by a particular
+ * client. Therefore, do not actually push a route to a client
+ * if it matches one of the client's iroutes.
*/
+ remove_iroutes_from_push_route_list(&mi->context.options);
+ }
+ else if (mi->context.options.iroutes)
+ {
+ msg(D_MULTI_ERRORS, "MULTI: --iroute options rejected for %s -- iroute"
+ "only works with tun-style tunnels",
+ multi_instance_string(mi, false, &gc));
+ }
- /* deprecated callback, use a file for passing back return info */
- if (plugin_defined(mi->context.plugins, OPENVPN_PLUGIN_CLIENT_CONNECT))
- {
- struct argv argv = argv_new();
- const char *dc_file = platform_create_temp_file(mi->context.options.tmp_dir,
- "cc", &gc);
+ /* set our client's VPN endpoint for status reporting purposes */
+ mi->reporting_addr = mi->context.c2.push_ifconfig_local;
+ mi->reporting_addr_ipv6 = mi->context.c2.push_ifconfig_ipv6_local;
- if (!dc_file)
- {
- cc_succeeded = false;
- goto script_depr_failed;
- }
+ /* set context-level authentication flag */
+ mi->context.c2.context_auth = CAS_SUCCEEDED;
- argv_printf(&argv, "%s", dc_file);
- if (plugin_call(mi->context.plugins, OPENVPN_PLUGIN_CLIENT_CONNECT, &argv, NULL, mi->context.c2.es) != OPENVPN_PLUGIN_FUNC_SUCCESS)
- {
- msg(M_WARN, "WARNING: client-connect plugin call failed");
- cc_succeeded = false;
- }
- else
- {
- multi_client_connect_post(m, mi, dc_file, option_permissions_mask, &option_types_found);
- ++cc_succeeded_count;
- }
+#ifdef ENABLE_ASYNC_PUSH
+ /* authentication complete, send push reply */
+ if (mi->context.c2.push_request_received)
+ {
+ process_incoming_push_request(&mi->context);
+ }
+#endif
+ gc_free(&gc);
+}
- if (!platform_unlink(dc_file))
- {
- msg(D_MULTI_ERRORS, "MULTI: problem deleting temporary file: %s",
- dc_file);
- }
-script_depr_failed:
- argv_reset(&argv);
- }
+static void
+multi_client_connect_early_setup(struct multi_context *m,
+ struct multi_instance *mi)
+{
+ ASSERT(mi->context.c1.tuntap);
+ /*
+ * lock down the common name and cert hashes so they can't change
+ * during future TLS renegotiations
+ */
+ tls_lock_common_name(mi->context.c2.tls_multi);
+ tls_lock_cert_hash_set(mi->context.c2.tls_multi);
- /* V2 callback, use a plugin_return struct for passing back return info */
- if (plugin_defined(mi->context.plugins, OPENVPN_PLUGIN_CLIENT_CONNECT_V2))
- {
- struct plugin_return pr;
+ /* generate a msg() prefix for this client instance */
+ generate_prefix(mi);
- plugin_return_init(&pr);
+ /* delete instances of previous clients with same common-name */
+ if (!mi->context.options.duplicate_cn)
+ {
+ multi_delete_dup(m, mi);
+ }
- if (plugin_call(mi->context.plugins, OPENVPN_PLUGIN_CLIENT_CONNECT_V2, NULL, &pr, mi->context.c2.es) != OPENVPN_PLUGIN_FUNC_SUCCESS)
- {
- msg(M_WARN, "WARNING: client-connect-v2 plugin call failed");
- cc_succeeded = false;
- }
- else
- {
- multi_client_connect_post_plugin(m, mi, &pr, option_permissions_mask, &option_types_found);
- ++cc_succeeded_count;
- }
+ /* reset pool handle to null */
+ mi->vaddr_handle = -1;
+}
- plugin_return_free(&pr);
- }
-#endif /* ifdef ENABLE_PLUGIN */
+/**
+ * Try to source a dynamic config file from the
+ * --client-config-dir directory.
+ */
+static void
+multi_client_connect_source_ccd(struct multi_context *m,
+ struct multi_instance *mi,
+ unsigned int *option_types_found)
+{
+ if (mi->context.options.client_config_dir)
+ {
+ struct gc_arena gc = gc_new();
+ const char *ccd_file;
- /*
- * Run --client-connect script.
- */
- if (mi->context.options.client_connect_script && cc_succeeded)
- {
- struct argv argv = argv_new();
- const char *dc_file = NULL;
+ ccd_file = platform_gen_path(mi->context.options.client_config_dir,
+ tls_common_name(mi->context.c2.tls_multi,
+ false),
+ &gc);
- setenv_str(mi->context.c2.es, "script_type", "client-connect");
+ /* try common-name file */
+ if (platform_test_file(ccd_file))
+ {
+ options_server_import(&mi->context.options,
+ ccd_file,
+ D_IMPORT_ERRORS|M_OPTERR,
+ CLIENT_CONNECT_OPT_MASK,
+ option_types_found,
+ mi->context.c2.es);
+ }
+ else /* try default file */
+ {
+ ccd_file = platform_gen_path(mi->context.options.client_config_dir,
+ CCD_DEFAULT,
+ &gc);
- dc_file = platform_create_temp_file(mi->context.options.tmp_dir,
- "cc", &gc);
- if (!dc_file)
+ if (platform_test_file(ccd_file))
{
- cc_succeeded = false;
- goto script_failed;
+ options_server_import(&mi->context.options,
+ ccd_file,
+ D_IMPORT_ERRORS|M_OPTERR,
+ CLIENT_CONNECT_OPT_MASK,
+ option_types_found,
+ mi->context.c2.es);
}
+ }
+ gc_free(&gc);
+ }
+}
+
+/*
+ * Called as soon as the SSL/TLS connection authenticates.
+ *
+ * Instance-specific directives to be processed:
+ *
+ * iroute start-ip end-ip
+ * ifconfig-push local remote-netmask
+ * push
+ */
+static void
+multi_connection_established(struct multi_context *m, struct multi_instance *mi)
+{
+ if (tls_authentication_status(mi->context.c2.tls_multi, 0)
+ == TLS_AUTHENTICATION_SUCCEEDED)
+ {
+ unsigned int option_types_found = 0;
- argv_parse_cmd(&argv, mi->context.options.client_connect_script);
- argv_printf_cat(&argv, "%s", dc_file);
+ int cc_succeeded = true; /* client connect script status */
+ int cc_succeeded_count = 0;
- if (openvpn_run_script(&argv, mi->context.c2.es, 0, "--client-connect"))
- {
- multi_client_connect_post(m, mi, dc_file, option_permissions_mask, &option_types_found);
- ++cc_succeeded_count;
- }
- else
- {
- cc_succeeded = false;
- }
+ multi_client_connect_early_setup (m, mi);
- if (!platform_unlink(dc_file))
- {
- msg(D_MULTI_ERRORS, "MULTI: problem deleting temporary file: %s",
- dc_file);
- }
+ multi_client_connect_source_ccd (m, mi, &option_types_found);
-script_failed:
- argv_reset(&argv);
- }
+ /*
+ * Select a virtual address from either --ifconfig-push in
+ * --client-config-dir file or --ifconfig-pool.
+ */
+ multi_select_virtual_addr(m, mi);
+
+ /* do --client-connect setenvs */
+ multi_client_connect_setenv(m, mi);
+
+ multi_client_connect_call_plugin_v1 (m, mi, &option_types_found,
+ &cc_succeeded,
+ &cc_succeeded_count);
+
+ multi_client_connect_call_plugin_v2 (m, mi, &option_types_found,
+ &cc_succeeded,
+ &cc_succeeded_count);
/*
* Check for client-connect script left by management interface client
*/
+
+ if (cc_succeeded)
+ {
+ multi_client_connect_call_script (m, mi, &option_types_found,
+ &cc_succeeded,
+ &cc_succeeded_count);
+
+ }
#ifdef MANAGEMENT_DEF_AUTH
if (cc_succeeded && mi->cc_config)
{
- multi_client_connect_mda(m, mi, mi->cc_config, option_permissions_mask, &option_types_found);
- ++cc_succeeded_count;
+ multi_client_connect_mda(m, mi, &option_types_found);
+ cc_succeeded_count++;
}
#endif
@@ -1991,99 +2159,21 @@ script_failed:
*/
if (mi->context.options.disable)
{
- msg(D_MULTI_ERRORS, "MULTI: client has been rejected due to 'disable' directive");
+ msg(D_MULTI_ERRORS, "MULTI: client has been rejected due to"
+ "'disable' directive");
cc_succeeded = false;
cc_succeeded_count = 0;
}
if (cc_succeeded)
{
- /*
- * Process sourced options.
- */
- do_deferred_options(&mi->context, option_types_found);
-
- /*
- * make sure we got ifconfig settings from somewhere
- */
- if (!mi->context.c2.push_ifconfig_defined)
- {
- msg(D_MULTI_ERRORS, "MULTI: no dynamic or static remote --ifconfig address is available for %s",
- multi_instance_string(mi, false, &gc));
- }
-
- /*
- * make sure that ifconfig settings comply with constraints
- */
- if (!ifconfig_push_constraint_satisfied(&mi->context))
- {
- /* JYFIXME -- this should cause the connection to fail */
- msg(D_MULTI_ERRORS, "MULTI ERROR: primary virtual IP for %s (%s) violates tunnel network/netmask constraint (%s/%s)",
- multi_instance_string(mi, false, &gc),
- print_in_addr_t(mi->context.c2.push_ifconfig_local, 0, &gc),
- print_in_addr_t(mi->context.options.push_ifconfig_constraint_network, 0, &gc),
- print_in_addr_t(mi->context.options.push_ifconfig_constraint_netmask, 0, &gc));
- }
-
- /*
- * For routed tunnels, set up internal route to endpoint
- * plus add all iroute routes.
- */
- if (TUNNEL_TYPE(mi->context.c1.tuntap) == DEV_TYPE_TUN)
- {
- if (mi->context.c2.push_ifconfig_defined)
- {
- multi_learn_in_addr_t(m, mi, mi->context.c2.push_ifconfig_local, -1, true);
- msg(D_MULTI_LOW, "MULTI: primary virtual IP for %s: %s",
- multi_instance_string(mi, false, &gc),
- print_in_addr_t(mi->context.c2.push_ifconfig_local, 0, &gc));
- }
-
- if (mi->context.c2.push_ifconfig_ipv6_defined)
- {
- multi_learn_in6_addr(m, mi, mi->context.c2.push_ifconfig_ipv6_local, -1, true);
- /* TODO: find out where addresses are "unlearned"!! */
- msg(D_MULTI_LOW, "MULTI: primary virtual IPv6 for %s: %s",
- multi_instance_string(mi, false, &gc),
- print_in6_addr(mi->context.c2.push_ifconfig_ipv6_local, 0, &gc));
- }
-
- /* add routes locally, pointing to new client, if
- * --iroute options have been specified */
- multi_add_iroutes(m, mi);
-
- /*
- * iroutes represent subnets which are "owned" by a particular
- * client. Therefore, do not actually push a route to a client
- * if it matches one of the client's iroutes.
- */
- remove_iroutes_from_push_route_list(&mi->context.options);
- }
- else if (mi->context.options.iroutes)
- {
- msg(D_MULTI_ERRORS, "MULTI: --iroute options rejected for %s -- iroute only works with tun-style tunnels",
- multi_instance_string(mi, false, &gc));
- }
-
- /* set our client's VPN endpoint for status reporting purposes */
- mi->reporting_addr = mi->context.c2.push_ifconfig_local;
- mi->reporting_addr_ipv6 = mi->context.c2.push_ifconfig_ipv6_local;
-
- /* set context-level authentication flag */
- mi->context.c2.context_auth = CAS_SUCCEEDED;
-
-#ifdef ENABLE_ASYNC_PUSH
- /* authentication complete, send push reply */
- if (mi->context.c2.push_request_received)
- {
- process_incoming_push_request(&mi->context);
- }
-#endif
+ multi_client_connect_late_setup (m, mi, option_types_found);
}
else
{
/* set context-level authentication flag */
- mi->context.c2.context_auth = cc_succeeded_count ? CAS_PARTIAL : CAS_FAILED;
+ mi->context.c2.context_auth =
+ cc_succeeded_count ? CAS_PARTIAL : CAS_FAILED;
}
/* set flag so we don't get called again */
@@ -2097,11 +2187,11 @@ script_failed:
#ifdef MANAGEMENT_DEF_AUTH
if (management)
{
- management_connection_established(management, &mi->context.c2.mda_context, mi->context.c2.es);
+ management_connection_established
+ (management, &mi->context.c2.mda_context, mi->context.c2.es);
}
#endif
- gc_free(&gc);
}
/*
@@ -628,7 +628,9 @@ multi_process_outgoing_tun(struct multi_context *m, const unsigned int mpp_flags
return ret;
}
-
+#define CLIENT_CONNECT_OPT_MASK (OPT_P_INSTANCE | OPT_P_INHERIT | \
+ OPT_P_PUSH | OPT_P_TIMER | OPT_P_CONFIG | \
+ OPT_P_ECHO | OPT_P_COMP | OPT_P_SOCKFLAGS)
static inline bool
multi_process_outgoing_link_dowork(struct multi_context *m, struct multi_instance *mi, const unsigned int mpp_flags)