[M] Change in openvpn[master]: oob: Add --server-probe-reply to advertise probe reply values

"stipa \(Code Review\) via Openvpn-devel" <[email protected]>
Newsgroups gmane.network.openvpn.devel
Message-ID <80433c03f061ea45d69688058235d8e5fa5a9691-EmailReplacePatchSet-HTML@gerrit.openvpn.net>
Attention is currently required from: plaisthos.

Hello plaisthos, 

I'd like you to reexamine a change. Please visit

    http://gerrit.openvpn.net/c/openvpn/+/1752?usp=email

to look at the new patch set (#16).


Change subject: oob: Add --server-probe-reply to advertise probe reply values
......................................................................

oob: Add --server-probe-reply to advertise probe reply values

Add a server option, --server-probe-reply [max-latency-diff] [weight] [prio],
each argument optional, setting the values the server returns in its OOB
PROBE_REPLY. An unconfigured server advertises weight 50, priority 100 and a 10 ms
max-latency-diff.
max-latency-diff is how much slower than the fastest server a server may be
and still count as equally good; 0 asks clients to pick strictly by latency,
which also stops weight from distributing load within a priority. All three
are range-checked to 0..65535.

The server fills them into the probe_reply it hands to oob_build_probe_reply(),
which only stamps the peer's session id; the client already reads and ranks
remotes by them.

Change-Id: Id74cfae7e9d69029d2ddbf635ee85a2a6cedc3d8
Signed-off-by: Lev Stipakov <[email protected]>
---
M Changes.rst
M doc/man-sections/server-options.rst
M src/openvpn/mudp.c
M src/openvpn/options.c
M src/openvpn/options.h
M tests/unit_tests/openvpn/test_oob.c
6 files changed, 87 insertions(+), 9 deletions(-)


  git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/52/1752/16

diff --git a/Changes.rst b/Changes.rst
index 1f992b2..080d928 100644
--- a/Changes.rst
+++ b/Changes.rst
@@ -1,5 +1,13 @@
 Overview of changes in 2.8
 ==========================
+New features
+------------
+Out-of-band server probing and server-controlled selection
+    With ``--server-probe``, a client probes all configured UDP remotes
+    before connecting and reorders them based on the replies: reachable
+    servers are tried first, ordered by server-advertised priority,
+    measured latency and advertised weight with DNS-SRV-like semantics.
+    Servers advertise these values with ``--server-probe-reply``.
 
 
 Overview of changes in 2.7
diff --git a/doc/man-sections/server-options.rst b/doc/man-sections/server-options.rst
index 9dfa6bd..2f2ead6 100644
--- a/doc/man-sections/server-options.rst
+++ b/doc/man-sections/server-options.rst
@@ -662,6 +662,34 @@
   Pushing of the ``--tun-ipv6`` directive is done for older clients which
   require an explicit ``--tun-ipv6`` in their configuration.
 
+--server-probe-reply args
+  Set the values a server advertises in its replies to out-of-band
+  probes from clients using ``--server-probe``.
+
+  Valid syntaxes::
+
+     server-probe-reply max-latency-diff
+     server-probe-reply max-latency-diff weight
+     server-probe-reply max-latency-diff weight priority
+
+  ``max-latency-diff`` is the candidate-band margin in milliseconds: a
+  probing client treats servers of the same priority whose round-trip
+  time is within this margin of the fastest one as equally good. The
+  default is :code:`10`; :code:`0` asks clients to pick strictly by
+  latency, so only the fastest server of a priority group is treated as
+  best and ``weight`` no longer distributes load between them. A client
+  that sets its own margin with ``--server-probe`` overrides this.
+
+  ``weight`` (default :code:`50`) and ``priority`` (default :code:`100`)
+  have DNS SRV (RFC 2782) semantics: clients try servers with a lower
+  priority value first, and distribute load between equally-good
+  servers of the same priority proportionally to their weights.
+
+  All values are in the range :code:`0` to :code:`65535`. A UDP server
+  answers probes regardless of this option; replies are stateless,
+  replay-protected and rate-limited. The option only controls the
+  advertised values.
+
 --stale-routes-check args
   Remove routes which haven't had activity for ``n`` seconds (i.e. the ageing
   time).  This check is run every ``t`` seconds (i.e. check interval).
diff --git a/src/openvpn/mudp.c b/src/openvpn/mudp.c
index 01d7441..e172f7c 100644
--- a/src/openvpn/mudp.c
+++ b/src/openvpn/mudp.c
@@ -238,7 +238,12 @@
         /* Out-of-band server probe. state->newbuf points at the TLV payload
          * (read_control_auth has stripped the opcode, session id and any
          * tls-auth/tls-crypt wrapping). Answer it without creating a session. */
