Files
WHCandCursor de2eaf87f7 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>
2026-10-29 13:19:03 +08:00

60 lines
1.9 KiB
C

#ifndef CST_PEER_H
#define CST_PEER_H
#include "cst_realm.h"
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Mutual Realm certificate challenge over TCP, then ephemeral X25519 +
* XChaCha20-Poly1305 (Monocypher) for the session. Same Realm public key
* required on both sides. */
typedef struct {
cst_realm_cert_t remote;
char host[64];
int port;
intptr_t sock; /* open until cst_peer_close */
uint8_t aead_key[32];
uint64_t send_ctr;
uint64_t recv_ctr;
int sealed; /* 1 after key exchange */
} cst_peer_session_t;
/* Dial host:port, prove our cert, verify theirs, establish AEAD session.
* timeout_ms is a wall-clock budget for connect+handshake+kx (not per-read).
* Leaves sock open for post-handshake sync; call cst_peer_close. */
int cst_peer_dial(const char *host, int port, const cst_realm_cert_t *self,
const uint8_t self_sk[64], const uint8_t realm_pk[32],
int timeout_ms, cst_peer_session_t *out, char *err,
size_t err_sz);
/* Accept one connection on listening socket (from os_net_listen). */
int cst_peer_accept(intptr_t listen_sock, const cst_realm_cert_t *self,
const uint8_t self_sk[64], const uint8_t realm_pk[32],
int timeout_ms, cst_peer_session_t *out, char *err,
size_t err_sz);
void cst_peer_close(cst_peer_session_t *s);
/* After handshake: exchange parliament revision/context over the sealed
* channel. Higher revision wins. Returns 0 on success. */
typedef struct {
unsigned long revision;
char parliament_id[64];
char project_id[64];
char chair_instance[64];
char *context; /* malloc'd when loading; freed by caller after sync */
} cst_peer_sync_bundle_t;
int cst_peer_sync(cst_peer_session_t *s, cst_peer_sync_bundle_t *local,
int timeout_ms, char *err, size_t err_sz);
#ifdef __cplusplus
}
#endif
#endif