The protocol length field is validated to 50 MiB, but a peer that sends
bytes which never assemble into a complete packet — for example an HTTP-mask
envelope without its terminating CRLF CRLF, which Parse() waits on
indefinitely — could grow the per-connection input buffer without bound.
handleConnection now closes the connection once unparsed buffered bytes
exceed MaxBufferedBytes (default 50 MiB + 64 KiB slack, covering the largest
legitimate packet plus its mask envelope and a read chunk).
Co-Authored-By: deepseek-v4-pro
The TCP device port is exposed directly to the public internet, so a single
host must not be able to exhaust the global connection budget, flood new
connection attempts, or brute-force the device authorization passcode.
- server: cap concurrent connections and the accept rate per source IP
(defaults 256 concurrent / 120 per minute, overridable via
YAMA_PERIP_MAX_CONNS and YAMA_PERIP_CONN_RATE). Rejections happen at
accept time, before any buffer or goroutine is allocated, and a rejected
device simply retries on its reconnect loop.
- cmd: throttle TOKEN_AUTH per source IP (120/min) and answer over-limit
attempts with a normal failed response so clients get a definitive reply.
- web: periodically sweep the login rate-limit maps so the username-keyed
one (which is attacker-controlled) cannot grow without bound.
Per-IP defaults are generous enough that a NAT office whose devices share
one source IP is unaffected.
Co-Authored-By: deepseek-v4-pro