perf: accept thread + dial backoff; join/peers.json (0.9.23)
Run inbound peer handling on its own thread so outbound dials cannot starve :9100. Failed peers cool down exponentially. Also land --join (member seat) and realm/peers.json seed discovery for Tailscale meshes. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -250,6 +250,60 @@ static void ingest_local(cst_discover_t *d) {
|
||||
remember(d, &list[i]);
|
||||
}
|
||||
|
||||
/* Optional realm/peers.json for meshes without multicast (e.g. Tailscale):
|
||||
* {"peers":[{"host":"100.x.y.z","port":9100,"iid":"seat-a","name":"a"}]} */
|
||||
static void ingest_seed_peers(cst_discover_t *d) {
|
||||
char dir[OS_PATH_MAX], path[OS_PATH_MAX];
|
||||
if (cst_realm_dir(dir, sizeof(dir)) != 0)
|
||||
return;
|
||||
if (os_path_join(path, sizeof(path), dir, "peers.json") != 0)
|
||||
return;
|
||||
FILE *f = fopen(path, "rb");
|
||||
if (!f)
|
||||
return;
|
||||
cst_buf_t b = {0};
|
||||
char chunk[4096];
|
||||
size_t n;
|
||||
while ((n = fread(chunk, 1, sizeof(chunk), f)) && b.len < 64 * 1024)
|
||||
cst_buf_append(&b, chunk, n);
|
||||
fclose(f);
|
||||
cJSON *root = cJSON_Parse(b.buf ? b.buf : "{}");
|
||||
cst_buf_free(&b);
|
||||
if (!root)
|
||||
return;
|
||||
cJSON *arr = cJSON_GetObjectItemCaseSensitive(root, "peers");
|
||||
if (!cJSON_IsArray(arr)) {
|
||||
cJSON_Delete(root);
|
||||
return;
|
||||
}
|
||||
const cJSON *it;
|
||||
cJSON_ArrayForEach(it, arr) {
|
||||
const cJSON *host = cJSON_GetObjectItemCaseSensitive(it, "host");
|
||||
const cJSON *port = cJSON_GetObjectItemCaseSensitive(it, "port");
|
||||
const cJSON *iid = cJSON_GetObjectItemCaseSensitive(it, "iid");
|
||||
const cJSON *name = cJSON_GetObjectItemCaseSensitive(it, "name");
|
||||
const cJSON *rid = cJSON_GetObjectItemCaseSensitive(it, "rid");
|
||||
if (!cJSON_IsString(host) || !host->valuestring[0] || !cJSON_IsNumber(port) ||
|
||||
port->valueint <= 0 || !cJSON_IsString(iid) || !iid->valuestring[0])
|
||||
continue;
|
||||
if (cJSON_IsString(rid) && rid->valuestring[0] &&
|
||||
strcmp(rid->valuestring, d->realm_fp) != 0)
|
||||
continue;
|
||||
cst_peer_info_t p;
|
||||
memset(&p, 0, sizeof(p));
|
||||
snprintf(p.realm_fp, sizeof(p.realm_fp), "%s", d->realm_fp);
|
||||
snprintf(p.instance_id, sizeof(p.instance_id), "%s", iid->valuestring);
|
||||
snprintf(p.host, sizeof(p.host), "%s", host->valuestring);
|
||||
if (cJSON_IsString(name) && name->valuestring[0])
|
||||
snprintf(p.name, sizeof(p.name), "%s", name->valuestring);
|
||||
else
|
||||
snprintf(p.name, sizeof(p.name), "%s", iid->valuestring);
|
||||
p.port = port->valueint;
|
||||
remember(d, &p);
|
||||
}
|
||||
cJSON_Delete(root);
|
||||
}
|
||||
|
||||
static int send_beacon(cst_discover_t *d) {
|
||||
if (d->sock == DISC_BAD)
|
||||
return -1;
|
||||
@@ -310,6 +364,7 @@ static void *discover_main(void *arg) {
|
||||
(void)cst_discover_local_put(d->realm_fp, d->instance_id, d->name,
|
||||
d->peer_port);
|
||||
ingest_local(d);
|
||||
ingest_seed_peers(d);
|
||||
}
|
||||
ticks++;
|
||||
if (d->sock == DISC_BAD) {
|
||||
|
||||
Reference in New Issue
Block a user