|  |  |  | @ -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); | 
			
		
	
	
		
			
				
					|  |  |  | 
 |