Respond with error when open invitation buckets are empty
Expand the error type returns by invite() to include a new error for when there are no available bridges for open invitation users. This fixes a bug that previously caused a panic when we have no bridges to distribute. See https://gitlab.torproject.org/tpo/anti-censorship/lox/-/issues/43
This commit is contained in:
parent
364b55dc4c
commit
39449cabe8
|
@ -6,7 +6,7 @@ use lox_library::{
|
||||||
blockage_migration, check_blockage, issue_invite, level_up, migration, open_invite,
|
blockage_migration, check_blockage, issue_invite, level_up, migration, open_invite,
|
||||||
redeem_invite, trust_promotion,
|
redeem_invite, trust_promotion,
|
||||||
},
|
},
|
||||||
BridgeAuth, BridgeDb, ExceededMaxBridgesError, IssuerPubKey,
|
BridgeAuth, BridgeDb, OpenInvitationError, IssuerPubKey,
|
||||||
};
|
};
|
||||||
use rdsys_backend::proto::{Resource, ResourceState};
|
use rdsys_backend::proto::{Resource, ResourceState};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -361,7 +361,7 @@ impl LoxServerContext {
|
||||||
|
|
||||||
// Generates a Lox invitation if fewer than MAX_BRIDGES_PER_DAY have been
|
// Generates a Lox invitation if fewer than MAX_BRIDGES_PER_DAY have been
|
||||||
// requested on a given day
|
// requested on a given day
|
||||||
fn gen_invite(&self) -> Result<lox_utils::Invite, ExceededMaxBridgesError> {
|
fn gen_invite(&self) -> Result<lox_utils::Invite, OpenInvitationError> {
|
||||||
let mut obj = self.db.lock().unwrap();
|
let mut obj = self.db.lock().unwrap();
|
||||||
match obj.invite() {
|
match obj.invite() {
|
||||||
Ok(invite) => {
|
Ok(invite) => {
|
||||||
|
@ -450,7 +450,7 @@ impl LoxServerContext {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
println!("Error parsing Invite to JSON");
|
println!("Error generating open invitation");
|
||||||
prepare_error_header(e.to_string())
|
prepare_error_header(e.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,9 +86,12 @@ pub enum NoAvailableIDError {
|
||||||
/// This error is thrown after the MAX_DAILY_BRIDGES threshold for bridges
|
/// This error is thrown after the MAX_DAILY_BRIDGES threshold for bridges
|
||||||
/// distributed in a day has been reached
|
/// distributed in a day has been reached
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub enum ExceededMaxBridgesError {
|
pub enum OpenInvitationError {
|
||||||
#[error("The maximum number of bridges has already been distributed today, please try again tomorrow!")]
|
#[error("The maximum number of bridges has already been distributed today, please try again tomorrow!")]
|
||||||
ExceededMaxBridges,
|
ExceededMaxBridges,
|
||||||
|
|
||||||
|
#[error("There are no bridges available for open invitations.")]
|
||||||
|
NoBridgesAvailable,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Private Key of the Issuer
|
/// Private Key of the Issuer
|
||||||
|
@ -215,7 +218,7 @@ impl BridgeDb {
|
||||||
/// Produce an open invitation such that the next k users, where k is <
|
/// Produce an open invitation such that the next k users, where k is <
|
||||||
/// OPENINV_K, will receive the same open invitation bucket
|
/// OPENINV_K, will receive the same open invitation bucket
|
||||||
/// chosen randomly from the set of open-invitation buckets.
|
/// chosen randomly from the set of open-invitation buckets.
|
||||||
pub fn invite(&mut self) -> Result<[u8; OPENINV_LENGTH], ExceededMaxBridgesError> {
|
pub fn invite(&mut self) -> Result<[u8; OPENINV_LENGTH], OpenInvitationError> {
|
||||||
let mut res: [u8; OPENINV_LENGTH] = [0; OPENINV_LENGTH];
|
let mut res: [u8; OPENINV_LENGTH] = [0; OPENINV_LENGTH];
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
// Choose a random invitation id (a Scalar) and serialize it
|
// Choose a random invitation id (a Scalar) and serialize it
|
||||||
|
@ -226,6 +229,9 @@ impl BridgeDb {
|
||||||
self.today = Utc::now();
|
self.today = Utc::now();
|
||||||
self.daily_bridges_distributed = 0;
|
self.daily_bridges_distributed = 0;
|
||||||
}
|
}
|
||||||
|
if self.openinv_buckets.is_empty() {
|
||||||
|
return Err(OpenInvitationError::NoBridgesAvailable)
|
||||||
|
}
|
||||||
if self.daily_bridges_distributed < MAX_DAILY_BRIDGES {
|
if self.daily_bridges_distributed < MAX_DAILY_BRIDGES {
|
||||||
if self.current_k < OPENINV_K && !self.distributed_buckets.is_empty() {
|
if self.current_k < OPENINV_K && !self.distributed_buckets.is_empty() {
|
||||||
bucket_num = *self.distributed_buckets.last().unwrap();
|
bucket_num = *self.distributed_buckets.last().unwrap();
|
||||||
|
@ -246,7 +252,7 @@ impl BridgeDb {
|
||||||
res[(32 + 4)..].copy_from_slice(&sig.to_bytes());
|
res[(32 + 4)..].copy_from_slice(&sig.to_bytes());
|
||||||
Ok(res)
|
Ok(res)
|
||||||
} else {
|
} else {
|
||||||
Err(ExceededMaxBridgesError::ExceededMaxBridges)
|
Err(OpenInvitationError::ExceededMaxBridges)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue