Attention is currently required from: flichtenheld, plaisthos. Hello flichtenheld, plaisthos,
I'd like you to reexamine a change. Please visit http://gerrit.openvpn.net/c/openvpn/+/766?usp=email to look at the new patch set (#2). Change subject: Refinement to handle simultaneous UDP and TCP connections ...................................................................... Refinement to handle simultaneous UDP and TCP connections MULTI: properly remove TCP instances by checking the multi_instance protocol instead of the global one. TLS: set the tls_option xmit_hold bool value to true only in case of TCP child instance to avoid checking the global protocol value. INIT: initialize the c->c2.event_set in the inherit_context_top() by default and not only in case of UDP since we could have multiple different sockets. Change-Id: Ibe0614bf6ced210c136b2d13036048188196f7ef Signed-off-by: Gianmarco De Gregori <gianma...@mandelbit.com> --- M src/openvpn/init.c M src/openvpn/mtcp.c M src/openvpn/mudp.c M src/openvpn/multi.c M src/openvpn/multi.h M src/openvpn/multi_io.c M src/openvpn/options.c M src/openvpn/options.h 8 files changed, 142 insertions(+), 53 deletions(-) git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/66/766/2 diff --git a/src/openvpn/init.c b/src/openvpn/init.c index 5877ebb..b2f772b 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -225,7 +225,7 @@ if (streq(p[1], "HTTP")) { struct http_proxy_options *ho; - if (ce->proto != PROTO_TCP && ce->proto != PROTO_TCP_CLIENT) + if (ce->proto != PROTO_TCP && c->mode != CM_CHILD_TCP) { msg(M_WARN, "HTTP proxy support only works for TCP based connections"); return false; @@ -602,7 +602,10 @@ ce_defined = false; } + int proto = c->options.ce.proto; c->options.ce = *ce; + c->options.ce.proto = proto; + #ifdef ENABLE_MANAGEMENT if (ce_defined && management && management_query_remote_enabled(management)) { @@ -2673,7 +2676,7 @@ if (found & OPT_P_EXPLICIT_NOTIFY) { - if (!proto_is_udp(c->options.ce.proto) && c->options.ce.explicit_exit_notification) + if (!proto_is_udp(c->c2.link_sockets[0]->info.proto) && c->options.ce.explicit_exit_notification) { msg(D_PUSH, "OPTIONS IMPORT: --explicit-exit-notify can only be used with --proto udp"); c->options.ce.explicit_exit_notification = 0; @@ -2833,14 +2836,21 @@ int sec = 2; int backoff = 0; - switch (c->options.ce.proto) + switch (c->mode) { - case PROTO_TCP_SERVER: - sec = 1; + case CM_TOP: + if (has_udp_in_local_list(&c->options)) + { + sec = c->options.ce.connect_retry_seconds; + } + else + { + sec = 1; + } break; - case PROTO_UDP: - case PROTO_TCP_CLIENT: + case CM_CHILD_UDP: + case CM_CHILD_TCP: sec = c->options.ce.connect_retry_seconds; break; } @@ -2858,7 +2868,7 @@ } /* Slow down reconnection after 5 retries per remote -- for TCP client or UDP tls-client only */ - if (c->options.ce.proto == PROTO_TCP_CLIENT + if (c->mode == CM_CHILD_TCP || (c->options.ce.proto == PROTO_UDP && c->options.tls_client)) { backoff = (c->options.unsuccessful_attempts / c->options.connection_list->len) - 4; @@ -3338,7 +3348,21 @@ to.server = options->tls_server; to.replay_window = options->replay_window; to.replay_time = options->replay_time; - to.tcp_mode = link_socket_proto_connection_oriented(options->ce.proto); + + if (c->options.ce.local_list->len > 1) + { + for (int i = 0; i < c->options.ce.local_list->len; i++) + { + if (proto_is_dgram(c->options.ce.local_list->array[i]->proto)) + { + to.tcp_mode = false; + } + } + } + else + { + to.tcp_mode = link_socket_proto_connection_oriented(c->options.ce.local_list->array[0]->proto); + } to.config_ciphername = c->options.ciphername; to.config_ncp_ciphers = c->options.ncp_ciphers; to.transition_window = options->transition_window; @@ -3383,7 +3407,7 @@ /* should we not xmit any packets until we get an initial * response from client? */ - if (to.server && options->ce.proto == PROTO_TCP_SERVER) + if (to.server && c->mode == CM_CHILD_TCP) { to.xmit_hold = true; } @@ -4287,20 +4311,13 @@ #ifdef _WIN32 msg(M_INFO, "NOTE: --fast-io is disabled since we are running on Windows"); #else - if (!proto_is_udp(c->options.ce.proto)) + if (c->options.shaper) { - msg(M_INFO, "NOTE: --fast-io is disabled since we are not using UDP"); + msg(M_INFO, "NOTE: --fast-io is disabled since we are using --shaper"); } else { - if (c->options.shaper) - { - msg(M_INFO, "NOTE: --fast-io is disabled since we are using --shaper"); - } - else - { - c->c2.fast_io = true; - } + c->c2.fast_io = true; } #endif } @@ -4997,6 +5014,7 @@ /* options */ dest->options = src->options; + dest->options.ce.proto = sock->info.proto; options_detach(&dest->options); dest->c2.event_set = src->c2.event_set; @@ -5095,10 +5113,7 @@ dest->c2.es_owned = false; dest->c2.event_set = NULL; - if (proto_is_dgram(src->options.ce.proto)) - { - do_event_set_init(dest, false); - } + do_event_set_init(dest, false); #ifdef USE_COMP dest->c2.comp_context = NULL; diff --git a/src/openvpn/mtcp.c b/src/openvpn/mtcp.c index 5d04c64..c1107ab 100644 --- a/src/openvpn/mtcp.c +++ b/src/openvpn/mtcp.c @@ -153,12 +153,19 @@ { if (mi) { - mi->socket_set_called = true; - socket_set(mi->context.c2.link_sockets[0], - m->multi_io->es, - mbuf_defined(mi->tcp_link_out_deferred) ? EVENT_WRITE : EVENT_READ, - &mi->ev_arg, - &mi->tcp_rwflags); + if (proto_is_dgram(mi->context.c2.link_sockets[0]->info.proto)) + { + return; + } + else + { + mi->socket_set_called = true; + socket_set(mi->context.c2.link_sockets[0], + m->multi_io->es, + mbuf_defined(mi->tcp_link_out_deferred) ? EVENT_WRITE : EVENT_READ, + &mi->ev_arg, + &mi->tcp_rwflags); + } } } diff --git a/src/openvpn/mudp.c b/src/openvpn/mudp.c index 50b4e21..3189fe9 100644 --- a/src/openvpn/mudp.c +++ b/src/openvpn/mudp.c @@ -194,6 +194,7 @@ struct hash *hash = m->hash; real.proto = sock->info.proto; m->local.proto = real.proto; + m->hmac_reply_ls = sock; if (mroute_extract_openvpn_sockaddr(&real, &m->top.c2.from.dest, true) && m->top.c2.buf.len > 0) @@ -320,15 +321,8 @@ msg_set_prefix("Connection Attempt"); m->top.c2.to_link = m->hmac_reply; m->top.c2.to_link_addr = m->hmac_reply_dest; - for (int i = 0; i < m->top.c1.link_sockets_num; i++) - { - if (!proto_is_dgram(m->top.c2.link_sockets[i]->info.proto)) - { - continue; - } - - process_outgoing_link(&m->top, m->top.c2.link_sockets[i]); - } + process_outgoing_link(&m->top, m->hmac_reply_ls); + m->hmac_reply_ls = NULL; m->hmac_reply_dest = NULL; } } diff --git a/src/openvpn/multi.c b/src/openvpn/multi.c index 0d2ad78..b5efb3a 100644 --- a/src/openvpn/multi.c +++ b/src/openvpn/multi.c @@ -606,6 +606,7 @@ ASSERT(!mi->halt); mi->halt = true; + bool is_dgram = proto_is_dgram(mi->context.c2.link_sockets[0]->info.proto); dmsg(D_MULTI_DEBUG, "MULTI: multi_close_instance called"); @@ -664,7 +665,7 @@ mi->did_iroutes = false; } - if (m->multi_io && !proto_is_dgram(m->top.options.ce.proto)) + if (!is_dgram) { multi_tcp_dereference_instance(m->multi_io, mi); } @@ -3400,7 +3401,7 @@ /* decrypt in instance context */ perf_push(PERF_PROC_IN_LINK); - lsi = get_link_socket_info(c); + lsi = &sock->info; orig_buf = c->c2.buf.data; if (process_incoming_link_part1(c, lsi, floated)) { @@ -3851,7 +3852,7 @@ while ((he = hash_iterator_next(&hi))) { struct multi_instance *mi = (struct multi_instance *) he->value; - if (!mi->halt) + if (!mi->halt && proto_is_dgram(mi->context.options.ce.proto)) { send_control_channel_string(&mi->context, next_server ? "RESTART,[N]" : "RESTART", D_PUSH); multi_schedule_context_wakeup(m, mi); @@ -3889,13 +3890,15 @@ status_close(so); return false; } - else if (proto_is_dgram(m->top.options.ce.proto) - && is_exit_restart(m->top.sig->signal_received) - && (m->deferred_shutdown_signal.signal_received == 0) - && m->top.options.ce.explicit_exit_notification != 0) + else if (has_udp_in_local_list(&m->top.options)) { - multi_push_restart_schedule_exit(m, m->top.options.ce.explicit_exit_notification == 2); - return false; + if (is_exit_restart(m->top.sig->signal_received) + && (m->deferred_shutdown_signal.signal_received == 0) + && m->top.options.ce.explicit_exit_notification != 0) + { + multi_push_restart_schedule_exit(m, m->top.options.ce.explicit_exit_notification == 2); + return false; + } } return true; } diff --git a/src/openvpn/multi.h b/src/openvpn/multi.h index 0a15fd9..ad56416 100644 --- a/src/openvpn/multi.h +++ b/src/openvpn/multi.h @@ -205,6 +205,7 @@ struct buffer hmac_reply; struct link_socket_actual *hmac_reply_dest; + struct link_socket *hmac_reply_ls; /* * Timer object for stale route check diff --git a/src/openvpn/multi_io.c b/src/openvpn/multi_io.c index 43fe24b..59661ed 100644 --- a/src/openvpn/multi_io.c +++ b/src/openvpn/multi_io.c @@ -142,6 +142,11 @@ &m->top.c2.link_sockets[i]->ev_arg); } + if (has_udp_in_local_list(&m->top.options)) + { + get_io_flags_udp(&m->top, m->multi_io, p2mp_iow_flags(m)); + } + #ifdef _WIN32 if (tuntap_is_wintun(m->top.c1.tuntap)) { @@ -396,6 +401,10 @@ multi_protocol_process_io(struct multi_context *m) { struct multi_protocol *multi_io = m->multi_io; + const unsigned int udp_status = multi_io->udp_flags; + const unsigned int mpp_flags = m->top.c2.fast_io + ? (MPP_CONDITIONAL_PRE_SELECT | MPP_CLOSE_ON_SIGNAL) + : (MPP_PRE_SELECT | MPP_CLOSE_ON_SIGNAL); int i; for (i = 0; i < multi_io->n_esr; ++i) @@ -447,6 +456,39 @@ } break; } + else + { + if (e->arg >= MULTI_N) + { + struct event_arg *ev_arg = (struct event_arg *)e->arg; + if (ev_arg->type != EVENT_ARG_LINK_SOCKET) + { + multi_io->udp_flags = ES_ERROR; + msg(D_LINK_ERRORS, + "MULTI PROTOCOL: io_work: non socket event delivered"); + break; + } + } + else + { + ev_arg->pending = true; + } + + if (udp_status & SOCKET_READ) + { + read_incoming_link(&m->top, ev_arg->u.sock); + if (!IS_SIG(&m->top)) + { + multi_process_incoming_link(m, NULL, mpp_flags, + ev_arg->u.sock); + } + } + else + { + multi_process_io_udp(m); + } + break; + } } } else diff --git a/src/openvpn/options.c b/src/openvpn/options.c index 6f4d5e2..edda0bb 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -993,10 +993,13 @@ const struct connection_entry *e, const int i) { - setenv_str_i(es, "proto", proto2ascii(e->proto, e->af, false), i); - /* expected to be for single socket contexts only */ - setenv_str_i(es, "local", e->local_list->array[0]->local, i); - setenv_str_i(es, "local_port", e->local_list->array[0]->port, i); + for (int j = 0; j < e->local_list->len; j++) + { + setenv_str_i(es, "proto", proto2ascii(e->local_list->array[j]->proto, e->af, false), i); + /* expected to be for single socket contexts only */ + setenv_str_i(es, "local", e->local_list->array[j]->local, i); + setenv_str_i(es, "local_port", e->local_list->array[j]->port, i); + } setenv_str_i(es, "remote", e->remote, i); setenv_str_i(es, "remote_port", e->remote_port, i); @@ -2466,7 +2469,7 @@ { struct local_entry *le = ce->local_list->array[i]; - if (proto_is_net(ce->proto) + if (proto_is_net(le->proto) && string_defined_equal(le->local, ce->remote) && string_defined_equal(le->port, ce->remote_port)) { @@ -3828,6 +3831,12 @@ options_postprocess_mutate_ce(o, o->connection_list->array[i]); } + if (!has_udp_in_local_list(o)) + { + o->fast_io = false; + msg(M_INFO, "NOTE: --fast-io is disabled while using multi-socket"); + } + if (o->ce.local_list) { for (i = 0; i < o->ce.local_list->len; i++) @@ -9722,3 +9731,19 @@ err: gc_free(&gc); } + +bool +has_udp_in_local_list(const struct options *options) +{ + if (options->ce.local_list) + { + for (int i = 0; i < options->ce.local_list->len; i++) + { + if (proto_is_dgram(options->ce.local_list->array[i]->proto)) + { + return true; + } + } + } + return false; +} diff --git a/src/openvpn/options.h b/src/openvpn/options.h index f3cf7e5..30bd5aa 100644 --- a/src/openvpn/options.h +++ b/src/openvpn/options.h @@ -917,6 +917,8 @@ bool key_is_external(const struct options *options); +bool has_udp_in_local_list(const struct options *options); + /** * Returns whether the current configuration has dco enabled. */ -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/766?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: Ibe0614bf6ced210c136b2d13036048188196f7ef Gerrit-Change-Number: 766 Gerrit-PatchSet: 2 Gerrit-Owner: its_Giaan <gianma...@mandelbit.com> Gerrit-Reviewer: flichtenheld <fr...@lichtenheld.com> Gerrit-Reviewer: plaisthos <arne-open...@rfc2549.org> Gerrit-CC: openvpn-devel <openvpn-devel@lists.sourceforge.net> Gerrit-Attention: plaisthos <arne-open...@rfc2549.org> Gerrit-Attention: flichtenheld <fr...@lichtenheld.com> Gerrit-MessageType: newpatchset
_______________________________________________ Openvpn-devel mailing list Openvpn-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openvpn-devel