@@ -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+
481520int 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 }
0 commit comments