diff --git a/src/stratifier.c b/src/stratifier.c index 1aaeec78..57e592e1 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -185,6 +185,8 @@ struct user_instance { bool authorised; /* Has this username ever been authorised? */ 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 */ @@ -2165,6 +2167,7 @@ static user_instance_t *generate_user(ckpool_t *ckp, stratum_instance_t *client, if (!user) { /* New user instance. Secondary user id will be NULL */ user = ckzalloc(sizeof(user_instance_t)); + user->auth_backoff = 3; /* Set initial backoff to 3 seconds */ strcpy(user->username, username); new_instance = true; 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); client->start_time = now.tv_sec; strcpy(client->address, address); - 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)) ret = true; else { @@ -2413,9 +2425,15 @@ static json_t *parse_authorise(stratum_instance_t *client, json_t *params_val, j inc_worker(ckp, user_instance); LOGNOTICE("Authorised client %ld worker %s as user %s", client->id, buf, user_instance->username); + user_instance->auth_backoff = 3; /* Reset auth backoff time */ } else { LOGNOTICE("Client %ld worker %s failed to authorise as user %s", client->id, buf, 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: return json_boolean(ret);