Two bugs prevented the cluster from working after a stop/start cycle:
1. tcp_listen_tcp() and tcp_listen_tls() had reuse_addr set to false,
causing bind() to fail with EADDRINUSE when ports are in TIME_WAIT
state after a restart. Set SO_REUSEADDR to true.
2. The vsr_boot_marker file (created in CWD on first boot) was never
cleaned up on cluster stop. On restart, all nodes would enter
STATUS_RECOVERY, but since RECOVERY messages are only processed by
nodes in STATUS_NORMAL, the entire cluster would deadlock with no
node able to recover. Remove the marker in cluster.sh stop.
https://claude.ai/code/session_01U72omHJrk95xFwm22Rkqgt
- Use closesocket() instead of close() for sockets on Windows (lib/tcp.c)
- Call WSAStartup in tcp_init so outbound connections work (lib/tcp.c)
- Check WSAGetLastError() instead of errno for recv/send on Windows (lib/tcp.c)
- Use WSAEWOULDBLOCK instead of EINPROGRESS for non-blocking connect (lib/tcp.c)
- Add NULL guard in tcp_write for stale connection handles (lib/tcp.c)
- Fix ConnMetadata/TCP_Conn index mismatch in get_next_message: use
event.handle.idx directly instead of searching for a free metadata
slot, which could diverge when stale entries remain from failed
outbound connections (lib/message.c)
- Initialize num_senders to 0 and skip unused metadata in
find_conn_by_target (lib/message.c)
- Clear ready flag in http_server_next_request to prevent infinite
loop (lib/http_server.c)
- Add CRT invalid parameter handler for the HTTP proxy (src/main.c)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>