|
|
|
@ -1727,14 +1727,27 @@ static inline bool client_active(stratum_instance_t *client)
|
|
|
|
|
return (client->authorised && !client->dropped); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Ask the connector asynchronously to send us dropclient commands if this
|
|
|
|
|
* client no longer exists. */ |
|
|
|
|
static void connector_test_client(ckpool_t *ckp, const int64_t id) |
|
|
|
|
{ |
|
|
|
|
char buf[256]; |
|
|
|
|
|
|
|
|
|
LOGDEBUG("Stratifier requesting connector test client %"PRId64, id); |
|
|
|
|
snprintf(buf, 255, "testclient=%"PRId64, id); |
|
|
|
|
async_send_proc(ckp, ckp->connector, buf); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* For creating a list of sends without locking that can then be concatenated
|
|
|
|
|
* to the stratum_sends list. Minimises locking and avoids taking recursive |
|
|
|
|
* locks. Sends only to sdata bound clients (everyone in ckpool) */ |
|
|
|
|
static void stratum_broadcast(sdata_t *sdata, json_t *val) |
|
|
|
|
{ |
|
|
|
|
sdata_t *ckp_sdata = sdata->ckp->data; |
|
|
|
|
ckpool_t *ckp = sdata->ckp; |
|
|
|
|
sdata_t *ckp_sdata = ckp->data; |
|
|
|
|
stratum_instance_t *client, *tmp; |
|
|
|
|
ckmsg_t *bulk_send = NULL; |
|
|
|
|
time_t now_t = time(NULL); |
|
|
|
|
ckmsgq_t *ssends; |
|
|
|
|
|
|
|
|
|
if (unlikely(!val)) { |
|
|
|
@ -1742,6 +1755,7 @@ static void stratum_broadcast(sdata_t *sdata, json_t *val)
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Use this locking as an opportunity to test other clients. */ |
|
|
|
|
ck_rlock(&ckp_sdata->instance_lock); |
|
|
|
|
HASH_ITER(hh, ckp_sdata->stratum_instances, client, tmp) { |
|
|
|
|
ckmsg_t *client_msg; |
|
|
|
@ -1749,6 +1763,22 @@ static void stratum_broadcast(sdata_t *sdata, json_t *val)
|
|
|
|
|
|
|
|
|
|
if (sdata != ckp_sdata && client->sdata != sdata) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
/* Test for clients that haven't authed in over a minute and drop them */ |
|
|
|
|
if (!client->authorised) { |
|
|
|
|
if (now_t > client->start_time + 60) { |
|
|
|
|
client->dropped = true; |
|
|
|
|
connector_drop_client(ckp, client->id); |
|
|
|
|
} |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
/* Look for clients that may have been dropped which the stratifer has
|
|
|
|
|
* not been informed about and ask the connector of they still exist */ |
|
|
|
|
if (client->dropped || client->reconnect) { |
|
|
|
|
connector_test_client(ckp, client->id); |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!client_active(client)) |
|
|
|
|
continue; |
|
|
|
|
client_msg = ckalloc(sizeof(ckmsg_t)); |
|
|
|
@ -1808,17 +1838,6 @@ static void dec_worker(ckpool_t *ckp, user_instance_t *instance)
|
|
|
|
|
mutex_unlock(&sdata->stats_lock); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Ask the connector asynchronously to send us dropclient commands if this
|
|
|
|
|
* client no longer exists. */ |
|
|
|
|
static void connector_test_client(ckpool_t *ckp, const int64_t id) |
|
|
|
|
{ |
|
|
|
|
char buf[256]; |
|
|
|
|
|
|
|
|
|
LOGDEBUG("Stratifier requesting connector test client %"PRId64, id); |
|
|
|
|
snprintf(buf, 255, "testclient=%"PRId64, id); |
|
|
|
|
async_send_proc(ckp, ckp->connector, buf); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void drop_client(ckpool_t *ckp, sdata_t *sdata, const int64_t id) |
|
|
|
|
{ |
|
|
|
|
stratum_instance_t *client, *tmp; |
|
|
|
@ -1828,25 +1847,7 @@ static void drop_client(ckpool_t *ckp, sdata_t *sdata, const int64_t id)
|
|
|
|
|
|
|
|
|
|
LOGINFO("Stratifier asked to drop client %"PRId64, id); |
|
|
|
|
|
|
|
|
|
/* Use this locking as an opportunity to test other clients. */ |
|
|
|
|
ck_ilock(&sdata->instance_lock); |
|
|
|
|
/* Test for clients that haven't authed in over a minute and drop them */ |
|
|
|
|
HASH_ITER(hh, sdata->stratum_instances, client, tmp) { |
|
|
|
|
if (client->authorised) |
|
|
|
|
continue; |
|
|
|
|
if (now_t > client->start_time + 60) { |
|
|
|
|
client->dropped = true; |
|
|
|
|
connector_drop_client(ckp, client->id); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Look for clients that may have been dropped which the stratifer has
|
|
|
|
|
* not been informed about and ask the connector of they still exist */ |
|
|
|
|
HASH_ITER(hh, sdata->stratum_instances, client, tmp) { |
|
|
|
|
if (client->dropped || client->reconnect) |
|
|
|
|
connector_test_client(ckp, client->id); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
client = __instance_by_id(sdata, id); |
|
|
|
|
/* Upgrade to write lock */ |
|
|
|
|
ck_ulock(&sdata->instance_lock); |
|
|
|
|