BBS:      TELESC.NET.BR
Assunto:  src/ssh/README.md deucessh-conn.h ssh-conn.c ssh-internal.h src/ssh/te
De:       Deuc¨
Data:     Tue, 5 May 2026 08:02:38 -0700
-----------------------------------------------------------
https://gitlab.synchro.net/main/sbbs/-/commit/facce791262fb43be1302556
Modified Files:
	src/ssh/README.md deucessh-conn.h ssh-conn.c ssh-internal.h src/ssh/test/test_chan.c test_conn.c
Log Message:
DeuceSSH: rx-window enforcement + DSSH_PARAM_ACCEPT_EARLY_DATA

Two related changes that together let DeuceSSH clients tolerate
servers that begin sending CHANNEL_DATA before the terminal-request
response, while otherwise tightening rx-side window handling.

1. Universal rx-window truncation.

   handle_channel_data and handle_channel_extended_data now clip the
   inbound payload length to the locally-advertised window before
   invoking the ZC callback.  A peer that ignores the window can no
   longer drive the library into unbounded buffering -- bytes past
   the window are silently dropped and never reach the bytebuf.  The
   ZC callback contract is widened (and the typedef comment updated)
   to allow len == 0 or len < wire-payload; in-tree consumers
   (stream_zc_cb) already handled both safely.

2. Per-channel DSSH_PARAM_ACCEPT_EARLY_DATA opt-in (flag 0x02 + new
   dssh_chan_params_set_accept_early_data setter).

   Cryptlib-based servers that don't wait for
   CRYPT_SESSINFO_SSH_CHANNEL_TYPE to be set before sending (such as
   Mystic BBS) emit banner data immediately after CHANNEL_OPEN_
   CONFIRMATION, while local_window is still 0.  The flag asks the
   library to deliver pre-setup data anyway: while
   ch->setup_complete is still false, handle_channel_data /
   handle_channel_extended_data take a bypass branch that delivers
   the full dlen, leaves local_window untouched (no credit returned
   to the peer), and skips the ZC WINDOW_ADJUST.  Once
   send_window_adjust at the end of dssh_chan_open / dssh_chan_zc_
   open succeeds, setup_complete latches true and the bypass
   disengages permanently.

   Type-locked at chan_open entry: the flag is rejected (NULL
   return) for DSSH_CHAN_SUBSYSTEM since subsystem channels use a
   message queue and have no coherent destination for pre-setup
   bytes.

   init_channel_buffers is hoisted unconditionally to before
   open_session_channel so the bytebufs exist when the first DATA
   arrives.  Universal rx-truncation makes this a behavioural no-op
   for non-flagged channels (early data is clipped to len == 0
   before stream_zc_cb runs, so the freshly-allocated bytebuf is
   harmless).  The flag is the only thing that punches a hole in
   that, and only while !setup_complete.

7 new tests:

  - params_set_accept_early_data: setter toggles the bit, NULL guard
  - rx_truncation/default: closed window drops everything
  - rx_truncation/clips_to_window: dlen > local_window clipped to 4
  - rx_bypass/pre_setup: flagged + !setup_complete delivers full
    payload, local_window untouched
  - rx_bypass/disengages_post_setup: flagged + setup_complete drops
    again
  - early_data/type_lock_subsystem: dssh_chan_open returns NULL for
    SUBSYSTEM + ACCEPT_EARLY_DATA

OpenSSL: 3410/3410 pass.  Botan: 3411/3411 pass.

Co-Authored-By: Claude Opus 4.7 (1M context) 
n
---
  mSynchronetn  hgVertrauen n hHome of Synchronet n gh[vert/cvs/bbs].synchro.net

-----------------------------------------------------------
[Voltar]