libnetplus (20260505+9) unstable; urgency=medium

  * QUIC: fix connection-level flow control double-counting — _data_recv
    was incremented by the full STREAM frame length on every receive,
    including retransmissions and overlapping data.  Over many streams
    (e.g. during long cluster imports) this inflated the counter and
    could trigger a spurious FLOW_CONTROL_ERROR that killed the
    connection mid-transfer.  Fix: compute overlap with existing
    recv_ranges to determine new unique bytes; only count those for
    _data_recv and the connection-level limit check.
  * QUIC: fix sendStreamData(vector) silent data loss on congestion
    control stall — after 50 stalls the function silently broke out of
    the send loop, losing remaining data with no error to the caller.
    Fix: throw NetException so callers (e.g. paritypp store_stripe)
    know the stream write failed and can retry.
  * QUIC: fix unidirectional stream dispatch before data complete —
    uni-stream callbacks fired on recv_fin (FIN frame arrival) instead
    of recv_complete (all data contiguous from offset 0).  If packets
    arrived out of order or needed retransmission, the callback received
    a buffer with zero-filled gaps.  Fix: check recv_complete (matching
    the bidi path) and std::move the buffer to avoid copy + memory waste.

 -- Jan Koester <jan.koester@tuxist.de>  Mon, 05 May 2026 12:00:00 +0200

libnetplus (20260504+8) unstable; urgency=medium

  * QUIC: fix PTO re-queue spin loop — when sendPacket() failed (EAGAIN),
    the re-queued entry kept its original sent_time, causing
    checkLossAndRetransmit to fire PTO again immediately on the next call.
    This created an infinite hot loop that blocked the event loop.  Fix:
    reset sent_time to now and increment _pto_count for exponential
    back-off on send failure.

libnetplus (20260504+7) unstable; urgency=medium

  * QUIC: cap max_udp_payload_size to 1472 (Ethernet-safe) instead of
    16384.  The old value caused 16KB UDP datagrams that get fragmented
    into ~11 IP fragments each, amplifying packet loss ~11x on standard
    1500 MTU networks.  This was the primary cause of store_stripe
    hanging — the server received only ~30% of packets despite the
    client believing they were delivered.
  * QUIC: add post-HEAD range verification diagnostic — logs
    recv_contiguous and first range immediately after inserting offset-0
    data to trace the contig=0 mystery

libnetplus (20260504+6) unstable; urgency=medium

  * QUIC: add per-stream recv_frame_count diagnostic — tracks how many
    STREAM frames the server actually processes for each stream.  Logged
    in the FIN-gap diagnostic line and as "[QUIC-DIAG] stream N HEAD
    frame" when offset-0 data arrives.  This distinguishes "data never
    reached processStreamFrame" from "data was processed but lost in
    reassembly".

libnetplus (20260504+5) unstable; urgency=medium

  * QUIC: fix critical data-loss bug in loss-detection retransmit — if
    sendPacket() failed (EAGAIN / send-buffer full after a burst), the
    stream data was erased from _sent_packets but never re-inserted,
    causing permanent loss of ~47 in-flight packets.  Fix: on send
    failure, re-queue under the original PN so the next loss-detection
    cycle retries the retransmit.
  * QUIC: fix same data-loss bug in PTO retransmit path — only erase
    the original entry and increment _pto_count after sendPacket()
    succeeds; re-queue on failure.
  * QUIC: improve [QUIC-DIAG] retransmit logging — report retransmit_ok
    / retransmit_fail counts and PTO re-queue events

