Browse Source

Use separate structures for different linked lists used by clients to prevent cross list corruption.

master
Con Kolivas 7 years ago
parent
commit
0b45322be7
  1. 55
      src/stratifier.c

55
src/stratifier.c

@ -181,8 +181,17 @@ struct stratum_instance {
/* Virtualid used as unique local id for passthrough clients */ /* Virtualid used as unique local id for passthrough clients */
int64_t virtualid; int64_t virtualid;
stratum_instance_t *next; stratum_instance_t *recycled_next;
stratum_instance_t *prev; stratum_instance_t *recycled_prev;
stratum_instance_t *user_next;
stratum_instance_t *user_prev;
stratum_instance_t *node_next;
stratum_instance_t *node_prev;
stratum_instance_t *remote_next;
stratum_instance_t *remote_prev;
/* Descriptive of ID number and passthrough if any */ /* Descriptive of ID number and passthrough if any */
char identity[128]; char identity[128];
@ -885,7 +894,7 @@ static void send_node_workinfo(ckpool_t *ckp, sdata_t *sdata, const workbase_t *
json_set_string(wb_val, "coinb2", wb->coinb2); json_set_string(wb_val, "coinb2", wb->coinb2);
ck_rlock(&sdata->instance_lock); ck_rlock(&sdata->instance_lock);
DL_FOREACH(sdata->node_instances, client) { DL_FOREACH2(sdata->node_instances, client, node_next) {
ckmsg_t *client_msg; ckmsg_t *client_msg;
smsg_t *msg; smsg_t *msg;
json_t *json_msg = json_deep_copy(wb_val); json_t *json_msg = json_deep_copy(wb_val);
@ -899,7 +908,7 @@ static void send_node_workinfo(ckpool_t *ckp, sdata_t *sdata, const workbase_t *
DL_APPEND(bulk_send, client_msg); DL_APPEND(bulk_send, client_msg);
messages++; messages++;
} }
DL_FOREACH(sdata->remote_instances, client) { DL_FOREACH2(sdata->remote_instances, client, remote_next) {
ckmsg_t *client_msg; ckmsg_t *client_msg;
smsg_t *msg; smsg_t *msg;
json_t *json_msg = json_deep_copy(wb_val); json_t *json_msg = json_deep_copy(wb_val);
@ -1144,7 +1153,7 @@ static void send_node_transactions(ckpool_t *ckp, sdata_t *sdata, const json_t *
smsg_t *msg; smsg_t *msg;
ck_rlock(&sdata->instance_lock); ck_rlock(&sdata->instance_lock);
DL_FOREACH(sdata->node_instances, client) { DL_FOREACH2(sdata->node_instances, client, node_next) {
json_msg = json_deep_copy(txn_val); json_msg = json_deep_copy(txn_val);
json_set_string(json_msg, "node.method", stratum_msgs[SM_TRANSACTIONS]); json_set_string(json_msg, "node.method", stratum_msgs[SM_TRANSACTIONS]);
client_msg = ckalloc(sizeof(ckmsg_t)); client_msg = ckalloc(sizeof(ckmsg_t));
@ -1155,7 +1164,7 @@ static void send_node_transactions(ckpool_t *ckp, sdata_t *sdata, const json_t *
DL_APPEND(bulk_send, client_msg); DL_APPEND(bulk_send, client_msg);
messages++; messages++;
} }
DL_FOREACH(sdata->remote_instances, client) { DL_FOREACH2(sdata->remote_instances, client, remote_next) {
json_msg = json_deep_copy(txn_val); json_msg = json_deep_copy(txn_val);
json_set_string(json_msg, "method", stratum_msgs[SM_TRANSACTIONS]); json_set_string(json_msg, "method", stratum_msgs[SM_TRANSACTIONS]);
client_msg = ckalloc(sizeof(ckmsg_t)); client_msg = ckalloc(sizeof(ckmsg_t));
@ -1509,7 +1518,7 @@ static void downstream_json(sdata_t *sdata, const json_t *val, const int64_t cli
int messages = 0; int messages = 0;
ck_rlock(&sdata->instance_lock); ck_rlock(&sdata->instance_lock);
DL_FOREACH(sdata->remote_instances, client) { DL_FOREACH2(sdata->remote_instances, client, remote_next) {
ckmsg_t *client_msg; ckmsg_t *client_msg;
json_t *json_msg; json_t *json_msg;
smsg_t *msg; smsg_t *msg;
@ -1728,7 +1737,7 @@ static void add_remote_base(ckpool_t *ckp, sdata_t *sdata, workbase_t *wb)
/* Send a copy of this to all OTHER remote trusted servers as well */ /* Send a copy of this to all OTHER remote trusted servers as well */
ck_rlock(&sdata->instance_lock); ck_rlock(&sdata->instance_lock);
DL_FOREACH(sdata->remote_instances, client) { DL_FOREACH2(sdata->remote_instances, client, remote_next) {
ckmsg_t *client_msg; ckmsg_t *client_msg;
json_t *json_msg; json_t *json_msg;
smsg_t *msg; smsg_t *msg;
@ -1746,7 +1755,7 @@ static void add_remote_base(ckpool_t *ckp, sdata_t *sdata, workbase_t *wb)
DL_APPEND(bulk_send, client_msg); DL_APPEND(bulk_send, client_msg);
messages++; messages++;
} }
DL_FOREACH(sdata->node_instances, client) { DL_FOREACH2(sdata->node_instances, client, node_next) {
ckmsg_t *client_msg; ckmsg_t *client_msg;
json_t *json_msg; json_t *json_msg;
smsg_t *msg; smsg_t *msg;
@ -1934,7 +1943,7 @@ static void send_nodes_block(sdata_t *sdata, const json_t *block_val, const int6
skip = subclient(client_id); skip = subclient(client_id);
ck_rlock(&sdata->instance_lock); ck_rlock(&sdata->instance_lock);
DL_FOREACH(sdata->node_instances, client) { DL_FOREACH2(sdata->node_instances, client, node_next) {
ckmsg_t *client_msg; ckmsg_t *client_msg;
json_t *json_msg; json_t *json_msg;
smsg_t *msg; smsg_t *msg;
@ -2236,7 +2245,7 @@ static void __kill_instance(sdata_t *sdata, stratum_instance_t *client)
free(client->password); free(client->password);
free(client->useragent); free(client->useragent);
memset(client, 0, sizeof(stratum_instance_t)); memset(client, 0, sizeof(stratum_instance_t));
DL_APPEND(sdata->recycled_instances, client); DL_APPEND2(sdata->recycled_instances, client, recycled_prev, recycled_next);
} }
/* Called with instance_lock held. Note stats.users is protected by /* Called with instance_lock held. Note stats.users is protected by
@ -2296,7 +2305,7 @@ static void __del_client(sdata_t *sdata, stratum_instance_t *client)
HASH_DEL(sdata->stratum_instances, client); HASH_DEL(sdata->stratum_instances, client);
if (user) { if (user) {
DL_DELETE(user->clients, client); DL_DELETE2(user->clients, client, user_prev, user_next );
__dec_worker(sdata, user, client->worker_instance); __dec_worker(sdata, user, client->worker_instance);
} }
} }
@ -3226,10 +3235,10 @@ static void __drop_client(sdata_t *sdata, stratum_instance_t *client, bool lazil
bool parent = false; bool parent = false;
if (unlikely(client->node)) { if (unlikely(client->node)) {
DL_DELETE(sdata->node_instances, client); DL_DELETE2(sdata->node_instances, client, node_prev, node_next);
parent = true; parent = true;
} else if (unlikely(client->trusted)) { } else if (unlikely(client->trusted)) {
DL_DELETE(sdata->remote_instances, client); DL_DELETE2(sdata->remote_instances, client, remote_prev, remote_next);
parent = true; parent = true;
} else if (unlikely(client->passthrough)) } else if (unlikely(client->passthrough))
parent = true; parent = true;
@ -3302,7 +3311,7 @@ static stratum_instance_t *__recruit_stratum_instance(sdata_t *sdata)
stratum_instance_t *client = sdata->recycled_instances; stratum_instance_t *client = sdata->recycled_instances;
if (client) if (client)
DL_DELETE(sdata->recycled_instances, client); DL_DELETE2(sdata->recycled_instances, client, recycled_prev, recycled_next);
else { else {
client = ckzalloc(sizeof(stratum_instance_t)); client = ckzalloc(sizeof(stratum_instance_t));
sdata->stratum_generated++; sdata->stratum_generated++;
@ -3979,7 +3988,7 @@ static void userclients(sdata_t *sdata, const char *buf, int *sockd)
client_arr = json_array(); client_arr = json_array();
ck_rlock(&sdata->instance_lock); ck_rlock(&sdata->instance_lock);
DL_FOREACH(user->clients, client) { DL_FOREACH2(user->clients, client, user_next) {
json_array_append_new(client_arr, json_integer(client->id)); json_array_append_new(client_arr, json_integer(client->id));
} }
ck_runlock(&sdata->instance_lock); ck_runlock(&sdata->instance_lock);
@ -4019,7 +4028,7 @@ static void workerclients(sdata_t *sdata, const char *buf, int *sockd)
client_arr = json_array(); client_arr = json_array();
ck_rlock(&sdata->instance_lock); ck_rlock(&sdata->instance_lock);
DL_FOREACH(user->clients, client) { DL_FOREACH2(user->clients, client, user_next) {
if (strcmp(client->workername, workername)) if (strcmp(client->workername, workername))
continue; continue;
json_array_append_new(client_arr, json_integer(client->id)); json_array_append_new(client_arr, json_integer(client->id));
@ -4220,7 +4229,7 @@ static void user_clientinfo(sdata_t *sdata, const char *buf, int *sockd)
client_arr = json_array(); client_arr = json_array();
ck_rlock(&sdata->instance_lock); ck_rlock(&sdata->instance_lock);
DL_FOREACH(user->clients, client) { DL_FOREACH2(user->clients, client, user_next) {
json_array_append_new(client_arr, clientinfo(client)); json_array_append_new(client_arr, clientinfo(client));
} }
ck_runlock(&sdata->instance_lock); ck_runlock(&sdata->instance_lock);
@ -4260,7 +4269,7 @@ static void worker_clientinfo(sdata_t *sdata, const char *buf, int *sockd)
client_arr = json_array(); client_arr = json_array();
ck_rlock(&sdata->instance_lock); ck_rlock(&sdata->instance_lock);
DL_FOREACH(user->clients, client) { DL_FOREACH2(user->clients, client, user_next) {
if (strcmp(client->workername, workername)) if (strcmp(client->workername, workername))
continue; continue;
json_array_append_new(client_arr, clientinfo(client)); json_array_append_new(client_arr, clientinfo(client));
@ -5298,7 +5307,7 @@ static user_instance_t *generate_user(ckpool_t *ckp, stratum_instance_t *client,
ck_wlock(&sdata->instance_lock); ck_wlock(&sdata->instance_lock);
client->user_instance = user; client->user_instance = user;
client->worker_instance = worker; client->worker_instance = worker;
DL_APPEND(user->clients, client); DL_APPEND2(user->clients, client, user_prev, user_next);
__inc_worker(sdata,user, worker); __inc_worker(sdata,user, worker);
ck_wunlock(&sdata->instance_lock); ck_wunlock(&sdata->instance_lock);
@ -5345,7 +5354,7 @@ static void set_worker_mindiff(ckpool_t *ckp, const char *workername, int mindif
* if we can. Otherwise it will only act as a clamp on next share * if we can. Otherwise it will only act as a clamp on next share
* submission. */ * submission. */
ck_rlock(&sdata->instance_lock); ck_rlock(&sdata->instance_lock);
DL_FOREACH(user->clients, client) { DL_FOREACH2(user->clients, client, user_next) {
if (client->worker_instance != worker) if (client->worker_instance != worker)
continue; continue;
/* Per connection suggest diff overrides worker mindiff ugh */ /* Per connection suggest diff overrides worker mindiff ugh */
@ -6484,7 +6493,7 @@ static void add_mining_node(ckpool_t *ckp, sdata_t *sdata, stratum_instance_t *c
ck_wlock(&sdata->instance_lock); ck_wlock(&sdata->instance_lock);
client->node = true; client->node = true;
DL_APPEND(sdata->node_instances, client); DL_APPEND2(sdata->node_instances, client, node_prev, node_next);
__inc_instance_ref(client); __inc_instance_ref(client);
ck_wunlock(&sdata->instance_lock); ck_wunlock(&sdata->instance_lock);
@ -6498,7 +6507,7 @@ static void add_remote_server(sdata_t *sdata, stratum_instance_t *client)
{ {
ck_wlock(&sdata->instance_lock); ck_wlock(&sdata->instance_lock);
client->trusted = true; client->trusted = true;
DL_APPEND(sdata->remote_instances, client); DL_APPEND2(sdata->remote_instances, client, remote_prev, remote_next);
__inc_instance_ref(client); __inc_instance_ref(client);
ck_wunlock(&sdata->instance_lock); ck_wunlock(&sdata->instance_lock);

Loading…
Cancel
Save