|
|
@ -185,6 +185,8 @@ struct user_instance { |
|
|
|
|
|
|
|
|
|
|
|
bool authorised; /* Has this username ever been authorised? */ |
|
|
|
bool authorised; /* Has this username ever been authorised? */ |
|
|
|
time_t auth_time; |
|
|
|
time_t auth_time; |
|
|
|
|
|
|
|
time_t failed_authtime; /* Last time this username failed to authorise */ |
|
|
|
|
|
|
|
int auth_backoff; /* How long to reject any auth attempts since last failure */ |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
/* Combined data from workers with the same workername */ |
|
|
|
/* Combined data from workers with the same workername */ |
|
|
@ -2165,6 +2167,7 @@ static user_instance_t *generate_user(ckpool_t *ckp, stratum_instance_t *client, |
|
|
|
if (!user) { |
|
|
|
if (!user) { |
|
|
|
/* New user instance. Secondary user id will be NULL */ |
|
|
|
/* New user instance. Secondary user id will be NULL */ |
|
|
|
user = ckzalloc(sizeof(user_instance_t)); |
|
|
|
user = ckzalloc(sizeof(user_instance_t)); |
|
|
|
|
|
|
|
user->auth_backoff = 3; /* Set initial backoff to 3 seconds */ |
|
|
|
strcpy(user->username, username); |
|
|
|
strcpy(user->username, username); |
|
|
|
new_instance = true; |
|
|
|
new_instance = true; |
|
|
|
user->id = sdata->user_instance_id++; |
|
|
|
user->id = sdata->user_instance_id++; |
|
|
@ -2385,8 +2388,17 @@ static json_t *parse_authorise(stratum_instance_t *client, json_t *params_val, j |
|
|
|
ts_realtime(&now); |
|
|
|
ts_realtime(&now); |
|
|
|
client->start_time = now.tv_sec; |
|
|
|
client->start_time = now.tv_sec; |
|
|
|
strcpy(client->address, address); |
|
|
|
strcpy(client->address, address); |
|
|
|
|
|
|
|
|
|
|
|
client->workername = strdup(buf); |
|
|
|
client->workername = strdup(buf); |
|
|
|
|
|
|
|
if (user_instance->failed_authtime) { |
|
|
|
|
|
|
|
time_t now_t = time(NULL); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (now_t < user_instance->failed_authtime + user_instance->auth_backoff) { |
|
|
|
|
|
|
|
LOGNOTICE("Client %ld worker %s rate limited due to failed auth attempts", |
|
|
|
|
|
|
|
client->id, buf); |
|
|
|
|
|
|
|
client->dropped = true; |
|
|
|
|
|
|
|
goto out; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
if (CKP_STANDALONE(ckp)) |
|
|
|
if (CKP_STANDALONE(ckp)) |
|
|
|
ret = true; |
|
|
|
ret = true; |
|
|
|
else { |
|
|
|
else { |
|
|
@ -2413,9 +2425,15 @@ static json_t *parse_authorise(stratum_instance_t *client, json_t *params_val, j |
|
|
|
inc_worker(ckp, user_instance); |
|
|
|
inc_worker(ckp, user_instance); |
|
|
|
LOGNOTICE("Authorised client %ld worker %s as user %s", client->id, buf, |
|
|
|
LOGNOTICE("Authorised client %ld worker %s as user %s", client->id, buf, |
|
|
|
user_instance->username); |
|
|
|
user_instance->username); |
|
|
|
|
|
|
|
user_instance->auth_backoff = 3; /* Reset auth backoff time */ |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
LOGNOTICE("Client %ld worker %s failed to authorise as user %s", client->id, buf, |
|
|
|
LOGNOTICE("Client %ld worker %s failed to authorise as user %s", client->id, buf, |
|
|
|
user_instance->username); |
|
|
|
user_instance->username); |
|
|
|
|
|
|
|
user_instance->failed_authtime = time(NULL); |
|
|
|
|
|
|
|
user_instance->auth_backoff <<= 1; |
|
|
|
|
|
|
|
/* Cap backoff time to 10 mins */ |
|
|
|
|
|
|
|
if (user_instance->auth_backoff > 600) |
|
|
|
|
|
|
|
user_instance->auth_backoff = 600; |
|
|
|
} |
|
|
|
} |
|
|
|
out: |
|
|
|
out: |
|
|
|
return json_boolean(ret); |
|
|
|
return json_boolean(ret); |
|
|
|