libnetplus (20260504+4) unstable; urgency=medium

  * QUIC: add client-side [QUIC-DIAG] logging for ACK processing (first
    ACK received, range count, sent_packets), PTO probes (age, threshold),
    and loss detection (lost count, retransmit stats) to trace why gaps
    in server-side stream receive are never filled
  * QUIC: add server-side [QUIC-DIAG] logging for large streams that
    have received FIN but are not yet contiguously complete — logs
    stream ID, FIN offset, contiguous bytes, range count, and first gap
    to diagnose store_stripe response-timeout on remote nodes
  * QUIC: implement PTO (Probe Timeout, RFC 9002 §6.2) — retransmit
    the oldest unacked packet with exponential back-off when the peer
    has not acknowledged tail packets, fixing the "tail loss" deadlock
    where both sides wait indefinitely after the last few UDP datagrams
    are lost
  * QUIC: pumpNetwork() now calls checkLossAndRetransmit() so that
    callers waiting for responses (e.g. parity store_stripe Phase 2)
    trigger retransmission of lost packets
  * QUIC: fix sendStreamData(vector) silently losing data on congestion
    control stall — now retries in a loop with pumpIncoming() between
    attempts until all data (including FIN) is delivered
  * QUIC: only mark stream send_fin when all data was actually sent on
    the wire, preventing incorrect state when CC breaks the send loop

 -- Jan Koester <jan.koester@tuxist.de>  Sun, 04 May 2026 19:30:00 +0200

libnetplus (20260502+1) unstable; urgency=medium

  * QUIC: add udp::recvBatchAddr() — batch receive with peer addresses
    via recvmmsg, with thread_local 4 MB flat buffer to avoid per-call
    heap allocation
  * QUIC: server accept() uses recvBatchAddr() instead of per-datagram
    recvfrom, cutting recv syscalls from ~73 K to ~1 K per benchmark run
  * QUIC: vector sendStreamData() delegates to fast-path variant with
    batching, congestion-control gating, and ACK piggybacking
  * QUIC: raise initial congestion window to 10 MB (avoids CC stalls on
    loopback / LAN); CC still engages on actual loss
  * QUIC: CC wait loop spins 8× before falling back to poll(1 ms),
    avoiding unnecessary syscalls when ACKs are already queued
  * QUIC: stream FIN cleanup (MAX_STREAMS replenish) added to fast-path
    sendStreamData
  * Benchmark echo throughput: 1 KB 0.2→40 MB/s, 16 KB 0.7→85 MB/s,
    65 KB 30→100 MB/s, 262 KB 31→129 MB/s

 -- Jan Koester <jan.koester@tuxist.de>  Sat, 02 May 2026 12:00:00 +0200

libnetplus (20260501+1) unstable; urgency=medium

  * AES-GCM: implement 4-way pipelined AES-NI CTR encryption,
    exploiting counter-mode parallelism for higher throughput
  * AES-GCM: implement interleaved GHASH with encryption in a single
    pass, eliminating the second traversal over ciphertext
  * AES-GCM encrypt throughput improved ~3.5x (AES-128-GCM: 479 → 1720 MB/s,
    AES-256-GCM: 453 → 1565 MB/s at 256 KB payloads)

 -- Jan Koester <jan.koester@tuxist.de>  Thu, 01 May 2026 12:00:00 +0200

libnetplus (20260425+5) unstable; urgency=high

  * RSA Montgomery CIOS: fix heap buffer over-read in
    montgomeryMultiply_into — b operand was indexed up to mod.used
    without bounds check (b.used may be smaller, e.g. the constant 1).
    Caused SEC_ERROR_BAD_SIGNATURE in TLS handshakes.

 -- Jan Koester <jan.koester@tuxist.de>  Sat, 25 Apr 2026 20:00:00 +0200

libnetplus (20260425+4) unstable; urgency=medium

  * SHA-256 SHA-NI: fix message schedule bugs — double sha256msg1
    expansion, wrong W+K round pairing, and incorrect final register.
    All 12 NIST FIPS 180-4 test vectors now pass.

 -- Jan Koester <jan.koester@tuxist.de>  Sat, 25 Apr 2026 19:00:00 +0200

libnetplus (20260425+3) unstable; urgency=medium

  * SHA-256: add SHA-NI hardware-accelerated path with runtime CPU
    dispatch via __builtin_cpu_supports("sha")
  * Build: raise optimisation level from -O1 to -O2, enabling
    auto-vectorisation and better __uint128_t codegen

 -- Jan Koester <jan.koester@tuxist.de>  Sat, 25 Apr 2026 16:00:00 +0200

libnetplus (20260425+2) unstable; urgency=medium

  * RSA bigInt: switch from fixed 32-bit limbs to portable limb_t/dlimb_t
    typedefs — 64-bit limbs with __uint128_t accumulator on GCC/Clang,
    32-bit fallback on MSVC. Halves limb count for RSA-2048 (64→32),
    yielding ~4x fewer inner-loop iterations in Montgomery CIOS.

 -- Jan Koester <jan.koester@tuxist.de>  Sat, 25 Apr 2026 14:00:00 +0200

