|
|
@ -157,28 +157,7 @@ static int64_t workbase_id; |
|
|
|
static int64_t blockchange_id; |
|
|
|
static int64_t blockchange_id; |
|
|
|
static char lasthash[68]; |
|
|
|
static char lasthash[68]; |
|
|
|
|
|
|
|
|
|
|
|
/* For protecting the stratum msg data */ |
|
|
|
|
|
|
|
static pthread_mutex_t stratum_recv_lock; |
|
|
|
|
|
|
|
static pthread_mutex_t stratum_send_lock; |
|
|
|
|
|
|
|
static pthread_mutex_t sshare_lock; |
|
|
|
|
|
|
|
static pthread_mutex_t sauth_lock; |
|
|
|
|
|
|
|
static pthread_mutex_t ckdbq_lock; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* For signalling the threads to wake up and do work */ |
|
|
|
|
|
|
|
static pthread_cond_t stratum_recv_cond; |
|
|
|
|
|
|
|
static pthread_cond_t stratum_send_cond; |
|
|
|
|
|
|
|
static pthread_cond_t sshare_cond; |
|
|
|
|
|
|
|
static pthread_cond_t sauth_cond; |
|
|
|
|
|
|
|
static pthread_cond_t ckdbq_cond; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* For the linked list of all queued messages */ |
|
|
|
|
|
|
|
static stratum_msg_t *stratum_recvs; |
|
|
|
|
|
|
|
static stratum_msg_t *stratum_sends; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct json_params { |
|
|
|
struct json_params { |
|
|
|
struct json_params *next; |
|
|
|
|
|
|
|
struct json_params *prev; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
json_t *params; |
|
|
|
json_t *params; |
|
|
|
json_t *id_val; |
|
|
|
json_t *id_val; |
|
|
|
int client_id; |
|
|
|
int client_id; |
|
|
@ -186,20 +165,26 @@ struct json_params { |
|
|
|
|
|
|
|
|
|
|
|
typedef struct json_params json_params_t; |
|
|
|
typedef struct json_params json_params_t; |
|
|
|
|
|
|
|
|
|
|
|
static json_params_t *sshares; |
|
|
|
|
|
|
|
static json_params_t *sauths; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct ckdb_msg { |
|
|
|
struct ckdb_msg { |
|
|
|
struct ckdb_msg *next; |
|
|
|
|
|
|
|
struct ckdb_msg *prev; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
json_t *val; |
|
|
|
json_t *val; |
|
|
|
int idtype; |
|
|
|
int idtype; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
typedef struct ckdb_msg ckdb_msg_t; |
|
|
|
typedef struct ckdb_msg ckdb_msg_t; |
|
|
|
|
|
|
|
|
|
|
|
static ckdb_msg_t *ckdb_msgs; |
|
|
|
/* Stratum json messages with their associated client id */ |
|
|
|
|
|
|
|
struct smsg { |
|
|
|
|
|
|
|
json_t *json_msg; |
|
|
|
|
|
|
|
int client_id; |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct smsg smsg_t; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static ckmsgq_t *ssends; // Stratum sends
|
|
|
|
|
|
|
|
static ckmsgq_t *srecvs; // Stratum receives
|
|
|
|
|
|
|
|
static ckmsgq_t *ckdbq; // ckdb
|
|
|
|
|
|
|
|
static ckmsgq_t *sshareq; // Stratum share sends
|
|
|
|
|
|
|
|
static ckmsgq_t *sauthq; // Stratum authorisations
|
|
|
|
|
|
|
|
|
|
|
|
static int user_instance_id; |
|
|
|
static int user_instance_id; |
|
|
|
|
|
|
|
|
|
|
@ -427,11 +412,7 @@ static void ckdbq_add(const int idtype, json_t *val) |
|
|
|
|
|
|
|
|
|
|
|
msg->val = val; |
|
|
|
msg->val = val; |
|
|
|
msg->idtype = idtype; |
|
|
|
msg->idtype = idtype; |
|
|
|
|
|
|
|
ckmsgq_add(ckdbq, msg); |
|
|
|
mutex_lock(&ckdbq_lock); |
|
|
|
|
|
|
|
DL_APPEND(ckdb_msgs, msg); |
|
|
|
|
|
|
|
pthread_cond_signal(&ckdbq_cond); |
|
|
|
|
|
|
|
mutex_unlock(&ckdbq_lock); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void send_workinfo(ckpool_t *ckp, workbase_t *wb) |
|
|
|
static void send_workinfo(ckpool_t *ckp, workbase_t *wb) |
|
|
@ -796,15 +777,11 @@ out: |
|
|
|
|
|
|
|
|
|
|
|
static void stratum_add_recvd(json_t *val) |
|
|
|
static void stratum_add_recvd(json_t *val) |
|
|
|
{ |
|
|
|
{ |
|
|
|
stratum_msg_t *msg; |
|
|
|
smsg_t *msg; |
|
|
|
|
|
|
|
|
|
|
|
msg = ckzalloc(sizeof(stratum_msg_t)); |
|
|
|
msg = ckzalloc(sizeof(smsg_t)); |
|
|
|
msg->json_msg = val; |
|
|
|
msg->json_msg = val; |
|
|
|
|
|
|
|
ckmsgq_add(srecvs, msg); |
|
|
|
mutex_lock(&stratum_recv_lock); |
|
|
|
|
|
|
|
DL_APPEND(stratum_recvs, msg); |
|
|
|
|
|
|
|
pthread_cond_signal(&stratum_recv_cond); |
|
|
|
|
|
|
|
mutex_unlock(&stratum_recv_lock); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* For creating a list of sends without locking that can then be concatenated
|
|
|
|
/* For creating a list of sends without locking that can then be concatenated
|
|
|
@ -813,7 +790,7 @@ static void stratum_add_recvd(json_t *val) |
|
|
|
static void stratum_broadcast(json_t *val) |
|
|
|
static void stratum_broadcast(json_t *val) |
|
|
|
{ |
|
|
|
{ |
|
|
|
stratum_instance_t *instance, *tmp; |
|
|
|
stratum_instance_t *instance, *tmp; |
|
|
|
stratum_msg_t *bulk_send = NULL; |
|
|
|
ckmsg_t *bulk_send = NULL; |
|
|
|
|
|
|
|
|
|
|
|
if (unlikely(!val)) { |
|
|
|
if (unlikely(!val)) { |
|
|
|
LOGERR("Sent null json to stratum_broadcast"); |
|
|
|
LOGERR("Sent null json to stratum_broadcast"); |
|
|
@ -822,14 +799,17 @@ static void stratum_broadcast(json_t *val) |
|
|
|
|
|
|
|
|
|
|
|
ck_rlock(&instance_lock); |
|
|
|
ck_rlock(&instance_lock); |
|
|
|
HASH_ITER(hh, stratum_instances, instance, tmp) { |
|
|
|
HASH_ITER(hh, stratum_instances, instance, tmp) { |
|
|
|
stratum_msg_t *msg; |
|
|
|
ckmsg_t *client_msg; |
|
|
|
|
|
|
|
smsg_t *msg; |
|
|
|
|
|
|
|
|
|
|
|
if (!instance->authorised) |
|
|
|
if (!instance->authorised) |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
msg = ckzalloc(sizeof(stratum_msg_t)); |
|
|
|
client_msg = ckalloc(sizeof(ckmsg_t)); |
|
|
|
|
|
|
|
msg = ckzalloc(sizeof(smsg_t)); |
|
|
|
msg->json_msg = json_deep_copy(val); |
|
|
|
msg->json_msg = json_deep_copy(val); |
|
|
|
msg->client_id = instance->id; |
|
|
|
msg->client_id = instance->id; |
|
|
|
DL_APPEND(bulk_send, msg); |
|
|
|
client_msg->data = msg; |
|
|
|
|
|
|
|
DL_APPEND(bulk_send, client_msg); |
|
|
|
} |
|
|
|
} |
|
|
|
ck_runlock(&instance_lock); |
|
|
|
ck_runlock(&instance_lock); |
|
|
|
|
|
|
|
|
|
|
@ -838,27 +818,23 @@ static void stratum_broadcast(json_t *val) |
|
|
|
if (!bulk_send) |
|
|
|
if (!bulk_send) |
|
|
|
return; |
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
mutex_lock(&stratum_send_lock); |
|
|
|
mutex_lock(&ssends->lock); |
|
|
|
if (stratum_sends) |
|
|
|
if (ssends->msgs) |
|
|
|
DL_CONCAT(stratum_sends, bulk_send); |
|
|
|
DL_CONCAT(ssends->msgs, bulk_send); |
|
|
|
else |
|
|
|
else |
|
|
|
stratum_sends = bulk_send; |
|
|
|
ssends->msgs = bulk_send; |
|
|
|
pthread_cond_signal(&stratum_send_cond); |
|
|
|
pthread_cond_signal(&ssends->cond); |
|
|
|
mutex_unlock(&stratum_send_lock); |
|
|
|
mutex_unlock(&ssends->lock); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void stratum_add_send(json_t *val, int client_id) |
|
|
|
static void stratum_add_send(json_t *val, int client_id) |
|
|
|
{ |
|
|
|
{ |
|
|
|
stratum_msg_t *msg; |
|
|
|
smsg_t *msg; |
|
|
|
|
|
|
|
|
|
|
|
msg = ckzalloc(sizeof(stratum_msg_t)); |
|
|
|
msg = ckzalloc(sizeof(smsg_t)); |
|
|
|
msg->json_msg = val; |
|
|
|
msg->json_msg = val; |
|
|
|
msg->client_id = client_id; |
|
|
|
msg->client_id = client_id; |
|
|
|
|
|
|
|
ckmsgq_add(ssends, msg); |
|
|
|
mutex_lock(&stratum_send_lock); |
|
|
|
|
|
|
|
DL_APPEND(stratum_sends, msg); |
|
|
|
|
|
|
|
pthread_cond_signal(&stratum_send_cond); |
|
|
|
|
|
|
|
mutex_unlock(&stratum_send_lock); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void drop_client(int id) |
|
|
|
static void drop_client(int id) |
|
|
@ -1835,11 +1811,7 @@ static void parse_method(const int client_id, json_t *id_val, json_t *method_val |
|
|
|
if (!strncasecmp(method, "mining.auth", 11)) { |
|
|
|
if (!strncasecmp(method, "mining.auth", 11)) { |
|
|
|
json_params_t *jp = create_json_params(client_id, params_val, id_val); |
|
|
|
json_params_t *jp = create_json_params(client_id, params_val, id_val); |
|
|
|
|
|
|
|
|
|
|
|
mutex_lock(&sauth_lock); |
|
|
|
ckmsgq_add(sauthq, jp); |
|
|
|
DL_APPEND(sauths, jp); |
|
|
|
|
|
|
|
pthread_cond_signal(&sauth_cond); |
|
|
|
|
|
|
|
mutex_unlock(&sauth_lock); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -1859,18 +1831,14 @@ static void parse_method(const int client_id, json_t *id_val, json_t *method_val |
|
|
|
if (!strncasecmp(method, "mining.submit", 13)) { |
|
|
|
if (!strncasecmp(method, "mining.submit", 13)) { |
|
|
|
json_params_t *jp = create_json_params(client_id, params_val, id_val); |
|
|
|
json_params_t *jp = create_json_params(client_id, params_val, id_val); |
|
|
|
|
|
|
|
|
|
|
|
mutex_lock(&sshare_lock); |
|
|
|
ckmsgq_add(sshareq, jp); |
|
|
|
DL_APPEND(sshares, jp); |
|
|
|
|
|
|
|
pthread_cond_signal(&sshare_cond); |
|
|
|
|
|
|
|
mutex_unlock(&sshare_lock); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Unhandled message here */ |
|
|
|
/* Unhandled message here */ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void parse_instance_msg(stratum_msg_t *msg) |
|
|
|
static void parse_instance_msg(smsg_t *msg) |
|
|
|
{ |
|
|
|
{ |
|
|
|
json_t *val = msg->json_msg, *id_val, *method, *params; |
|
|
|
json_t *val = msg->json_msg, *id_val, *method, *params; |
|
|
|
int client_id = msg->client_id; |
|
|
|
int client_id = msg->client_id; |
|
|
@ -1898,98 +1866,52 @@ out: |
|
|
|
free(msg); |
|
|
|
free(msg); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void *stratum_receiver(void *arg) |
|
|
|
static void srecv_process(ckpool_t *ckp, smsg_t *msg) |
|
|
|
{ |
|
|
|
{ |
|
|
|
ckpool_t *ckp = (ckpool_t *)arg; |
|
|
|
stratum_instance_t *instance; |
|
|
|
stratum_msg_t *msg; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pthread_detach(pthread_self()); |
|
|
|
|
|
|
|
rename_proc("sreceiver"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while (42) { |
|
|
|
|
|
|
|
stratum_instance_t *instance; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Pop the head off the list if it exists or wait for a conditional
|
|
|
|
|
|
|
|
* signal telling us there is work */ |
|
|
|
|
|
|
|
mutex_lock(&stratum_recv_lock); |
|
|
|
|
|
|
|
if (!stratum_recvs) |
|
|
|
|
|
|
|
pthread_cond_wait(&stratum_recv_cond, &stratum_recv_lock); |
|
|
|
|
|
|
|
msg = stratum_recvs; |
|
|
|
|
|
|
|
if (likely(msg)) |
|
|
|
|
|
|
|
DL_DELETE(stratum_recvs, msg); |
|
|
|
|
|
|
|
mutex_unlock(&stratum_recv_lock); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (unlikely(!msg)) |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
msg->client_id = json_integer_value(json_object_get(msg->json_msg, "client_id")); |
|
|
|
msg->client_id = json_integer_value(json_object_get(msg->json_msg, "client_id")); |
|
|
|
json_object_del(msg->json_msg, "client_id"); |
|
|
|
json_object_del(msg->json_msg, "client_id"); |
|
|
|
|
|
|
|
|
|
|
|
/* Parse the message here */ |
|
|
|
|
|
|
|
ck_ilock(&instance_lock); |
|
|
|
|
|
|
|
instance = __instance_by_id(msg->client_id); |
|
|
|
|
|
|
|
if (!instance) { |
|
|
|
|
|
|
|
/* client_id instance doesn't exist yet, create one */ |
|
|
|
|
|
|
|
ck_ulock(&instance_lock); |
|
|
|
|
|
|
|
instance = __stratum_add_instance(ckp, msg->client_id); |
|
|
|
|
|
|
|
ck_dwilock(&instance_lock); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
ck_uilock(&instance_lock); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
parse_instance_msg(msg); |
|
|
|
/* Parse the message here */ |
|
|
|
|
|
|
|
ck_ilock(&instance_lock); |
|
|
|
|
|
|
|
instance = __instance_by_id(msg->client_id); |
|
|
|
|
|
|
|
if (!instance) { |
|
|
|
|
|
|
|
/* client_id instance doesn't exist yet, create one */ |
|
|
|
|
|
|
|
ck_ulock(&instance_lock); |
|
|
|
|
|
|
|
instance = __stratum_add_instance(ckp, msg->client_id); |
|
|
|
|
|
|
|
ck_dwilock(&instance_lock); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
ck_uilock(&instance_lock); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
parse_instance_msg(msg); |
|
|
|
|
|
|
|
|
|
|
|
return NULL; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void discard_stratum_msg(stratum_msg_t **msg) |
|
|
|
static void discard_stratum_msg(smsg_t **msg) |
|
|
|
{ |
|
|
|
{ |
|
|
|
json_decref((*msg)->json_msg); |
|
|
|
json_decref((*msg)->json_msg); |
|
|
|
free(*msg); |
|
|
|
free(*msg); |
|
|
|
*msg = NULL; |
|
|
|
*msg = NULL; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void *stratum_sender(void *arg) |
|
|
|
static void ssend_process(ckpool_t *ckp, smsg_t *msg) |
|
|
|
{ |
|
|
|
{ |
|
|
|
ckpool_t *ckp = (ckpool_t *)arg; |
|
|
|
char *s; |
|
|
|
stratum_msg_t *msg = NULL; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pthread_detach(pthread_self()); |
|
|
|
|
|
|
|
rename_proc("ssender"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while (42) { |
|
|
|
|
|
|
|
char *s; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (msg) |
|
|
|
|
|
|
|
discard_stratum_msg(&msg); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mutex_lock(&stratum_send_lock); |
|
|
|
|
|
|
|
if (!stratum_sends) |
|
|
|
|
|
|
|
pthread_cond_wait(&stratum_send_cond, &stratum_send_lock); |
|
|
|
|
|
|
|
msg = stratum_sends; |
|
|
|
|
|
|
|
if (likely(msg)) |
|
|
|
|
|
|
|
DL_DELETE(stratum_sends, msg); |
|
|
|
|
|
|
|
mutex_unlock(&stratum_send_lock); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (unlikely(!msg)) |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (unlikely(!msg->json_msg)) { |
|
|
|
|
|
|
|
LOGERR("Sent null json msg to stratum_sender"); |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Add client_id to the json message and send it to the
|
|
|
|
|
|
|
|
* connector process to be delivered */ |
|
|
|
|
|
|
|
json_object_set_new_nocheck(msg->json_msg, "client_id", json_integer(msg->client_id)); |
|
|
|
|
|
|
|
s = json_dumps(msg->json_msg, 0); |
|
|
|
|
|
|
|
send_proc(ckp->connector, s); |
|
|
|
|
|
|
|
free(s); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
discard_stratum_msg(&msg); |
|
|
|
if (unlikely(!msg->json_msg)) { |
|
|
|
|
|
|
|
LOGERR("Sent null json msg to stratum_sender"); |
|
|
|
|
|
|
|
free(msg); |
|
|
|
|
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return NULL; |
|
|
|
/* Add client_id to the json message and send it to the
|
|
|
|
|
|
|
|
* connector process to be delivered */ |
|
|
|
|
|
|
|
json_object_set_new_nocheck(msg->json_msg, "client_id", json_integer(msg->client_id)); |
|
|
|
|
|
|
|
s = json_dumps(msg->json_msg, 0); |
|
|
|
|
|
|
|
send_proc(ckp->connector, s); |
|
|
|
|
|
|
|
free(s); |
|
|
|
|
|
|
|
discard_stratum_msg(&msg); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void discard_json_params(json_params_t **jp) |
|
|
|
static void discard_json_params(json_params_t **jp) |
|
|
@ -2000,144 +1922,82 @@ static void discard_json_params(json_params_t **jp) |
|
|
|
*jp = NULL; |
|
|
|
*jp = NULL; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void *share_processor(void *arg) |
|
|
|
static void sshare_process(ckpool_t __maybe_unused *ckp, json_params_t *jp) |
|
|
|
{ |
|
|
|
{ |
|
|
|
ckpool_t __maybe_unused *ckp = (ckpool_t *)arg; |
|
|
|
json_t *result_val, *json_msg, *err_val = NULL; |
|
|
|
json_params_t *jp = NULL; |
|
|
|
stratum_instance_t *client; |
|
|
|
|
|
|
|
int client_id; |
|
|
|
pthread_detach(pthread_self()); |
|
|
|
|
|
|
|
rename_proc("sprocessor"); |
|
|
|
|
|
|
|
while (42) { |
|
|
|
|
|
|
|
json_t *result_val, *json_msg, *err_val = NULL; |
|
|
|
|
|
|
|
stratum_instance_t *client; |
|
|
|
|
|
|
|
int client_id; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (jp) |
|
|
|
|
|
|
|
discard_json_params(&jp); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mutex_lock(&sshare_lock); |
|
|
|
|
|
|
|
if (!sshares) |
|
|
|
|
|
|
|
pthread_cond_wait(&sshare_cond, &sshare_lock); |
|
|
|
|
|
|
|
jp = sshares; |
|
|
|
|
|
|
|
if (likely(jp)) |
|
|
|
|
|
|
|
DL_DELETE(sshares, jp); |
|
|
|
|
|
|
|
mutex_unlock(&sshare_lock); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (unlikely(!jp)) |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
client_id = jp->client_id; |
|
|
|
client_id = jp->client_id; |
|
|
|
|
|
|
|
|
|
|
|
ck_rlock(&instance_lock); |
|
|
|
ck_rlock(&instance_lock); |
|
|
|
client = __instance_by_id(client_id); |
|
|
|
client = __instance_by_id(client_id); |
|
|
|
ck_runlock(&instance_lock); |
|
|
|
ck_runlock(&instance_lock); |
|
|
|
|
|
|
|
|
|
|
|
if (unlikely(!client)) { |
|
|
|
if (unlikely(!client)) { |
|
|
|
LOGINFO("Share processor failed to find client id %d in hashtable!", client_id); |
|
|
|
LOGINFO("Share processor failed to find client id %d in hashtable!", client_id); |
|
|
|
continue; |
|
|
|
goto out; |
|
|
|
} |
|
|
|
|
|
|
|
json_msg = json_object(); |
|
|
|
|
|
|
|
result_val = parse_submit(client, json_msg, jp->params, &err_val); |
|
|
|
|
|
|
|
json_object_set_new_nocheck(json_msg, "result", result_val); |
|
|
|
|
|
|
|
json_object_set_new_nocheck(json_msg, "error", err_val ? err_val : json_null()); |
|
|
|
|
|
|
|
json_object_set_nocheck(json_msg, "id", jp->id_val); |
|
|
|
|
|
|
|
stratum_add_send(json_msg, client_id); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
json_msg = json_object(); |
|
|
|
return NULL; |
|
|
|
result_val = parse_submit(client, json_msg, jp->params, &err_val); |
|
|
|
|
|
|
|
json_object_set_new_nocheck(json_msg, "result", result_val); |
|
|
|
|
|
|
|
json_object_set_new_nocheck(json_msg, "error", err_val ? err_val : json_null()); |
|
|
|
|
|
|
|
json_object_set_nocheck(json_msg, "id", jp->id_val); |
|
|
|
|
|
|
|
stratum_add_send(json_msg, client_id); |
|
|
|
|
|
|
|
out: |
|
|
|
|
|
|
|
discard_json_params(&jp); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void *authoriser(void *arg) |
|
|
|
static void sauth_process(ckpool_t *ckp, json_params_t *jp) |
|
|
|
{ |
|
|
|
{ |
|
|
|
ckpool_t *ckp = (ckpool_t *)arg; |
|
|
|
json_t *result_val, *json_msg, *err_val = NULL; |
|
|
|
json_params_t *jp = NULL; |
|
|
|
stratum_instance_t *client; |
|
|
|
|
|
|
|
int client_id; |
|
|
|
pthread_detach(pthread_self()); |
|
|
|
|
|
|
|
rename_proc("authoriser"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while (42) { |
|
|
|
|
|
|
|
json_t *result_val, *json_msg, *err_val = NULL; |
|
|
|
|
|
|
|
stratum_instance_t *client; |
|
|
|
|
|
|
|
int client_id; |
|
|
|
|
|
|
|
char buf[256]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (jp) |
|
|
|
|
|
|
|
discard_json_params(&jp); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mutex_lock(&sauth_lock); |
|
|
|
|
|
|
|
if (!sauths) |
|
|
|
|
|
|
|
pthread_cond_wait(&sauth_cond, &sauth_lock); |
|
|
|
|
|
|
|
jp = sauths; |
|
|
|
|
|
|
|
if (likely(jp)) |
|
|
|
|
|
|
|
DL_DELETE(sauths, jp); |
|
|
|
|
|
|
|
mutex_unlock(&sauth_lock); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (unlikely(!jp)) |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
client_id = jp->client_id; |
|
|
|
client_id = jp->client_id; |
|
|
|
|
|
|
|
|
|
|
|
ck_rlock(&instance_lock); |
|
|
|
ck_rlock(&instance_lock); |
|
|
|
client = __instance_by_id(client_id); |
|
|
|
client = __instance_by_id(client_id); |
|
|
|
ck_runlock(&instance_lock); |
|
|
|
ck_runlock(&instance_lock); |
|
|
|
|
|
|
|
|
|
|
|
if (unlikely(!client)) { |
|
|
|
if (unlikely(!client)) { |
|
|
|
LOGINFO("Authoriser failed to find client id %d in hashtable!", client_id); |
|
|
|
LOGINFO("Authoriser failed to find client id %d in hashtable!", client_id); |
|
|
|
continue; |
|
|
|
goto out; |
|
|
|
} |
|
|
|
|
|
|
|
result_val = parse_authorise(client, jp->params, &err_val); |
|
|
|
|
|
|
|
if (json_is_true(result_val)) { |
|
|
|
|
|
|
|
snprintf(buf, 255, "Authorised, welcome to %s %s!", ckp->name, |
|
|
|
|
|
|
|
client->user_instance->username); |
|
|
|
|
|
|
|
stratum_send_message(client, buf); |
|
|
|
|
|
|
|
} else |
|
|
|
|
|
|
|
stratum_send_message(client, "Failed authorisation :("); |
|
|
|
|
|
|
|
json_msg = json_object(); |
|
|
|
|
|
|
|
json_object_set_new_nocheck(json_msg, "result", result_val); |
|
|
|
|
|
|
|
json_object_set_new_nocheck(json_msg, "error", err_val ? err_val : json_null()); |
|
|
|
|
|
|
|
json_object_set_nocheck(json_msg, "id", jp->id_val); |
|
|
|
|
|
|
|
stratum_add_send(json_msg, client_id); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
result_val = parse_authorise(client, jp->params, &err_val); |
|
|
|
|
|
|
|
if (json_is_true(result_val)) { |
|
|
|
|
|
|
|
char *buf; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ASPRINTF(&buf, "Authorised, welcome to %s %s!", ckp->name, |
|
|
|
|
|
|
|
client->user_instance->username); |
|
|
|
|
|
|
|
stratum_send_message(client, buf); |
|
|
|
|
|
|
|
} else |
|
|
|
|
|
|
|
stratum_send_message(client, "Failed authorisation :("); |
|
|
|
|
|
|
|
json_msg = json_object(); |
|
|
|
|
|
|
|
json_object_set_new_nocheck(json_msg, "result", result_val); |
|
|
|
|
|
|
|
json_object_set_new_nocheck(json_msg, "error", err_val ? err_val : json_null()); |
|
|
|
|
|
|
|
json_object_set_nocheck(json_msg, "id", jp->id_val); |
|
|
|
|
|
|
|
stratum_add_send(json_msg, client_id); |
|
|
|
|
|
|
|
out: |
|
|
|
|
|
|
|
discard_json_params(&jp); |
|
|
|
|
|
|
|
|
|
|
|
return NULL; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void *ckdbqueue(void *arg) |
|
|
|
static void ckdbq_process(ckpool_t *ckp, ckdb_msg_t *data) |
|
|
|
{ |
|
|
|
{ |
|
|
|
ckpool_t *ckp = (ckpool_t *)arg; |
|
|
|
bool logged = false; |
|
|
|
|
|
|
|
char *buf = NULL; |
|
|
|
pthread_detach(pthread_self()); |
|
|
|
|
|
|
|
rename_proc("ckdbqueue"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while (42) { |
|
|
|
|
|
|
|
bool logged = false; |
|
|
|
|
|
|
|
char *buf = NULL; |
|
|
|
|
|
|
|
ckdb_msg_t *msg; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mutex_lock(&ckdbq_lock); |
|
|
|
|
|
|
|
if (!ckdb_msgs) |
|
|
|
|
|
|
|
pthread_cond_wait(&ckdbq_cond, &ckdbq_lock); |
|
|
|
|
|
|
|
msg = ckdb_msgs; |
|
|
|
|
|
|
|
if (likely(msg)) |
|
|
|
|
|
|
|
DL_DELETE(ckdb_msgs, msg); |
|
|
|
|
|
|
|
mutex_unlock(&ckdbq_lock); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (unlikely(!msg)) |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while (!buf) { |
|
|
|
while (!buf) { |
|
|
|
buf = json_ckdb_call(ckp, ckdb_ids[msg->idtype], msg->val, logged); |
|
|
|
buf = json_ckdb_call(ckp, ckdb_ids[data->idtype], data->val, logged); |
|
|
|
if (unlikely(!buf)) { |
|
|
|
if (unlikely(!buf)) { |
|
|
|
LOGWARNING("Failed to talk to ckdb, queueing messages"); |
|
|
|
LOGWARNING("Failed to talk to ckdb, queueing messages"); |
|
|
|
sleep(5); |
|
|
|
sleep(5); |
|
|
|
} |
|
|
|
|
|
|
|
logged = true; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
LOGINFO("Got %s ckdb response: %s", ckdb_ids[msg->idtype], buf); |
|
|
|
logged = true; |
|
|
|
free(buf); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
LOGINFO("Got %s ckdb response: %s", ckdb_ids[data->idtype], buf); |
|
|
|
return NULL; |
|
|
|
free(buf); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static const double nonces = 4294967296; |
|
|
|
static const double nonces = 4294967296; |
|
|
@ -2386,9 +2246,7 @@ static void *statsupdate(void *arg) |
|
|
|
|
|
|
|
|
|
|
|
int stratifier(proc_instance_t *pi) |
|
|
|
int stratifier(proc_instance_t *pi) |
|
|
|
{ |
|
|
|
{ |
|
|
|
pthread_t pth_blockupdate, pth_stratum_receiver, pth_stratum_sender; |
|
|
|
pthread_t pth_blockupdate, pth_statsupdate; |
|
|
|
pthread_t pth_statsupdate, pth_share_processer, pth_authoriser; |
|
|
|
|
|
|
|
pthread_t pth_ckdbqueue; |
|
|
|
|
|
|
|
ckpool_t *ckp = pi->ckp; |
|
|
|
ckpool_t *ckp = pi->ckp; |
|
|
|
char *buf; |
|
|
|
char *buf; |
|
|
|
int ret; |
|
|
|
int ret; |
|
|
@ -2414,25 +2272,11 @@ int stratifier(proc_instance_t *pi) |
|
|
|
|
|
|
|
|
|
|
|
cklock_init(&instance_lock); |
|
|
|
cklock_init(&instance_lock); |
|
|
|
|
|
|
|
|
|
|
|
mutex_init(&stratum_send_lock); |
|
|
|
ssends = create_ckmsgq(ckp, "ssender", &ssend_process); |
|
|
|
cond_init(&stratum_send_cond); |
|
|
|
srecvs = create_ckmsgq(ckp, "sreceiver", &srecv_process); |
|
|
|
create_pthread(&pth_stratum_sender, stratum_sender, ckp); |
|
|
|
sshareq = create_ckmsgq(ckp, "sprocessor", &sshare_process); |
|
|
|
|
|
|
|
sauthq = create_ckmsgq(ckp, "authoriser", &sauth_process); |
|
|
|
mutex_init(&stratum_recv_lock); |
|
|
|
ckdbq = create_ckmsgq(ckp, "ckdbqueue", &ckdbq_process); |
|
|
|
cond_init(&stratum_recv_cond); |
|
|
|
|
|
|
|
create_pthread(&pth_stratum_receiver, stratum_receiver, ckp); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mutex_init(&sshare_lock); |
|
|
|
|
|
|
|
cond_init(&sshare_cond); |
|
|
|
|
|
|
|
create_pthread(&pth_share_processer, share_processor, ckp); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mutex_init(&sauth_lock); |
|
|
|
|
|
|
|
cond_init(&sauth_cond); |
|
|
|
|
|
|
|
create_pthread(&pth_authoriser, authoriser, ckp); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mutex_init(&ckdbq_lock); |
|
|
|
|
|
|
|
cond_init(&ckdbq_cond); |
|
|
|
|
|
|
|
create_pthread(&pth_ckdbqueue, ckdbqueue, ckp); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cklock_init(&workbase_lock); |
|
|
|
cklock_init(&workbase_lock); |
|
|
|
if (!ckp->proxy) |
|
|
|
if (!ckp->proxy) |
|
|
|