• src/sbbs3/js_socket.cpp js_socket.h

    From Rob Swindell (on Windows 11)@VERT to Git commit to main/sbbs/master on Tue Nov 10 20:49:05 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/ab31f9f1c04c35ede2c86d15
    Modified Files:
    src/sbbs3/js_socket.cpp js_socket.h
    Log Message:
    js: don't probe a TLS session known to hold no buffered plaintext

    Since 059de49b8e (2026-07-16), js_handle_events() and Socket.poll() call js_socket_tls_readable() for each TLS socket before waiting on its
    descriptor, to find plaintext that cryptlib has decrypted but not yet
    returned. The probe is a one-byte cryptPopData() with a zero read timeout,
    and on Windows that still waits on the descriptor for about a timer tick.
    The event loop dispatches one callback per iteration, so every callback
    paid that wait once per TLS socket with a read event: with 40 idle TLS
    sockets a script got about 3 callbacks per second instead of several
    hundred thousand.

    The ircd relays each line from a hub to every directly linked server, one queued callback per send, so with 46 linked servers Vertrauen took longer
    than the 30-second clock announcement deadline to read a hub's burst and dropped the link each time it was established.

    A pop that returns less than was asked for, or times out, leaves nothing buffered in the session: only new data on the descriptor can make it
    readable again, and select()/poll() reports that. Record it in the socket
    and skip the probe until a pop fills its caller's buffer or a new session
    is created.

    Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Rob Swindell (on Windows 11)@VERT to Git commit to main/sbbs/master on Wed Nov 11 13:56:56 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/3cf61919e19595adf7612375
    Modified Files:
    src/sbbs3/js_socket.cpp js_socket.h
    Log Message:
    js: don't mark a TLS session drained while it holds a saved error

    When cryptlib meets a fatal error after copying plaintext, the pop
    returns that data with CRYPT_OK and reports the error on the next pop
    only. It has already consumed the input, so the descriptor never
    signals it. Since ab31f9f1c0 (2026-11-10) a short successful pop marked
    the session drained, js_socket_tls_readable() stopped probing, and an event-driven reader was never told of the failure while the TCP
    connection stayed open and idle (reported by Deuce on that commit).

    Each pop begins by clearing the session's error message, so a message
    present after a successful pop is that saved error: leave the session
    undrained then, and the next probe finds it. Asking for the message
    does no I/O, so a clean short read costs no extra wait.

    Reproduced with a TLS 1.2 peer that sends data and a corrupt record,
    or data and a close alert, in one write and keeps TCP open: a script
    reading from a "read" callback got the data and nothing more for 8
    seconds before, and is told about 2 ms after the data now. Built with
    MSVC and GCC; the reproduction was run on the GCC build only.

    Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net