libnetplus (20260425+1) unstable; urgency=medium

  * RSA: replace separate multiply + reduce with fused CIOS
    (Coarsely Integrated Operand Scanning) in montgomeryMultiply_into,
    eliminating a full schoolbook multiplication pass and improving
    cache locality

 -- Jan Koester <jan.koester@tuxist.de>  Sat, 25 Apr 2026 12:00:00 +0200

libnetplus (20260424+22) unstable; urgency=medium

  * Fix remaining compiler warnings: remove unused derOctetString, enlarge
    snprintf buffer in derUtcTime, remove unused label in epoll.cpp,
    suppress GCC 14 false-positive -Wfree-nonheap-object in tls.cpp/quic.cpp

 -- Jan Koester <jan.koester@tuxist.de>  Thu, 24 Apr 2026 18:00:00 +0200

libnetplus (20260424+21) unstable; urgency=medium

  * Fix compiler warnings: remove unused debug variables in quic.cpp

 -- Jan Koester <jan.koester@tuxist.de>  Thu, 24 Apr 2026 17:30:00 +0200

libnetplus (20260424+20) unstable; urgency=medium

  * Disable QUIC_DBG macro after HTTP/3 debugging complete

 -- Jan Koester <jan.koester@tuxist.de>  Thu, 24 Apr 2026 17:15:00 +0200

libnetplus (20260424+19) unstable; urgency=medium

  * Add accept() debug logging for QUIC remote connection diagnosis

 -- Jan Koester <jan.koester@tuxist.de>  Thu, 24 Apr 2026 16:15:00 +0200

libnetplus (20260424+18) unstable; urgency=medium

  * Enable QUIC debug logging for HTTP/3 handshake diagnosis

 -- Jan Koester <jan.koester@tuxist.de>  Thu, 24 Apr 2026 15:55:00 +0200

libnetplus (20260414+17) unstable; urgency=medium

  * Add utils/certgen: self-signed RSA certificate + key generation API
  * Add netplus-certgen CLI tool for certificate generation
  * Optimize RSA key generation: fix bit_count (p,q now half of target N)
  * Add trial division by small primes before Miller-Rabin
  * Optimize modPow: use repeated doubling for R^2 mod N computation
  * Optimize isProbablyPrime: direct squaring instead of modPow(x,2,n)
  * Optimize bigIntToBytesBE: direct word extraction O(n) vs O(n^2)
  * Optimize shiftLeft: in-place without temp vector allocation
  * Add RSA key accessors: getN(), getE(), getD()

 -- Jan Koester <jan.koester@tuxist.de>  Mon, 14 Apr 2026 00:00:00 +0200

libnetplus (20260410+16) unstable; urgency=medium

  * Add PEM auto-detection for x509cert::loadFromFile() and rsa constructors
  * Add x509cert::loadAllFromPem() for PEM chain/bundle files
  * Add PKCS#12 (.p12/.pfx) parser with 3DES-CBC and PBES2/AES support
  * Add CertificateBundle::loadFromFile() with auto-detect by file extension

 -- Jan Koester <jan.koester@tuxist.de>  Thu, 10 Apr 2026 00:00:00 +0200

libnetplus (20260409+15) unstable; urgency=medium

  * Add netplus::isIPAddr() utility function (posix + windows)

 -- Jan Koester <jan.koester@tuxist.de>  Wed, 09 Apr 2026 00:00:00 +0200

libnetplus (20260409+14) unstable; urgency=medium

  * Increase BLOCKSIZE from 16384 to 65536 for improved streaming throughput

 -- Jan Koester <jan.koester@tuxist.de>  Wed, 09 Apr 2026 00:00:00 +0200

libnetplus (20260407+13) unstable; urgency=medium

  * New release

 -- Jan Koester <jan.koester@tuxist.de>  Tue, 07 Apr 2026 00:00:00 +0200

