fix: stop parliament accept starvation on outbound dial (0.9.22)

Peer dial used per-step read timeouts so a stuck handshake could block the
single-threaded daemon for tens of seconds; inbound hellos piled up unread
(CLOSE-WAIT). Use a wall-clock dial budget, drain accepts before each dial,
skip self, and only one side initiates idle polls.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
WHC
2026-10-29 13:19:03 +08:00
co-authored by Cursor
parent 2f96b050d6
commit de2eaf87f7
5 changed files with 129 additions and 45 deletions
+15
View File
@@ -9,6 +9,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
typedef struct {
os_socket_t listen;
@@ -109,8 +110,22 @@ int main(void) {
pthread_join(th, NULL);
assert(!srv2.ok);
/* Wall-clock dial budget: listener that never accepts must fail fast. */
os_socket_t ls3 = os_net_listen("127.0.0.1", 0, err, sizeof(err));
assert(ls3 != OS_SOCKET_BAD);
int port3 = os_net_port(ls3);
struct timespec t0, t1;
clock_gettime(CLOCK_MONOTONIC, &t0);
assert(cst_peer_dial("127.0.0.1", port3, &ca, ska, realm.pk, 800, &sess, err,
sizeof(err)) != 0);
clock_gettime(CLOCK_MONOTONIC, &t1);
long ms = (long)((t1.tv_sec - t0.tv_sec) * 1000 +
(t1.tv_nsec - t0.tv_nsec) / 1000000);
assert(ms >= 400 && ms < 2500);
os_net_close(ls);
os_net_close(ls2);
os_net_close(ls3);
os_net_cleanup();
puts("test_peer_auth: OK");
return 0;