- runtime.sql: widen starttime to varchar(32). ctime() produces 25 chars;
MariaDB's default strict mode rejects the 20-char column instead of
silently truncating like the original MySQL 5.0 target did.
- SocketServer.cpp/SocketBase.cpp: the accept-loop's select() used `maxfd`
set only from `sock`, never updated for the ISC sockets (sckISC/sckISCII).
Any fd beyond nfds is left however FD_SET last set it, since select()
never examines it -- so those bits stayed permanently "set", and the
server treated them as always-ready. For the login server specifically
this was fatal: its sckISC is created but never listen()'d (the login
server has no inbound ISC use), so accept() on it returned EINVAL on
every single loop iteration, spinning the login server's CPU and
spamming the log without ever getting to the real client-facing accept()
in a timely way. Root-caused with a real client connecting for the first
time (this path was never exercised end-to-end before). Fixed by
including the ISC sockets in maxfd and skipping the ISC accept branch
entirely for the login server. Also initialize sckISC/sckISCII to
INVALID_SOCKET in the constructor -- they were previously left
uninitialized for server types that never touch them.
- tools/rose_login_test.cpp: protocol-level login smoke test. Links
directly against Src/Common/rosecrypt.cpp (the server's own encryption
code) rather than reimplementing the crypto, so there's no risk of a
second, subtly-wrong implementation. Documents the wire handshake
(0x703 encryption request -> 0x7FF -> 0x708 login, password[32]+username[16]
payload) for future reference.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>