Attention is currently required from: plaisthos.

Hello plaisthos,

I'd like you to do a code review.
Please visit

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

to review the following change.


Change subject: oob: Add --server-probe-reply to advertise probe priority/weight
......................................................................

oob: Add --server-probe-reply to advertise probe priority/weight

Add a server option, --server-probe-reply <priority> <weight>, that sets
the DNS-SRV-style priority and weight the server returns in its OOB
PROBE_REPLY. Both default to 0 (the previous hardcoded behaviour), and are
range-checked to 0..65535.

The values are plumbed through oob_build_probe_reply() into the probe_reply
TLV; the client already reads and ranks remotes by them.

Change-Id: Id74cfae7e9d69029d2ddbf635ee85a2a6cedc3d8
Signed-off-by: Lev Stipakov <[email protected]>
---
M src/openvpn/mudp.c
M src/openvpn/oob.c
M src/openvpn/oob.h
M src/openvpn/options.c
M src/openvpn/options.h
M tests/unit_tests/openvpn/test_oob.c
6 files changed, 58 insertions(+), 15 deletions(-)



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

diff --git a/src/openvpn/mudp.c b/src/openvpn/mudp.c
index 9bc2d9c..0e9414d 100644
--- a/src/openvpn/mudp.c
+++ b/src/openvpn/mudp.c
@@ -236,7 +236,11 @@
          * tls-auth/tls-crypt wrapping). Answer it without creating a session. 
*/
         struct oob_probe_reply reply;
         if (!oob_build_probe_reply(&state->newbuf, (uint64_t)now, 
(uint64_t)handwindow,
-                                   &state->peer_session_id, &reply))
+                                   &state->peer_session_id,
+                                   
(uint16_t)m->top.options.server_probe_reply_priority,
+                                   
(uint16_t)m->top.options.server_probe_reply_weight,
+                                   
(uint16_t)m->top.options.server_probe_reply_max_latency_diff,
+                                   &reply))
         {
             /* malformed or replayed/stale probe: silently drop */
             return false;
diff --git a/src/openvpn/oob.c b/src/openvpn/oob.c
index 9b359dd..42a618d 100644
--- a/src/openvpn/oob.c
+++ b/src/openvpn/oob.c
@@ -222,7 +222,8 @@

 bool
 oob_build_probe_reply(struct buffer *probe_payload, uint64_t now, uint64_t 
window_secs,
-                      const struct session_id *peer_sid, struct 
oob_probe_reply *reply)
+                      const struct session_id *peer_sid, uint16_t priority, 
uint16_t weight,
+                      uint16_t max_latency_diff, struct oob_probe_reply *reply)
 {
     struct oob_probe_parameter param;
     if (!oob_server_probe_read(probe_payload, &param))
@@ -238,7 +239,10 @@

     memset(reply, 0, sizeof(*reply));
     reply->peer_session_id = *peer_sid;
-    /* priority/weight/connect_lifetime/flags left at 0 for now */
+    reply->priority = priority;
+    reply->weight = weight;
+    reply->max_latency_diff = max_latency_diff;
+    /* connect_lifetime/flags left at 0 for now */
     return true;
 }

diff --git a/src/openvpn/oob.h b/src/openvpn/oob.h
index 65e84bd..fcefb26 100644
--- a/src/openvpn/oob.h
+++ b/src/openvpn/oob.h
@@ -200,8 +200,8 @@
  * answer it. Combines oob_server_probe_read() and oob_timestamp_in_window():
  * the probe is dropped (false returned) if it has no valid probe_parameter or
  * its timestamp is outside the acceptable window. On success @p reply is
- * populated with the peer's session id echoed back and the remaining fields
- * zeroed, ready to be wrapped and sent.
+ * populated with the peer's session id echoed back and the given priority and
+ * weight (other fields zeroed), ready to be wrapped and sent.
  *
  * This is the transport-agnostic decision step; the caller performs the send.
  *
@@ -209,11 +209,15 @@
  * @param now            current time (UNIX seconds)
  * @param window_secs    acceptable timestamp skew, in either direction
  * @param peer_sid       session id of the requesting peer (echoed in the 
reply)
+ * @param priority       priority to advertise (DNS-SRV semantics; lower 
preferred)
+ * @param weight         weight to advertise (DNS-SRV semantics; higher 
preferred)
+ * @param max_latency_diff  candidate-band margin (ms) to advertise; 0 = defer 
to client
  * @param reply          filled with the reply to send on success
  * @return true if a reply should be sent, false to silently drop the probe
  */
 bool oob_build_probe_reply(struct buffer *probe_payload, uint64_t now, 
uint64_t window_secs,
-                           const struct session_id *peer_sid, struct 
oob_probe_reply *reply);
+                           const struct session_id *peer_sid, uint16_t 
priority, uint16_t weight,
+                           uint16_t max_latency_diff, struct oob_probe_reply 
*reply);

 /* Candidate-band margin (ms) used when neither the client nor the server
  * specifies one. */
diff --git a/src/openvpn/options.c b/src/openvpn/options.c
index d54e3ab..f86b438 100644
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
@@ -804,10 +804,14 @@
     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 (or the built-in default) applies. An (unconfigured)
+     * server advertises weight 50 / priority 100 and no margin (0). */
     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 = 0;
     o->ce.bind_ipv6_only = false;
     o->ce.connect_retry_seconds = 1;
     o->ce.connect_retry_seconds_max = 300;
@@ -6526,6 +6530,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 6b1120a..6e4829d 100644
--- a/src/openvpn/options.h
+++ b/src/openvpn/options.h
@@ -339,6 +339,12 @@
     /* 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 overrides the
+     * client's margin for this server (0 = defer to the client). */
+    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 b66ade2..c3efbdf 100644
--- a/tests/unit_tests/openvpn/test_oob.c
+++ b/tests/unit_tests/openvpn/test_oob.c
@@ -285,7 +285,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)
 {
@@ -300,12 +300,13 @@
     memcpy(peer.id, "PEER1234", SID_SIZE);

     struct oob_probe_reply reply;
-    assert_true(oob_build_probe_reply(&buf, now, 30, &peer, &reply));
+    assert_true(oob_build_probe_reply(&buf, now, 30, &peer, 5, 50, 25, 
&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);
 }
@@ -323,7 +324,7 @@

     struct session_id peer = { 0 };
     struct oob_probe_reply reply;
-    assert_false(oob_build_probe_reply(&buf, now, 30, &peer, &reply));
+    assert_false(oob_build_probe_reply(&buf, now, 30, &peer, 0, 0, 0, &reply));

     gc_free(&gc);
 }
@@ -341,7 +342,7 @@

     struct session_id peer = { 0 };
     struct oob_probe_reply reply;
-    assert_false(oob_build_probe_reply(&buf, 1000000, 30, &peer, &reply));
+    assert_false(oob_build_probe_reply(&buf, 1000000, 30, &peer, 0, 0, 0, 
&reply));

     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: newchange
Gerrit-Project: openvpn
Gerrit-Branch: master
Gerrit-Change-Id: Id74cfae7e9d69029d2ddbf635ee85a2a6cedc3d8
Gerrit-Change-Number: 1752
Gerrit-PatchSet: 1
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

Reply via email to