• src/Directory.Build.propsdocs/v322_new.md

    From Rob Swindell (on Windows 11)@VERT to Git commit to main/sbbs/master on Sun Aug 2 19:20:56 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/031df44f62dd9ac0040a2a27
    Added Files:
    src/Directory.Build.props
    Modified Files:
    docs/v322_new.md
    Log Message:
    Windows: raise FD_SETSIZE to 1024 for all MSBuild projects

    Winsock defaults FD_SETSIZE to 64, and nothing in the tree raised it.
    FD_SET() silently discards every socket past the 64th, after which
    select() can never report it ready.

    The JS event loop reaches that ceiling: js_internal.cpp polls its event
    list with select() on Windows (the poll() alternative is compiled only
    where PREFER_POLL is defined, which src/build/Common.gmake does for
    non-Win32 builds only, since 663ca552e6, 2021-03-31). Events are
    inserted at the head of the list and the fill loop walks it forward, so
    the oldest event is the first one dropped -- for a JS server that is the listening socket registered at startup. A Win32 JS server holding 64+
    sockets therefore stops accepting new connections entirely while every established connection keeps working, and the kernel still completes the
    TCP handshake from the listen backlog, so it presents as a network fault
    rather than a server one.

    Reachable since the socket-callback event loop landed in 1928973941 (2021-04-02); ircd.js moved its accept path into it in d7cb93923c
    (2021-05-22), before which it polled its listeners directly each pass.
    Observed on vert.synchro.net, a Win32 IRCd hub with 57 server links.

    The value has to be identical in every translation unit -- fd_set is
    { u_int fd_count; SOCKET fd_array[FD_SETSIZE]; }, and sbbs.h exports js_socket_add()/js_socket_isset(), which take fd_set* across the
    sbbs.dll boundary -- so it is set in src/Directory.Build.props, which
    also covers xpdev for the solutions that build it outside sbbs3.sln.
    Redefining FD_SETSIZE is explicitly supported by winsock2.h, and
    ws2_32.dll tolerates the larger struct because select() and
    __WSAFDIsSet() only walk fd_count entries.

    Switching Windows to poll()/WSAPoll() instead is the other candidate
    fix; see issue #1212 for what currently stands in the way.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

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