Tags

Tags give the ability to mark specific points in history as being important
  • v0.6.6

    Release: mlvpn v0.6.6
    v0.6.6: WireGuard-style immediate delivery for settled single-link mode
    
    Bypasses ReorderBuffer entirely when scheduling has settled on a single
    active link (primary_link_mode/follow_peer_primary), matching
    WireGuard's own single-path delivery architecture, instead of merely
    shrinking the reorder-buffer window (v0.6.5, verified in production to
    not help). Includes a Critical fix from independent review:
    peer_primary_link is now correctly reset on session changes in the
    bypass branch too, closing a path where it could have latched forever
    across rekeys under follow_peer_primary.
  • v0.6.5

    Release: mlvpn v0.6.5
    v0.6.5: scheduling-mode-aware + jitter-aware reorder-window auto-tuning
    
    The real next lever in the throughput investigation. auto_tune_reorder_window
    computed its suggestion from RTT spread across every Up link regardless
    of whether the active scheduling mode could deliver from more than one --
    with primary_link_mode/follow_peer_primary settled on a single link, an
    idle backup's own RTT was still inflating the window and adding real,
    unnecessary latency. Now gated on Scheduler::primary(): settled single
    link uses only that link's own jitter (multiplier 4.0, mirroring TCP's
    Jacobson/Karels RTO = SRTT + 4*RTTVAR); no settled primary combines the
    existing RTT-spread term with a new worst-case-jitter term. Targets the
    sawtooth TCP retransmission-timeout cycling observed in production despite
    0% probe-reported loss and an 886 Mbps raw-path ceiling.
  • v0.6.4

    Release: mlvpn v0.6.4
    v0.6.4: try_lock in the periodic reorder-buffer flush task
    
    Fourth same-night fix in the lock-contention investigation. reorder_flush
    ticks every 10ms and was unconditionally blocking on the same lock
    handle_incoming needs on every incoming Data packet, even though its
    own work is almost always redundant under real load (handle_incoming's
    inline drain already does it). Switched to try_lock -- skip the tick
    when contended, worst case a truly idle straggler waits one extra
    ~10ms before its own staleness timeout flushes it.
  • v0.6.3

    Release: mlvpn v0.6.3
    v0.6.3: split SessionState locking (Mutex -> RwLock), modeled on WireGuard
    
    Third same-night follow-up in the lock-contention investigation. The
    daemon-wide crypto session lock forced every encrypt call (11 sites:
    Data, Probe replies, StatsShare, VersionInfo, ThroughputTest) to
    serialize behind every other encrypt AND behind decrypt/install/
    expire_previous, even though encrypt has always taken &self and only
    genuinely needs shared access. Split into RwLock: encrypt uses
    .read().await (concurrent with other encrypts now), decrypt/install/
    expire_previous keep .write().await where exclusivity is actually
    needed. Modeled on wireguard-go's real design (lock-free nonce atomic,
    lock only guards which keypair is active). Independently reviewed
    given the crypto-adjacent correctness stakes -- all 16 call sites
    verified, concurrent-encrypt safety verified against the underlying
    snow crate's cipher implementation, no torn reads possible during a
    concurrent rekey install.
  • v0.6.2

    Release: mlvpn v0.6.2
    v0.6.2: merge duplicate per-packet link lock on the Data receive path
    
    Follow-up to v0.6.1: handle_incoming locked the same per-link mutex
    twice per incoming Data packet (remote-address check, then a separate
    record_rx lock). Merged into one acquisition. Live strace after v0.6.1
    showed futex contention essentially unchanged on both production
    hosts, so this closes the matching gap on the receive side.
  • v0.6.1

    Release: mlvpn v0.6.1
    v0.6.1: fix real per-packet lock-contention throughput bottleneck
    
    send_scheduled() was calling link::snapshot_scores() -- an async lock
    on every configured link -- on every single outgoing Data packet,
    unconditionally, even though Scheduler::select()'s primary/SWRR
    decision logic never reads the scores it's handed. Confirmed live via
    strace -f -c: ~75% of mlvpnd's wall-clock time was in futex contention,
    capping real tunneled throughput far below the link's measured raw
    capacity despite 0% loss and negligible CPU. New Scheduler::select_fast()
    resolves the same answer with zero link locking in the common case.
  • v0.6.0

    Release: mlvpn v0.6.0
    v0.6.0: primary-link failover mode, peer-signaled primary, peer MTU display
    
    - scheduler.primary_link_mode: single-link failover with hard-Down
      immediate switching and margin/streak hysteresis to prevent flapping
      between close-scoring links.
    - scheduler.follow_peer_primary: one host signals its chosen primary
      link (by name) to its peer over the wire, so the peer can follow
      instead of running its own independent primary-selection config.
    - mlvpn-tui shows both sides' live tunnel MTU in the Session panel.
    - VersionInfoPayload's decode is now tolerant of shorter payloads from
      pre-0.6.0 peers, avoiding a silent blind spot during rolling upgrades.
  • v0.5.4

    Release: mlvpn v0.5.4
    v0.5.4: raise default TUN transmit queue length to 4000
  • v0.5.3

    Release: mlvpn v0.5.3
    v0.5.3: fix ReorderBuffer watermark not resetting on rekey
  • v0.5.2

    Release: mlvpn v0.5.2
    v0.5.2: reorder buffer high-watermark fix
  • v0.5.1

    Release: mlvpn v0.5.1
    v0.5.1: adaptive bandwidth pacing
  • v0.5.0

    Release: mlvpn v0.5.0
    v0.5.0: software-support diagnostics integration + adaptive tunnel MTU
  • v0.4.6-gitlab-test2

    Throwaway tag to validate the shell-executor GitLab CI pipeline (cargo-deb/cargo-generate-rpm packaging + the rewritten Releases-API release job) end-to-end. Not a real release -- supersedes the earlier v0.4.6-gitlab-test1 tag, which validated the now-replaced Docker/QEMU-based pipeline.
  • v0.4.6-gitlab-test1

    Throwaway tag to validate the new GitLab CI release job (release-cli + Generic Package Registry uploads) end-to-end. Not a real release -- Cargo.toml/debian/rpm still say 0.4.6.
  • v0.4.6

    Release: v0.4.6
    v0.4.6: peer disconnect no longer cascades a restart, preinst fix
    
    - Fix: a peer's Disconnect (sent on any routine restart) used to make
      the receiving side exit its own process too, cascading a full
      stop-then-cold-restart onto the other end even when nothing was
      wrong with it. Now it just means the peer's session went stale:
      client mode immediately attempts a fresh handshake instead of
      waiting up to rekey_interval_secs; server mode needs no extra
      action. Reconnection now happens in about a second instead of a
      much longer restart cascade.
    - Fix: debian/mlvpn.postinst's restart-after-upgrade state capture
      could read the wrong value if mlvpnd crashed during dpkg's own
      unpacking step. New debian/mlvpn.preinst captures the pre-upgrade
      active state before dpkg unpacks anything.
    - New: peer version exchange -- mlvpn-tui's Session panel shows both
      sides' versions and flags a mismatch; both mlvpnd self-test commands
      print a peer version line.
    
    See CHANGELOG.md for full detail.
  • v0.4.5

    Release: v0.4.5
    v0.4.5: tunnel-level throughput self-test, active-bandwidth-probe fix
    
    - New: mlvpnd self-test --tunnel --peer-addr <ip> sends real UDP
      through the TUN device to the peer's tunnel-internal address,
      exercising the real outbound queue and scheduler (unlike the
      existing link-level self-test, which bypasses them). Reports each
      direction's own outbound-queue drop count.
    - Fix: active bandwidth probing badly underreported fast links (a
      real 688 Mbps link measured at just 56.7 Mbps). Replaced the fixed
      packet-count burst with active_bandwidth_probe_duration_secs,
      reusing mlvpnd self-test's own duration-based streaming code.
    
    See CHANGELOG.md for full detail.
  • v0.4.4

    Release: v0.4.4
    v0.4.4: log-field capture fix, self-test logging, /var/log/mlvpn default, restart rate-limit headroom
  • v0.4.3

    Release: v0.4.3
    v0.4.3: dual-stack alternate-family failover fix, on-demand/automatic diagnostic-dump capture
  • v0.4.2

    Release: v0.4.2
    v0.4.2: System-panel fix, active-bandwidth-probe lock-contention fix, mlvpn-tui real-time throughput display, on-demand throughput self-test
  • v0.4.1

    Release: v0.4.1
    v0.4.1: fix dual-stack handshake hang; mlvpn-tui Overview tab
    
    Fixes a real hang: a client-side link whose remote_addr resolves to
    both an IPv4 and IPv6 address could retry its initial handshake
    forever if the IPv6 path wasn't actually reachable end-to-end (a
    broken/absent route -- not uncommon on residential/consumer ISPs).
    Both candidates now race during the first handshake attempt and
    whichever answers wins, with a log line when the fallback kicks in.
    
    Also: mlvpn-tui gains a new Overview tab (default at startup,
    combining Links/Daemon/Logs panes into one screen), more color
    coding, and no longer fails immediately at startup if mlvpnd is
    running but hasn't created its control socket yet.
    
    See CHANGELOG.md's [0.4.1] section for full detail.