[Openvpn-devel,v3] dco-freebsd: use m->instances[] instead of m->hash

Message ID 20230322192733.20295-1-a@unstable.cc
State Superseded
Headers show
Series [Openvpn-devel,v3] dco-freebsd: use m->instances[] instead of m->hash | expand

Commit Message

Antonio Quartulli March 22, 2023, 7:27 p.m. UTC
When retrieving the multi_instance of a specific peer,
there is no need to peform a linear search across the
whole m->hash list. We can directly access the needed
object via m->instances[peer-id] in constant time (and
just one line of code).

Adapt the dco-freebsd code to do so.

Cc: Kristof Provost <kp@FreeBSD.org>
Change-Id: I8d8af6f872146604a9710edf443db65df48ac3cb
Signed-off-by: Antonio Quartulli <a@unstable.cc>
---
NOTE: not tested because I have no FreeBSD environment

Changes from v1:
* added boundary check on peer-id

Changes from v2:
* use one check only instead of two
---
 src/openvpn/dco_freebsd.c | 23 +++++++----------------
 1 file changed, 7 insertions(+), 16 deletions(-)

Comments

Kristof Provost March 23, 2023, 1:55 a.m. UTC | #1
On 23 Mar 2023, at 4:27, Antonio Quartulli wrote:
> When retrieving the multi_instance of a specific peer,
> there is no need to peform a linear search across the
> whole m->hash list. We can directly access the needed
> object via m->instances[peer-id] in constant time (and
> just one line of code).
>
> Adapt the dco-freebsd code to do so.
>
> Cc: Kristof Provost <kp@FreeBSD.org>
> Change-Id: I8d8af6f872146604a9710edf443db65df48ac3cb
> Signed-off-by: Antonio Quartulli <a@unstable.cc>
> ---
> NOTE: not tested because I have no FreeBSD environment
>
> Changes from v1:
> * added boundary check on peer-id
>
> Changes from v2:
> * use one check only instead of two
> ---
>  src/openvpn/dco_freebsd.c | 23 +++++++----------------
>  1 file changed, 7 insertions(+), 16 deletions(-)
>
> diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c
> index 225b3cf8..54ec16ff 100644
> --- a/src/openvpn/dco_freebsd.c
> +++ b/src/openvpn/dco_freebsd.c
> @@ -674,27 +674,18 @@ dco_event_set(dco_context_t *dco, struct event_set *es, void *arg)
>  static void
>  dco_update_peer_stat(struct multi_context *m, uint32_t peerid, const nvlist_t *nvl)
‘peerid’ here

>  {
> -    struct hash_element *he;
> -    struct hash_iterator hi;
>
> -    hash_iterator_init(m->hash, &hi);
> -
> -    while ((he = hash_iterator_next(&hi)))
> +    if (peer_id >= m->max_clients || !m->instances[peer_id])
But ‘peer_id’ everywhere else.

So that needs to be fixed, because this version doesn’t build.

Other than that I’m happy with this change.

Best regards,
Kristof

Patch

diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c
index 225b3cf8..54ec16ff 100644
--- a/src/openvpn/dco_freebsd.c
+++ b/src/openvpn/dco_freebsd.c
@@ -674,27 +674,18 @@  dco_event_set(dco_context_t *dco, struct event_set *es, void *arg)
 static void
 dco_update_peer_stat(struct multi_context *m, uint32_t peerid, const nvlist_t *nvl)
 {
-    struct hash_element *he;
-    struct hash_iterator hi;
 
-    hash_iterator_init(m->hash, &hi);
-
-    while ((he = hash_iterator_next(&hi)))
+    if (peer_id >= m->max_clients || !m->instances[peer_id])
     {
-        struct multi_instance *mi = (struct multi_instance *) he->value;
-
-        if (mi->context.c2.tls_multi->peer_id != peerid)
-        {
-            continue;
-        }
-
-        mi->context.c2.dco_read_bytes = nvlist_get_number(nvl, "in");
-        mi->context.c2.dco_write_bytes = nvlist_get_number(nvl, "out");
-
+        msg(M_WARN, "Cannot store DCO stats for peer %u",
+            peerid);
         return;
     }
 
-    msg(M_INFO, "Peer %d returned by kernel, but not found locally", peerid);
+    struct multi_instance *mi = m->instances[peer_id];
+
+    mi->context.c2.dco_read_bytes = nvlist_get_number(nvl, "in");
+    mi->context.c2.dco_write_bytes = nvlist_get_number(nvl, "out");
 }
 
 int