The mamangement command "remote SKIP" is extended with an
optional parameter 'count' > 0. If count is greater than
number of connection entries (len), count % len is used.
On going past the index of the last connection entry,
counting is restarted from the first connection entry.
Without this, use of management-query-remote from a UI is
virtually impractical except when there are only a handful
of remote entries. Skipping the entries one by one takes
a long time when there are many entries to be skipped
(~ 1 second per entry). Use of "remote MOD" is not an
option as change of protocol is not supported.
Management clients can determine the availability of this
feature by checking that the management interface version
is > 3. Older versions will ignore the count parameter and
behave identically to using count = 1.
Signed-off-by: Selva Nair <selva.nair@gmail.com>
Acked-by: Arne Schwabe <arne@rfc2549.org>
Message-Id: <20210907223614.8574-1-selva.nair@gmail.com>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg22817.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
(cherry picked from commit ec5ffe35a394c44b1ea25b7c10dab7da7d792ef2)
| ... | ... |
@@ -877,6 +877,13 @@ use this command: |
| 877 | 877 |
|
| 878 | 878 |
remote SKIP |
| 879 | 879 |
|
| 880 |
+Starting OpenVPN version 2.6 (management version > 3), skip |
|
| 881 |
+multiple remotes using: |
|
| 882 |
+ |
|
| 883 |
+ remote SKIP n |
|
| 884 |
+ |
|
| 885 |
+where n > 0 is the number of remotes to skip. |
|
| 886 |
+ |
|
| 880 | 887 |
COMMAND -- proxy (OpenVPN 2.3 or higher) |
| 881 | 888 |
-------------------------------------------- |
| 882 | 889 |
|
| ... | ... |
@@ -389,6 +389,7 @@ management_callback_remote_cmd(void *arg, const char **p) |
| 389 | 389 |
{
|
| 390 | 390 |
flags = CE_MAN_QUERY_REMOTE_SKIP; |
| 391 | 391 |
ret = true; |
| 392 |
+ c->options.ce_advance_count = (p[2]) ? atoi(p[2]) : 1; |
|
| 392 | 393 |
} |
| 393 | 394 |
else if (!strcmp(p[1], "MOD") && p[2] && p[3]) |
| 394 | 395 |
{
|
| ... | ... |
@@ -563,18 +564,28 @@ next_connection_entry(struct context *c) |
| 563 | 563 |
c->c1.link_socket_addr.remote_list; |
| 564 | 564 |
} |
| 565 | 565 |
|
| 566 |
+ int advance_count = 1; |
|
| 567 |
+ |
|
| 568 |
+ /* If previous connection entry was skipped by management client |
|
| 569 |
+ * with a count to advance by, apply it. |
|
| 570 |
+ */ |
|
| 571 |
+ if (c->options.ce_advance_count > 0) |
|
| 572 |
+ {
|
|
| 573 |
+ advance_count = c->options.ce_advance_count; |
|
| 574 |
+ } |
|
| 575 |
+ |
|
| 566 | 576 |
/* |
| 567 | 577 |
* Increase the number of connection attempts |
| 568 | 578 |
* If this is connect-retry-max * size(l) |
| 569 | 579 |
* OpenVPN will quit |
| 570 | 580 |
*/ |
| 571 | 581 |
|
| 572 |
- c->options.unsuccessful_attempts++; |
|
| 582 |
+ c->options.unsuccessful_attempts += advance_count; |
|
| 583 |
+ l->current += advance_count; |
|
| 573 | 584 |
|
| 574 |
- if (++l->current >= l->len) |
|
| 585 |
+ if (l->current >= l->len) |
|
| 575 | 586 |
{
|
| 576 |
- |
|
| 577 |
- l->current = 0; |
|
| 587 |
+ l->current %= l->len; |
|
| 578 | 588 |
if (++n_cycles >= 2) |
| 579 | 589 |
{
|
| 580 | 590 |
msg(M_FATAL, "No usable connection profiles are present"); |
| ... | ... |
@@ -583,6 +594,7 @@ next_connection_entry(struct context *c) |
| 583 | 583 |
} |
| 584 | 584 |
} |
| 585 | 585 |
|
| 586 |
+ c->options.ce_advance_count = 1; |
|
| 586 | 587 |
ce = l->array[l->current]; |
| 587 | 588 |
|
| 588 | 589 |
if (ce->flags & CE_DISABLED) |
| ... | ... |
@@ -285,6 +285,8 @@ struct options |
| 285 | 285 |
bool advance_next_remote; |
| 286 | 286 |
/* Counts the number of unsuccessful connection attempts */ |
| 287 | 287 |
unsigned int unsuccessful_attempts; |
| 288 |
+ /* count of connection entries to advance by when no_advance is not set */ |
|
| 289 |
+ int ce_advance_count; |
|
| 288 | 290 |
/* the server can suggest a backoff time to the client, it |
| 289 | 291 |
* will still be capped by the max timeout between connections |
| 290 | 292 |
* (300s by default) */ |