Skip to content

Commit d64f372

Browse files
committed
Merge branch '0.2.x'
2 parents dd9790b + 1d8c681 commit d64f372

File tree

5 files changed

+59
-15
lines changed

5 files changed

+59
-15
lines changed

src/datum_api.c

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,45 @@ void datum_api_cmd_kill_client(int tid, int cid) {
478478
}
479479
}
480480

481+
void datum_api_cmd_kill_client2(const char * const data, const size_t size, const char ** const redirect_p) {
482+
const char * const end = &data[size];
483+
const char *underscore_pos = memchr(data, '_', size);
484+
if (!underscore_pos) return;
485+
const size_t tid_size = underscore_pos - data;
486+
const int tid = datum_atoi_strict(data, tid_size);
487+
const char *p = &underscore_pos[1];
488+
underscore_pos = memchr(p, '_', end - p);
489+
if (!underscore_pos) underscore_pos = end;
490+
const int cid = datum_atoi_strict(p, underscore_pos - p);
491+
492+
// Valid input; unconditionally redirect back to clients dashboard
493+
*redirect_p = "/clients";
494+
495+
if (tid < 0 || tid >= global_stratum_app->max_threads || cid < 0 || cid >= global_stratum_app->max_clients_thread) {
496+
return;
497+
}
498+
499+
if (underscore_pos != end) {
500+
// Check it's the same client intended
501+
p = &underscore_pos[1];
502+
underscore_pos = memchr(p, '_', end - p);
503+
if (!underscore_pos) underscore_pos = end;
504+
const uint64_t connect_tsms = datum_atoi_strict_u64(p, underscore_pos - p);
505+
const T_DATUM_MINER_DATA * const m = global_stratum_app->datum_threads[tid].client_data[cid].app_client_data;
506+
if (connect_tsms != m->connect_tsms) {
507+
DLOG_WARN("API Request to disconnect FORMER stratum client %d/%d (ignored; connect tsms req=%lu vs cur=%lu)", tid, cid, (unsigned long)connect_tsms, (unsigned long)m->connect_tsms);
508+
return;
509+
}
510+
p = &underscore_pos[1];
511+
const uint64_t unique_id = datum_atoi_strict_u64(p, end - p);
512+
if (unique_id != m->unique_id) {
513+
DLOG_WARN("API Request to disconnect FORMER stratum client %d/%d (ignored; unique id req=%lu vs cur=%lu)", tid, cid, (unsigned long)unique_id, (unsigned long)m->unique_id);
514+
return;
515+
}
516+
}
517+
datum_api_cmd_kill_client(tid, cid);
518+
}
519+
481520
int datum_api_cmd(struct MHD_Connection *connection, char *post, int len) {
482521
struct MHD_Response *response;
483522
char output[1024];
@@ -561,14 +600,7 @@ int datum_api_cmd(struct MHD_Connection *connection, char *post, int len) {
561600
if (param) {
562601
const char * const data = json_string_value(param);
563602
const size_t size = json_string_length(param);
564-
const char * const underscore_pos = memchr(data, '_', size);
565-
if (underscore_pos) {
566-
const size_t tid_size = underscore_pos - data;
567-
const int tid = datum_atoi_strict(data, tid_size);
568-
const int cid = datum_atoi_strict(&underscore_pos[1], size - tid_size - 1);
569-
datum_api_cmd_kill_client(tid, cid);
570-
redirect = "/clients";
571-
}
603+
datum_api_cmd_kill_client2(data, size, &redirect);
572604
}
573605

574606
response = MHD_create_response_from_buffer(0, "", MHD_RESPMEM_PERSISTENT);
@@ -803,7 +835,7 @@ int datum_api_client_dashboard(struct MHD_Connection *connection) {
803835
sz += snprintf(&output[sz], max_sz-1-sz, "<TD COLSPAN=\"8\">Not Subscribed</TD>");
804836
}
805837

806-
sz += snprintf(&output[sz], max_sz-1-sz, "<TD><button name='kill_client' value='%d_%d' onclick=\"sendPostRequest('/cmd', {cmd:'kill_client',tid:%d,cid:%d}); return false;\">Kick</button></TD></TR>", j, ii, j, ii);
838+
sz += snprintf(&output[sz], max_sz-1-sz, "<TD><button name='kill_client' value='%d_%d_%lu_%lu' onclick=\"sendPostRequest('/cmd', {cmd:'kill_client',tid:%d,cid:%d,t:%lu,id:%lu}); return false;\">Kick</button></TD></TR>", j, ii, (unsigned long)m->connect_tsms, (unsigned long)m->unique_id, j, ii, (unsigned long)m->connect_tsms, (unsigned long)m->unique_id);
807839
}
808840
}
809841
}