-        struct oob_probe_reply reply;
+        /* what we advertise; oob_build_probe_reply() adds the peer's session id */
+        struct oob_probe_reply reply = {
+            .priority = (uint16_t)m->top.options.server_probe_reply_priority,
+            .weight = (uint16_t)m->top.options.server_probe_reply_weight,
+            .max_latency_diff = (uint16_t)m->top.options.server_probe_reply_max_latency_diff,
+        };
         if (!oob_build_probe_reply(&state->newbuf, (uint64_t)now, (uint64_t)handwindow,
                                    &state->peer_session_id, &reply))
         {
diff --git a/src/openvpn/options.c b/src/openvpn/options.c
index 8b5afd0..e636fd5 100644
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
@@ -44,6 +44,7 @@
 #include "ssl.h"
 #include "ssl_ncp.h"
 #include "options.h"
+#include "oob.h"
 #include "misc.h"
 #include "socket_util.h"
 #include "packet_id.h"
@@ -810,10 +811,15 @@
     o->ce.proto = PROTO_UDP;
     o->ce.af = AF_UNSPEC;
 
-    /* The client latency margin is -1 = "not set": the client's value is
-     * authoritative when given, otherwise each server's advertised margin (or
-     * the built-in default) applies. */
+    /* server-probe defaults. The client latency margin is -1 = "not set": the
+     * client's value is authoritative when given, otherwise each server's
+     * advertised margin applies. An (unconfigured) server advertises weight 50 /
+     * priority 100 and a margin of OOB_DEFAULT_LATENCY_MARGIN_MS -- announcing 0
+     * would ask clients to pick strictly by latency and never by weight. */
     o->server_probe_latency_margin = -1;
+    o->server_probe_reply_weight = 50;
+    o->server_probe_reply_priority = 100;
+    o->server_probe_reply_max_latency_diff = OOB_DEFAULT_LATENCY_MARGIN_MS;
     o->ce.bind_ipv6_only = false;
     o->ce.connect_retry_seconds = 1;
     o->ce.connect_retry_seconds_max = 300;
@@ -5105,6 +5111,26 @@
             options->server_probe_latency_margin = margin;
         }
     }
+    else if (streq(p[0], "server-probe-reply") && !p[4])
+    {
+        VERIFY_PERMISSION(OPT_P_GENERAL);
+        /* --server-probe-reply [max-latency-diff] [weight] [prio]; each optional */
+        int vals[3] = { options->server_probe_reply_max_latency_diff,
+                        options->server_probe_reply_weight,
+                        options->server_probe_reply_priority };
+        for (int i = 0; i < 3 && p[i + 1]; i++)
+        {
+            vals[i] = positive_atoi(p[i + 1], msglevel);
+            if (vals[i] > 0xffff)
+            {
+                msg(msglevel, "--server-probe-reply: values must be 0 to 65535");
+                goto err;
+            }
+        }
+        options->server_probe_reply_max_latency_diff = vals[0];
+        options->server_probe_reply_weight = vals[1];
+        options->server_probe_reply_priority = vals[2];
+    }
     else if (streq(p[0], "nice") && p[1] && !p[2])
     {
         VERIFY_PERMISSION(OPT_P_NICE);
diff --git a/src/openvpn/options.h b/src/openvpn/options.h
index c2cde60..f5c0c28 100644
--- a/src/openvpn/options.h
+++ b/src/openvpn/options.h
@@ -341,6 +341,13 @@
     /* client: default candidate-band margin in ms (--server-probe [max-latency-diff]):
      * servers within this RTT of the fastest are treated as equally fast */
     int server_probe_latency_margin;
+    /* server: values advertised in the OOB PROBE_REPLY (--server-probe-reply).
+     * priority/weight follow DNS-SRV semantics; max_latency_diff is the
+     * candidate band this server asks clients to use (0 = only the fastest
+     * server of the group is a candidate). */
+    int server_probe_reply_priority;
+    int server_probe_reply_weight;
+    int server_probe_reply_max_latency_diff;
 
     bool mlock;
 
diff --git a/tests/unit_tests/openvpn/test_oob.c b/tests/unit_tests/openvpn/test_oob.c
index 4cac61f..389064a 100644
--- a/tests/unit_tests/openvpn/test_oob.c
+++ b/tests/unit_tests/openvpn/test_oob.c
@@ -401,7 +401,7 @@
 }
 
 /* A valid, in-window SERVER_PROBE yields a reply that echoes the peer's
- * session id and zeroes the remaining fields. */
+ * session id and carries the configured priority and weight. */
 static void
 test_build_probe_reply_valid(void **state)
 {
@@ -415,14 +415,18 @@
     struct session_id peer;
     memcpy(peer.id, "PEER1234", SID_SIZE);
 
-    /* left as the caller set them: the function only fills the session id */
-    struct oob_probe_reply reply = { 0 };
+    struct oob_probe_reply reply = {
+        .priority = 5,
+        .weight = 50,
+        .max_latency_diff = 25,
+    };
     assert_true(oob_build_probe_reply(&buf, now, 30, &peer, &reply));
     assert_memory_equal(reply.peer_session_id.id, peer.id, SID_SIZE);
-    assert_int_equal(reply.priority, 0);
-    assert_int_equal(reply.weight, 0);
+    assert_int_equal(reply.priority, 5);
+    assert_int_equal(reply.weight, 50);
     assert_int_equal(reply.connect_lifetime, 0);
     assert_int_equal(reply.flags, 0);
+    assert_int_equal(reply.max_latency_diff, 25);
 
     gc_free(&gc);
 }

-- 
To view, visit http://gerrit.openvpn.net/c/openvpn/+/1752?usp=email
To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings?usp=email

Gerrit-MessageType: newpatchset
Gerrit-Project: openvpn
Gerrit-Branch: master
Gerrit-Change-Id: Id74cfae7e9d69029d2ddbf635ee85a2a6cedc3d8
Gerrit-Change-Number: 1752
Gerrit-PatchSet: 16
Gerrit-Owner: stipa <[email protected]>
Gerrit-Reviewer: plaisthos <[email protected]>
Gerrit-CC: openvpn-devel <[email protected]>
Gerrit-Attention: plaisthos <[email protected]>

_______________________________________________
Openvpn-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openvpn-devel
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.