libnetplus (20260405+12) unstable; urgency=medium

  * Reduce QUIC sendStreamData flow-control stall limit from 5s to 500ms
    (MAX_FC_STALLS 5000 → 500) to prevent blocking on slow peers

 -- Jan Koester <jan.koester@tuxist.de>  Sun, 05 Apr 2026 00:00:00 +0000

libnetplus (20260405+11) unstable; urgency=medium

  * Add socketwait::waitReadMulti() to wait on multiple sockets at once
    using epoll/kqueue/select/poll (all 4 backends)

 -- Jan Koester <jan.koester@tuxist.de>  Sun, 05 Apr 2026 00:00:00 +0000

libnetplus (20260404+10) unstable; urgency=medium

  * Fix quic::pumpNetwork throwing NetException on EAGAIN/EWOULDBLOCK
    instead of returning gracefully; callers (paritypp store_stripe)
    treated the Note exception as a fatal error, failing all nodes

 -- Jan Koester <jan.koester@tuxist.de>  Sat, 04 Apr 2026 00:00:00 +0000

libnetplus (20260404+9) unstable; urgency=medium

  * Remove debug std::cerr logging from udp::bind() and epoll event workers
    to eliminate data races on _ZSt4cerr

 -- Jan Koester <jan.koester@tuxist.de>  Fri, 04 Apr 2026 00:00:00 +0000

libnetplus (20260404+8) unstable; urgency=medium

  * Fix QUIC stream limit exhaustion: increase initial_max_streams from 100 to 10M
  * Auto-cleanup completed streams and send MAX_STREAMS frames to replenish peer budget
  * Server sends MAX_STREAMS(bidi/uni) when peer-initiated streams are fully closed

 -- Jan Koester <jan.koester@tuxist.de>  Fri, 04 Apr 2026 23:00:00 +0200

libnetplus (20260404+7) unstable; urgency=medium

  * Remove [QUIC] server-side Initial/ServerHello debug logging

 -- Jan Koester <jan.koester@tuxist.de>  Fri, 04 Apr 2026 23:00:00 +0200

libnetplus (20260404+6) unstable; urgency=medium

  * Remove verbose [QUIC-client] debug logging from quic.cpp

 -- Jan Koester <jan.koester@tuxist.de>  Fri, 04 Apr 2026 20:30:00 +0200

libnetplus (20260403+5) unstable; urgency=medium

  * Handshake timeout tuning

 -- Jan Koester <jan.koester@tuxist.de>  Fri, 04 Apr 2026 05:00:00 +0200

libnetplus (20260403+4) unstable; urgency=medium

  * Use HANDSHAKE_TIMEOUT_MS (5000ms) in completeHandshake instead of
    hardcoded 1500ms — servers need time for crypto + key derivation

 -- Jan Koester <jan.koester@tuxist.de>  Fri, 04 Apr 2026 04:00:00 +0200

libnetplus (20260403+3) unstable; urgency=medium

  * Fix QUIC handshake packet loss: retry sendPacket on EAGAIN up to
    5 times with 1ms back-off instead of silently dropping packets

 -- Jan Koester <jan.koester@tuxist.de>  Fri, 04 Apr 2026 03:00:00 +0200

libnetplus (20260403+2) unstable; urgency=medium

  * Add client-side handshake debug logging: Initial/Handshake decrypt
    status, TLS message flow (ServerHello, EncryptedExtensions, etc.)

 -- Jan Koester <jan.koester@tuxist.de>  Fri, 04 Apr 2026 02:00:00 +0200

libnetplus (20260403+1) unstable; urgency=medium

  * Add udp::sendTo() method for unconnected socket sends
  * Rewrite quic::sendPacket() to use udp class methods instead of
    raw OS calls (sendto/send)

 -- Jan Koester <jan.koester@tuxist.de>  Fri, 04 Apr 2026 01:00:00 +0200

libnetplus (20260403) unstable; urgency=medium

  * Add QUIC handshake debug logging: log Initial packet reception
    (peer IP, port, length, version) and ServerHello send result

 -- Jan Koester <jan.koester@tuxist.de>  Fri, 04 Apr 2026 00:10:00 +0200

libnetplus (20260401) unstable; urgency=medium

  * Initial Debian packaging with multiarch support.

 -- Jan Koester <jan.koester@tuxist.de>  Wed, 01 Apr 2026 00:00:00 +0200
