• src/sbbs3/mqtt_broker.cpp

    From Deuc¿@VERT to Git commit to main/sbbs/m on Friday, May 08, 2026 21:16:00
    https://gitlab.synchro.net/main/sbbs/-/commit/128c1b6d5e4214e5884ace03
    Added Files:
    src/sbbs3/mqtt_broker.cpp mqtt_broker.h mqtt_broker_glue.cpp mqtt_protocol.cpp mqtt_protocol.h mqtt_topic.cpp mqtt_topic.h
    Modified Files:
    src/sbbs3/mqtt.c mqtt.h objects.mk src/sbbs3/scfg/scfgnet.c src/sbbs3/scfgdefs.h scfglib1.c scfgsave.c
    Log Message:
    mqtt: add optional experimental internal MQTT 5.0 broker

    C++ implementation of an MQTT 5.0 broker that runs as an in-process
    service, eliminating the libmosquitto dependency and solving the
    broker.js startup ordering problem.

    When InternalBroker=true in [MQTT], mqtt_startup() launches a broker
    thread and registers each server as a local client. Publish and
    subscribe calls go directly to the broker's routing engine without
    network overhead. External clients (qtmonitor) connect via TLS-PSK
    using the same Cryptlib infrastructure as other Synchronet servers.

    Architecture:
    - mqtt_protocol.h/.cpp: MQTT 5.0 wire codec (VBI, UTF-8, properties,
    all packet types). Three-tier data model with shared_ptr messages.
    - mqtt_topic.h/.cpp: trie-based topic tree with +/# wildcard matching,
    retained message store with shared_ptr ownership and expiry.
    - mqtt_broker.h/.cpp: broker thread with select() event loop, local
    client interface (mutex-protected), network client handling, TLS-PSK
    via Cryptlib, PSK table from sysop user list, session management,
    QoS 0/1/2 state machines, will messages with delay, session expiry,
    clean start/resume, keep-alive timeout.
    - mqtt_broker_glue.cpp: C linkage bridge between mqtt.c and the C++
    broker. Broker logs via startup->lputs for console and $SYS/broker/
    topics for MQTT. Recursion guard prevents logpublishlog loops.
    - mqtt.c: dual-path logic in all mqtt_pub_*/mqtt_subscribe functions.
    mqtt_dispatch_message shared between mosquitto and internal broker.
    - scfgdefs.h/scfglib1.c/scfgsave.c: InternalBroker config field.
    - scfg/scfgnet.c: UI toggle, hides external broker settings when
    internal broker is enabled.

    $SYS/broker/version retained message set at startup with full version
    string (broker_ver()). $SYS/broker/log/{level} for broker log messages.

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

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deuc¿@VERT to Git commit to main/sbbs/m on Friday, May 08, 2026 21:33:00
    https://gitlab.synchro.net/main/sbbs/-/commit/791fe91dd69b7cf6dc9f9f9b
    Modified Files:
    src/sbbs3/mqtt_broker.cpp
    Log Message:
    mqtt: fix MSVC build errors in internal broker

    Move sockwrap.h out of extern "C" block to prevent Windows SDK
    templates from being declared with C linkage. Parenthesize std::min
    calls to prevent Windows min/max macro interference.

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

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deuc¿@VERT to Git commit to main/sbbs/m on Saturday, May 09, 2026 22:50:00
    https://gitlab.synchro.net/main/sbbs/-/commit/7372b198cc5347a0cade1ae7
    Modified Files:
    src/sbbs3/mqtt_broker.cpp mqtt_broker.h
    Log Message:
    mqtt: split into accept/broker threads, flush from caller, poll/select

    Accept thread handles blocking TLS handshakes. Broker thread uses
    poll() (PREFER_POLL) or select() for network session I/O with 1s
    timeout. local_publish and publish_sys flush network send buffers
    directly in the calling thread, eliminating delivery latency for local-to-network message routing. Thread names set via SetThreadName.

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

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deuc¿@VERT to Git commit to main/sbbs/m on Sunday, May 10, 2026 19:29:00
    https://gitlab.synchro.net/main/sbbs/-/commit/7c52f1a90e33431d5824fc46
    Modified Files:
    src/sbbs3/mqtt_broker.cpp mqtt_broker.h
    Log Message:
    mqtt_broker: fix session map key collision on socket descriptor reuse

    Sessions were keyed by "pending-{socket}" strings. When a client
    disconnected, the session stayed in the map with socket=-1. When
    the OS reused the socket descriptor for a new connection, the old
    dead session was silently overwritten, corrupting broker state and
    causing subsequent connections to fail.

    Fix: key sessions by SOCKET descriptor directly. Dead sessions are
    erased before creating new entries for the same descriptor. Cleanup (unsubscribe, will delivery) now happens before socket close to
    ensure the descriptor isn't reused while cleanup is in progress.

    Also: use INVALID_SOCKET consistently instead of -1 for invalid
    socket descriptors (portability).

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

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deuc¿@VERT to Git commit to main/sbbs/m on Sunday, May 10, 2026 20:50:00
    https://gitlab.synchro.net/main/sbbs/-/commit/cd30ec911e5642a03d5acc62
    Modified Files:
    src/sbbs3/mqtt_broker.cpp
    Log Message:
    mqtt_broker: add DEBUG logging for unsubscribe and ping

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

    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net
  • From Deuc¿@VERT to Git commit to main/sbbs/m on Monday, May 11, 2026 10:45:00
    https://gitlab.synchro.net/main/sbbs/-/commit/35fa5b0d4150078a76e4ab7d
    Modified Files:
    src/sbbs3/mqtt_broker.cpp mqtt_topic.cpp mqtt_topic.h
    Log Message:
    mqtt_broker: periodic cleanup of expired retained messages

    Walk the topic tree once per minute and remove retained messages whose MESSAGE_EXPIRY property has elapsed. Previously, expired retained
    messages were only skipped on delivery to new subscribers but never
    actually removed from the tree.

    Nothing currently sets MESSAGE_EXPIRY, but this prevents unbounded
    accumulation if/when publishers start using it.

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

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