diff --git a/src/connector.c b/src/connector.c index 6ac551be..51054bd3 100644 --- a/src/connector.c +++ b/src/connector.c @@ -353,6 +353,14 @@ out: return ret; } +static void stratifier_drop_id(ckpool_t *ckp, const int64_t id) +{ + char buf[256]; + + sprintf(buf, "dropclient=%"PRId64, id); + send_proc(ckp->stratifier, buf); +} + /* Client must hold a reference count */ static int drop_client(cdata_t *cdata, client_instance_t *client) { @@ -375,6 +383,7 @@ static int drop_client(cdata_t *cdata, client_instance_t *client) client_id, address_name); } LOGDEBUG("Connector dropped fd %d", fd); + stratifier_drop_id(cdata->ckp, client_id); } return fd; @@ -391,14 +400,6 @@ static void generator_drop_client(ckpool_t *ckp, const client_instance_t *client generator_add_send(ckp, val); } -static void stratifier_drop_id(ckpool_t *ckp, const int64_t id) -{ - char buf[256]; - - sprintf(buf, "dropclient=%"PRId64, id); - send_proc(ckp->stratifier, buf); -} - static void stratifier_drop_client(ckpool_t *ckp, const client_instance_t *client) { stratifier_drop_id(ckp, client->id); diff --git a/src/stratifier.c b/src/stratifier.c index 139424c1..c6c098e6 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -1780,10 +1780,11 @@ share_diff(char *coinbase, const uchar *enonce1bin, const workbase_t *wb, const return diff_from_target(hash); } -/* passthrough subclients have client_ids in the high bits */ -static inline bool subclient(const int64_t client_id) +/* Subclients have client_ids in the high bits. Returns the value of the parent + * client if one exists. */ +static inline int64_t subclient(const int64_t client_id) { - return (client_id > 0xffffffffll); + return (client_id >> 32); } /* Note recursive lock here - entered with workbase lock held, grabs instance lock */ @@ -1797,10 +1798,7 @@ static void send_node_block(sdata_t *sdata, const char *enonce1, const char *non /* Don't send the block back to a remote node if that's where it was * found. */ - if (subclient(client_id)) - skip = client_id >> 32; - else - skip = 0; + skip = subclient(client_id); ck_rlock(&sdata->instance_lock); if (sdata->node_instances) { @@ -2993,11 +2991,29 @@ static inline stratum_instance_t *ref_instance_by_id(sdata_t *sdata, const int64 static void __drop_client(sdata_t *sdata, stratum_instance_t *client, bool lazily, char **msg) { user_instance_t *user = client->user_instance; + bool parent = false; - if (unlikely(client->node)) + if (unlikely(client->node)) { DL_DELETE(sdata->node_instances, client); - if (unlikely(client->trusted)) + parent = true; + } else if (unlikely(client->trusted)) { DL_DELETE(sdata->remote_instances, client); + parent = true; + } else if (unlikely(client->passthrough)) + parent = true; + + /* Tag any subclients of this parent to be dropped lazily */ + if (parent) { + stratum_instance_t *tmp; + + for (tmp = sdata->stratum_instances; tmp; tmp = tmp->hh.next) { + int64_t subid = subclient(tmp->id); + + if (subid && subid == client->id) + tmp->dropped = true; + } + } + if (client->workername) { if (user) { ASPRINTF(msg, "Dropped client %s %s %suser %s worker %s %s", @@ -3071,8 +3087,9 @@ static stratum_instance_t *__recruit_stratum_instance(sdata_t *sdata) static stratum_instance_t *__stratum_add_instance(ckpool_t *ckp, int64_t id, const char *address, int server) { - stratum_instance_t *client; sdata_t *sdata = ckp->sdata; + stratum_instance_t *client; + int64_t pass_id; client = __recruit_stratum_instance(sdata); client->start_time = time(NULL); @@ -3090,12 +3107,10 @@ static stratum_instance_t *__stratum_add_instance(ckpool_t *ckp, int64_t id, con /* Points to ckp sdata in ckpool mode, but is changed later in proxy * mode . */ client->sdata = sdata; - if (subclient(id)) { - stratum_instance_t *remote; - int64_t pass_id = id >> 32; + if ((pass_id = subclient(id))) { + stratum_instance_t *remote = __instance_by_id(sdata, pass_id); id &= 0xffffffffll; - remote = __instance_by_id(sdata, pass_id); if (remote && remote->node) { client->latency = remote->latency; LOGINFO("Client %s inherited node latency of %d", @@ -3213,8 +3228,9 @@ static void stratum_broadcast(sdata_t *sdata, json_t *val, const int msg_type) static void stratum_add_send(sdata_t *sdata, json_t *val, const int64_t client_id, const int msg_type) { - smsg_t *msg; ckpool_t *ckp = sdata->ckp; + int64_t remote_id; + smsg_t *msg; if (ckp->node) { /* Node shouldn't be sending any messages as it only uses the @@ -3223,11 +3239,9 @@ static void stratum_add_send(sdata_t *sdata, json_t *val, const int64_t client_i return; } - if (subclient(client_id)) { - int64_t remote_id = client_id >> 32; - stratum_instance_t *remote; + if ((remote_id = subclient(client_id))) { + stratum_instance_t *remote = ref_instance_by_id(sdata, remote_id); - remote = ref_instance_by_id(sdata, remote_id); if (unlikely(!remote)) { json_decref(val); return;