Browse Source

Keep track of clients that submit a run of continuous rejects and send them a diff update if they do it for longer than 1 minute and then lazily drop them if it goes beyond 2 minutes

master
Con Kolivas 10 years ago
parent
commit
1b45079802
  1. 35
      src/stratifier.c

35
src/stratifier.c

@ -272,6 +272,7 @@ struct stratum_instance {
int ssdc; /* Shares since diff change */ int ssdc; /* Shares since diff change */
tv_t first_share; tv_t first_share;
tv_t last_share; tv_t last_share;
time_t first_invalid; /* Time of first invalid in run of non stale rejects */
time_t start_time; time_t start_time;
char address[INET6_ADDRSTRLEN]; char address[INET6_ADDRSTRLEN];
@ -279,6 +280,9 @@ struct stratum_instance {
bool authorised; bool authorised;
bool idle; bool idle;
bool notified_idle; bool notified_idle;
int reject; /* Indicator that this client is having a run of rejects
* or other problem and should be dropped lazily if
* this is set to 2 */
user_instance_t *user_instance; user_instance_t *user_instance;
worker_instance_t *worker_instance; worker_instance_t *worker_instance;
@ -2055,13 +2059,15 @@ static json_t *parse_submit(stratum_instance_t *client, json_t *json_msg,
char idstring[20]; char idstring[20];
uint32_t ntime32; uint32_t ntime32;
uchar hash[32]; uchar hash[32];
int64_t id; time_t now_t;
json_t *val; json_t *val;
int64_t id;
ts_t now; ts_t now;
FILE *fp; FILE *fp;
int len; int len;
ts_realtime(&now); ts_realtime(&now);
now_t = now.tv_sec;
sprintf(cdfield, "%lu,%lu", now.tv_sec, now.tv_nsec); sprintf(cdfield, "%lu,%lu", now.tv_sec, now.tv_nsec);
if (unlikely(!json_is_array(params_val))) { if (unlikely(!json_is_array(params_val))) {
@ -2235,6 +2241,26 @@ out_unlock:
} }
ckdbq_add(ckp, ID_SHARES, val); ckdbq_add(ckp, ID_SHARES, val);
out: out:
if ((!result && !submit) || !share) {
/* Is this the first in a run of invalids? */
if (client->first_invalid < client->last_share.tv_sec || !client->first_invalid)
client->first_invalid = now_t;
else if (client->first_invalid && client->first_invalid < now_t - 120) {
LOGNOTICE("Client %d rejecting for 120s, disconnecting", client->id);
stratum_send_message(client, "Disconnecting for continuous invalid shares");
client->reject = 2;
} else if (client->first_invalid && client->first_invalid < now_t - 60) {
if (!client->reject) {
LOGINFO("Client %d rejecting for 60s, sending diff", client->id);
stratum_send_diff(client);
client->reject = 1;
}
}
} else {
client->first_invalid = 0;
client->reject = 0;
}
if (!share) { if (!share) {
JSON_CPACK(val, "{sI,ss,ss,sI,ss,ss,so,si,ss,ss,ss,ss}", JSON_CPACK(val, "{sI,ss,ss,sI,ss,ss,so,si,ss,ss,ss,ss}",
"clientid", client->id, "clientid", client->id,
@ -2401,6 +2427,13 @@ static void parse_method(const int64_t client_id, json_t *id_val, json_t *method
return; return;
} }
if (unlikely(client->reject == 2)) {
LOGINFO("Dropping client %d tagged for lazy invalidation", client_id);
snprintf(buf, 255, "dropclient=%ld", client->id);
send_proc(client->ckp->connector, buf);
return;
}
/* Random broken clients send something not an integer as the id so we copy /* Random broken clients send something not an integer as the id so we copy
* the json item for id_val as is for the response. */ * the json item for id_val as is for the response. */
method = json_string_value(method_val); method = json_string_value(method_val);

Loading…
Cancel
Save