src/datum_stratum.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,9 @@ void datum_stratum_v1_socket_thread_client_new(T_DATUM_CLIENT_DATA *c) {
352352
m->sdata = (T_DATUM_STRATUM_THREADPOOL_DATA *)c->datum_thread->app_thread_data;
353353
m->stats.last_swap_tsms = m->stats.last_share_tsms;
354354

355+
static uint64_t unique_id_ctr = 0;
356+
m->unique_id = unique_id_ctr++;
357+
355358
// set initial connection time
356359
// if this is the first client on the thread, we won't have a loop_tsms yet
357360
if (m->sdata->loop_tsms > 0) {

src/datum_stratum.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ typedef struct {
211211

212212
typedef struct {
213213
uint32_t sid, sid_inv;
214+
uint64_t unique_id;
214215
uint64_t connect_tsms;
215216
char useragent[128];
216217
char last_auth_username[192];

src/datum_utils.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -706,20 +706,27 @@ uint64_t datum_siphash_mod8(const void *src, uint64_t sz, const unsigned char ke
706706
}
707707

708708
// Uses a fixed-size buffer; positive only; digits only
709-
// Returns -1 on failure
710-
int datum_atoi_strict(const char * const s, const size_t size) {
711-
if (!size) return -1;
709+
// Returns UINT64_MAX on failure
710+
uint64_t datum_atoi_strict_u64(const char * const s, const size_t size) {
711+
if (!size) return UINT64_MAX;
712712
assert(s);
713-
int ret = 0;
713+
uint64_t ret = 0;
714714
for (size_t i = 0; i < size; ++i) {
715-
if (s[i] < '0' || s[i] > '9') return -1;
715+
if (s[i] < '0' || s[i] > '9') return UINT64_MAX;
716716
int digit = s[i] - '0';
717-
if (ret > (INT_MAX - digit) / 10) return -1;
717+
if (ret > (UINT64_MAX - digit) / 10) return UINT64_MAX;
718718
ret = (ret * 10) + digit;
719719
}
720720
return ret;
721721
}
722722

723+
// Uses a fixed-size buffer; positive only; digits only
724+
// Returns -1 on failure
725+
int datum_atoi_strict(const char * const s, const size_t size) {
726+
const uint64_t ret = datum_atoi_strict_u64(s, size);
727+
return (ret == UINT64_MAX || ret > INT_MAX) ? -1 : ret;
728+
}
729+
723730
bool datum_secure_strequals(const char *secret, const size_t secret_len, const char *guess) {
724731
const size_t guess_len = strlen(guess);
725732
size_t acc = secret_len ^ guess_len;

src/datum_utils.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ long double calc_network_difficulty(const char *bits_hex);
6969
unsigned char floorPoT(uint64_t x);
7070
uint64_t datum_siphash(const void *src, uint64_t sz, const unsigned char key[16]);
7171
uint64_t datum_siphash_mod8(const void *src, uint64_t sz, const unsigned char key[16]);
72+
uint64_t datum_atoi_strict_u64(const char *s, size_t size);
7273
int datum_atoi_strict(const char *s, size_t size);
7374
bool datum_secure_strequals(const char *secret, const size_t secret_len, const char *guess);
7475

0 commit comments

Comments
 (0)