mirror of
https://github.com/telemt/telemt.git
synced 2026-10-10 11:25:57 +03:00
Rustfmt
This commit is contained in:
@@ -290,11 +290,8 @@ impl Drop for UserIpPermit {
|
||||
let Some(owner) = self.owner.take() else {
|
||||
return;
|
||||
};
|
||||
self.tracker.enqueue_cleanup_for_incarnation(
|
||||
owner.user,
|
||||
owner.incarnation,
|
||||
owner.ip,
|
||||
);
|
||||
self.tracker
|
||||
.enqueue_cleanup_for_incarnation(owner.user, owner.incarnation, owner.ip);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -338,9 +335,7 @@ impl UserConnectionReservation {
|
||||
stats_observation: Option<UserConnectionObservation>,
|
||||
tracks_ip: bool,
|
||||
) -> Self {
|
||||
let ip_permit = tracks_ip.then(|| {
|
||||
UserIpPermit::new(ip_tracker, user, incarnation, ip)
|
||||
});
|
||||
let ip_permit = tracks_ip.then(|| UserIpPermit::new(ip_tracker, user, incarnation, ip));
|
||||
Self {
|
||||
stats,
|
||||
quota_handle,
|
||||
@@ -388,12 +383,7 @@ pub(crate) async fn acquire_user_connection_reservation(
|
||||
ip_tracker: Arc<UserIpTracker>,
|
||||
) -> Result<UserConnectionReservation> {
|
||||
acquire_user_connection_reservation_for_incarnation(
|
||||
user,
|
||||
0,
|
||||
config,
|
||||
stats,
|
||||
peer_addr,
|
||||
ip_tracker,
|
||||
user, 0, config, stats, peer_addr, ip_tracker,
|
||||
)
|
||||
.await
|
||||
}
|
||||
@@ -435,10 +425,7 @@ async fn acquire_user_connection_reservation_for_incarnation(
|
||||
.or((config.access.user_max_tcp_conns_global_each > 0)
|
||||
.then_some(config.access.user_max_tcp_conns_global_each))
|
||||
.map(|value| value as u64);
|
||||
let Some(connection_permit) = stats
|
||||
.connection_authority()
|
||||
.try_acquire(user, limit)
|
||||
else {
|
||||
let Some(connection_permit) = stats.connection_authority().try_acquire(user, limit) else {
|
||||
return Err(ProxyError::ConnectionLimitExceeded {
|
||||
user: user.to_string(),
|
||||
});
|
||||
|
||||
@@ -155,10 +155,7 @@ impl RunningClientHandler {
|
||||
.or((config.access.user_max_tcp_conns_global_each > 0)
|
||||
.then_some(config.access.user_max_tcp_conns_global_each))
|
||||
.map(|v| v as u64);
|
||||
let Some(_connection_permit) = stats
|
||||
.connection_authority()
|
||||
.try_acquire(user, limit)
|
||||
else {
|
||||
let Some(_connection_permit) = stats.connection_authority().try_acquire(user, limit) else {
|
||||
return Err(ProxyError::ConnectionLimitExceeded {
|
||||
user: user.to_string(),
|
||||
});
|
||||
|
||||
@@ -7,11 +7,11 @@ use tokio::sync::watch;
|
||||
|
||||
// Process controller and system-memory sampling remain outside data-plane accounting.
|
||||
mod controller;
|
||||
#[cfg(test)]
|
||||
use controller::connection_fill_pct;
|
||||
pub(crate) use controller::{
|
||||
resolve_direct_buffer_hard_limit, run_direct_buffer_budget_controller,
|
||||
};
|
||||
#[cfg(test)]
|
||||
use controller::connection_fill_pct;
|
||||
|
||||
/// Accounting granularity for process-wide Direct copy-buffer reservations.
|
||||
pub(crate) const DIRECT_BUFFER_UNIT_BYTES: usize = 4 * 1024;
|
||||
@@ -135,10 +135,7 @@ impl DirectBufferBudget {
|
||||
.fetch_max(generation, Ordering::AcqRel);
|
||||
}
|
||||
|
||||
fn begin_controller_update(
|
||||
&self,
|
||||
generation: u64,
|
||||
) -> Option<ParkingMutexGuard<'_, ()>> {
|
||||
fn begin_controller_update(&self, generation: u64) -> Option<ParkingMutexGuard<'_, ()>> {
|
||||
let controller_update = self.controller_update.lock();
|
||||
(self.active_controller_generation.load(Ordering::Acquire) == generation)
|
||||
.then_some(controller_update)
|
||||
|
||||
@@ -145,11 +145,8 @@ pub(super) fn connection_fill_pct(
|
||||
return None;
|
||||
}
|
||||
let max_connections = max_connections as usize;
|
||||
let active = max_connections.saturating_sub(
|
||||
connection_slots
|
||||
.available_permits()
|
||||
.min(max_connections),
|
||||
);
|
||||
let active =
|
||||
max_connections.saturating_sub(connection_slots.available_permits().min(max_connections));
|
||||
Some((active.saturating_mul(100) / max_connections).min(100) as u8)
|
||||
}
|
||||
|
||||
|
||||
@@ -74,8 +74,8 @@ pub(crate) use self::auth_probe::{
|
||||
auth_probe_saturation_is_throttled_at_for_testing_in_shared,
|
||||
auth_probe_saturation_is_throttled_for_testing_in_shared,
|
||||
auth_probe_saturation_state_for_testing_in_shared,
|
||||
auth_probe_saturation_state_lock_for_testing_in_shared, auth_probe_state_for_testing_in_shared,
|
||||
auth_probe_slots_for_testing_in_shared, clear_auth_probe_state_for_testing_in_shared,
|
||||
auth_probe_saturation_state_lock_for_testing_in_shared, auth_probe_slots_for_testing_in_shared,
|
||||
auth_probe_state_for_testing_in_shared, clear_auth_probe_state_for_testing_in_shared,
|
||||
clear_unknown_sni_warn_state_for_testing_in_shared, clear_warned_secrets_for_testing_in_shared,
|
||||
insert_auth_probe_state_for_testing_in_shared,
|
||||
should_emit_unknown_sni_warn_for_testing_in_shared, warned_secrets_for_testing_in_shared,
|
||||
|
||||
@@ -403,7 +403,10 @@ mod bounded_registry_tests {
|
||||
for index in (worker..ATTEMPTS).step_by(16) {
|
||||
let octets = (index as u32).to_be_bytes();
|
||||
let peer_ip = IpAddr::V4(std::net::Ipv4Addr::new(
|
||||
octets[1], octets[2], octets[3], worker as u8,
|
||||
octets[1],
|
||||
octets[2],
|
||||
octets[3],
|
||||
worker as u8,
|
||||
));
|
||||
sticky_hint_record_success_in(
|
||||
shared.as_ref(),
|
||||
@@ -416,7 +419,10 @@ mod bounded_registry_tests {
|
||||
}
|
||||
});
|
||||
|
||||
assert_eq!(shared.handshake.sticky_user_by_ip.len(), STICKY_HINT_MAX_ENTRIES);
|
||||
assert_eq!(
|
||||
shared.handshake.sticky_user_by_ip.len(),
|
||||
STICKY_HINT_MAX_ENTRIES
|
||||
);
|
||||
assert_eq!(
|
||||
shared.handshake.sticky_user_by_ip_prefix.len(),
|
||||
STICKY_HINT_MAX_ENTRIES
|
||||
|
||||
@@ -397,8 +397,7 @@ fn auth_probe_record_failure_with_state_and_budget_in(
|
||||
};
|
||||
if state
|
||||
.remove_if(&evict_key, |_, current| {
|
||||
current.fail_streak == evict_fail_streak
|
||||
&& current.last_seen == evict_last_seen
|
||||
current.fail_streak == evict_fail_streak && current.last_seen == evict_last_seen
|
||||
})
|
||||
.is_some()
|
||||
&& let Some(slots) = slots
|
||||
|
||||
@@ -160,7 +160,10 @@ fn parallel_distinct_failures_respect_exact_auth_probe_capacity() {
|
||||
for index in (worker..ATTEMPTS).step_by(16) {
|
||||
let octets = (index as u32).to_be_bytes();
|
||||
let peer_ip = IpAddr::V4(std::net::Ipv4Addr::new(
|
||||
octets[1], octets[2], octets[3], worker as u8,
|
||||
octets[1],
|
||||
octets[2],
|
||||
octets[3],
|
||||
worker as u8,
|
||||
));
|
||||
auth_probe_record_failure_in(shared.as_ref(), peer_ip, Instant::now());
|
||||
}
|
||||
@@ -168,7 +171,10 @@ fn parallel_distinct_failures_respect_exact_auth_probe_capacity() {
|
||||
}
|
||||
});
|
||||
|
||||
assert_eq!(shared.handshake.auth_probe.len(), AUTH_PROBE_TRACK_MAX_ENTRIES);
|
||||
assert_eq!(
|
||||
shared.handshake.auth_probe.len(),
|
||||
AUTH_PROBE_TRACK_MAX_ENTRIES
|
||||
);
|
||||
assert_eq!(
|
||||
auth_probe_slots_for_testing_in_shared(shared.as_ref()),
|
||||
AUTH_PROBE_TRACK_MAX_ENTRIES
|
||||
|
||||
@@ -151,10 +151,10 @@ where
|
||||
if let Some(snapshot) = config.runtime_user_auth() {
|
||||
let sticky_ip_hint = sticky_hint_get_by_ip(shared, peer.ip());
|
||||
let sticky_prefix_hint = sticky_hint_get_by_ip_prefix(shared, peer.ip());
|
||||
let sticky_ip_candidates = sticky_ip_hint
|
||||
.and_then(|hint_key| snapshot.candidate_ids_by_hint_key(hint_key));
|
||||
let sticky_prefix_candidates = sticky_prefix_hint
|
||||
.and_then(|hint_key| snapshot.candidate_ids_by_hint_key(hint_key));
|
||||
let sticky_ip_candidates =
|
||||
sticky_ip_hint.and_then(|hint_key| snapshot.candidate_ids_by_hint_key(hint_key));
|
||||
let sticky_prefix_candidates =
|
||||
sticky_prefix_hint.and_then(|hint_key| snapshot.candidate_ids_by_hint_key(hint_key));
|
||||
let preferred_user_id = preferred_user.and_then(|user| snapshot.user_id_by_name(user));
|
||||
let exact_user_id = exact_user.and_then(|user| snapshot.user_id_by_name(user));
|
||||
let has_hint = sticky_ip_candidates.is_some_and(|ids| !ids.is_empty())
|
||||
|
||||
@@ -400,12 +400,7 @@ where
|
||||
.runtime_user_auth()
|
||||
.and_then(|snapshot| snapshot.entry_by_id(user_id))
|
||||
{
|
||||
sticky_hint_record_success_in(
|
||||
shared,
|
||||
peer.ip(),
|
||||
entry.hint_key,
|
||||
client_sni.as_deref(),
|
||||
);
|
||||
sticky_hint_record_success_in(shared, peer.ip(), entry.hint_key, client_sni.as_deref());
|
||||
record_recent_user_success_in(shared, entry.hint_key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,17 +40,17 @@ pub(super) async fn validate_tls_client(
|
||||
};
|
||||
|
||||
let sticky_ip_hint = sticky_hint_get_by_ip(shared, peer.ip());
|
||||
let sticky_ip_candidates = sticky_ip_hint
|
||||
.and_then(|hint_key| snapshot.candidate_ids_by_hint_key(hint_key));
|
||||
let sticky_ip_candidates =
|
||||
sticky_ip_hint.and_then(|hint_key| snapshot.candidate_ids_by_hint_key(hint_key));
|
||||
let preferred_user_id = preferred_user_hint.and_then(|user| snapshot.user_id_by_name(user));
|
||||
let sticky_sni_hint = client_sni
|
||||
.as_deref()
|
||||
.and_then(|sni| sticky_hint_get_by_sni(shared, sni));
|
||||
let sticky_sni_candidates = sticky_sni_hint
|
||||
.and_then(|hint_key| snapshot.candidate_ids_by_hint_key(hint_key));
|
||||
let sticky_sni_candidates =
|
||||
sticky_sni_hint.and_then(|hint_key| snapshot.candidate_ids_by_hint_key(hint_key));
|
||||
let sticky_prefix_hint = sticky_hint_get_by_ip_prefix(shared, peer.ip());
|
||||
let sticky_prefix_candidates = sticky_prefix_hint
|
||||
.and_then(|hint_key| snapshot.candidate_ids_by_hint_key(hint_key));
|
||||
let sticky_prefix_candidates =
|
||||
sticky_prefix_hint.and_then(|hint_key| snapshot.candidate_ids_by_hint_key(hint_key));
|
||||
let sni_candidates = client_sni
|
||||
.as_deref()
|
||||
.and_then(|sni| snapshot.sni_candidates(sni));
|
||||
|
||||
@@ -191,7 +191,12 @@ where
|
||||
if let (Some(limit), Some(quota_handle)) = (quota_limit, quota_handle) {
|
||||
let soft_limit = quota_soft_cap(limit, quota_soft_overshoot_bytes);
|
||||
match reserve_user_quota_with_yield(
|
||||
quota_handle, data_len, soft_limit, stats, cancel, None,
|
||||
quota_handle,
|
||||
data_len,
|
||||
soft_limit,
|
||||
stats,
|
||||
cancel,
|
||||
None,
|
||||
)
|
||||
.await
|
||||
{
|
||||
|
||||
@@ -44,9 +44,9 @@ mod tests {
|
||||
c2me_sender: AbortOnDropHandle::new(tokio::spawn(pending_child(DropSignal(
|
||||
Arc::clone(&dropped),
|
||||
)))),
|
||||
me_writer: AbortOnDropHandle::new(tokio::spawn(pending_child(DropSignal(
|
||||
Arc::clone(&dropped),
|
||||
)))),
|
||||
me_writer: AbortOnDropHandle::new(tokio::spawn(pending_child(DropSignal(Arc::clone(
|
||||
&dropped,
|
||||
))))),
|
||||
flow_cancel: flow_cancel.clone(),
|
||||
stop_tx: Some(stop_tx),
|
||||
};
|
||||
|
||||
@@ -414,13 +414,7 @@ impl<S: AsyncWrite + Unpin> AsyncWrite for StatsIo<S> {
|
||||
if quota_reservation.is_none() {
|
||||
this.stats.increment_quota_contention_timeout_total();
|
||||
Self::arm_wait(&mut this.quota_wait, false, false);
|
||||
if Self::poll_wait(
|
||||
&mut this.quota_wait,
|
||||
cx,
|
||||
None,
|
||||
RateDirection::Up,
|
||||
)
|
||||
.is_ready()
|
||||
if Self::poll_wait(&mut this.quota_wait, cx, None, RateDirection::Up).is_ready()
|
||||
{
|
||||
cx.waker().wake_by_ref();
|
||||
}
|
||||
|
||||
@@ -219,8 +219,12 @@ impl ProxySharedState {
|
||||
users: &HashMap<String, String>,
|
||||
user_enabled: &HashMap<String, bool>,
|
||||
) -> Option<Vec<(String, usize)>> {
|
||||
self.user_admission
|
||||
.activate_config_source(source_generation, expected_epoch, users, user_enabled)
|
||||
self.user_admission.activate_config_source(
|
||||
source_generation,
|
||||
expected_epoch,
|
||||
users,
|
||||
user_enabled,
|
||||
)
|
||||
}
|
||||
|
||||
/// Applies an update only from the active runtime generation.
|
||||
@@ -276,8 +280,7 @@ impl ProxySharedState {
|
||||
user: &str,
|
||||
credential_id: UserCredentialId,
|
||||
) -> Option<UserAdmissionPublication<'_>> {
|
||||
self.user_admission
|
||||
.claim_authenticated(user, credential_id)
|
||||
self.user_admission.claim_authenticated(user, credential_id)
|
||||
}
|
||||
|
||||
pub(crate) fn register_user_session(
|
||||
|
||||
@@ -310,10 +310,7 @@ async fn cancelled_ip_admission_releases_process_connection_permit() {
|
||||
let user = "cancelled-admission-user";
|
||||
let peer_addr: SocketAddr = "198.51.100.210:50000".parse().unwrap();
|
||||
let mut config = ProxyConfig::default();
|
||||
config
|
||||
.access
|
||||
.user_max_tcp_conns
|
||||
.insert(user.to_string(), 1);
|
||||
config.access.user_max_tcp_conns.insert(user.to_string(), 1);
|
||||
|
||||
let (entered_tx, entered_rx) = tokio::sync::oneshot::channel();
|
||||
let (release_tx, release_rx) = tokio::sync::oneshot::channel();
|
||||
@@ -370,10 +367,7 @@ async fn cancelled_async_release_preserves_ip_cleanup_ownership() {
|
||||
let user = "cancelled-release-user";
|
||||
let peer_addr: SocketAddr = "198.51.100.211:50001".parse().unwrap();
|
||||
let mut config = ProxyConfig::default();
|
||||
config
|
||||
.access
|
||||
.user_max_tcp_conns
|
||||
.insert(user.to_string(), 1);
|
||||
config.access.user_max_tcp_conns.insert(user.to_string(), 1);
|
||||
|
||||
let reservation = acquire_user_connection_reservation(
|
||||
user,
|
||||
|
||||
@@ -77,9 +77,11 @@ fn controller_handoff_waits_for_inflight_update_and_fences_old_generation() {
|
||||
activated_tx.send(()).unwrap();
|
||||
});
|
||||
|
||||
assert!(activated_rx
|
||||
.recv_timeout(Duration::from_millis(50))
|
||||
.is_err());
|
||||
assert!(
|
||||
activated_rx
|
||||
.recv_timeout(Duration::from_millis(50))
|
||||
.is_err()
|
||||
);
|
||||
drop(update);
|
||||
activated_rx.recv_timeout(Duration::from_secs(1)).unwrap();
|
||||
activation.join().unwrap();
|
||||
|
||||
@@ -81,10 +81,8 @@ fn adversarial_intermediate_parent_swap_is_blocked_by_component_walk() {
|
||||
let parent = directory.path().join("parent");
|
||||
let moved = directory.path().join("moved");
|
||||
let outside = directory.path().join("outside");
|
||||
fs::create_dir_all(parent.join("nested"))
|
||||
.expect("original nested directory must be creatable");
|
||||
fs::create_dir_all(outside.join("nested"))
|
||||
.expect("outside nested directory must be creatable");
|
||||
fs::create_dir_all(parent.join("nested")).expect("original nested directory must be creatable");
|
||||
fs::create_dir_all(outside.join("nested")).expect("outside nested directory must be creatable");
|
||||
|
||||
let candidate = parent.join("nested/unknown-dc.log");
|
||||
let sanitized = sanitize_unknown_dc_log_path(
|
||||
|
||||
@@ -154,10 +154,7 @@ enum BucketReserveError {
|
||||
|
||||
impl BucketReserveError {
|
||||
fn exhausted_reserve_budget(self) -> bool {
|
||||
matches!(
|
||||
self,
|
||||
Self::Contended | Self::ReserveAndRefundContended
|
||||
)
|
||||
matches!(self, Self::Contended | Self::ReserveAndRefundContended)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -67,12 +67,8 @@ impl DirectionBucket {
|
||||
if self.should_force_reserve_failure() {
|
||||
return Err(current);
|
||||
}
|
||||
self.state.compare_exchange(
|
||||
current,
|
||||
next,
|
||||
Ordering::Relaxed,
|
||||
Ordering::Relaxed,
|
||||
)
|
||||
self.state
|
||||
.compare_exchange(current, next, Ordering::Relaxed, Ordering::Relaxed)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
@@ -81,12 +77,8 @@ impl DirectionBucket {
|
||||
if self.should_force_refund_failure() {
|
||||
return Err(current);
|
||||
}
|
||||
self.state.compare_exchange(
|
||||
current,
|
||||
next,
|
||||
Ordering::Relaxed,
|
||||
Ordering::Relaxed,
|
||||
)
|
||||
self.state
|
||||
.compare_exchange(current, next, Ordering::Relaxed, Ordering::Relaxed)
|
||||
}
|
||||
|
||||
fn unpack(state: u64) -> (u64, u64) {
|
||||
@@ -355,9 +347,9 @@ impl CidrDirectionBucket {
|
||||
});
|
||||
};
|
||||
let user_granted = user_debit.granted();
|
||||
let Some(aggregate_debit) = self
|
||||
.used
|
||||
.try_reserve_at(epoch, cap_epoch, user_granted, budget)?
|
||||
let Some(aggregate_debit) =
|
||||
self.used
|
||||
.try_reserve_at(epoch, cap_epoch, user_granted, budget)?
|
||||
else {
|
||||
return Ok(CidrReservation {
|
||||
granted: 0,
|
||||
@@ -410,12 +402,8 @@ impl CidrUserDirectionState {
|
||||
if observed_epoch > epoch {
|
||||
return Err(BucketReserveError::StaleEpoch);
|
||||
}
|
||||
let Some(mut active_debit) = active_users.try_reserve_at(
|
||||
epoch,
|
||||
PACKED_USAGE_MASK,
|
||||
1,
|
||||
budget,
|
||||
)?
|
||||
let Some(mut active_debit) =
|
||||
active_users.try_reserve_at(epoch, PACKED_USAGE_MASK, 1, budget)?
|
||||
else {
|
||||
return Ok(false);
|
||||
};
|
||||
@@ -532,10 +520,9 @@ impl CidrBucket {
|
||||
}
|
||||
let cap_epoch = bytes_per_epoch(cap_bps);
|
||||
match direction {
|
||||
RateDirection::Up => {
|
||||
self.up
|
||||
.try_reserve(&share.up, epoch, cap_epoch, requested, budget)
|
||||
}
|
||||
RateDirection::Up => self
|
||||
.up
|
||||
.try_reserve(&share.up, epoch, cap_epoch, requested, budget),
|
||||
RateDirection::Down => {
|
||||
self.down
|
||||
.try_reserve(&share.down, epoch, cap_epoch, requested, budget)
|
||||
|
||||
@@ -61,32 +61,28 @@ impl TrafficLease {
|
||||
let mut granted = requested;
|
||||
let mut user_debit = None;
|
||||
if let Some(user_bucket) = binding.user_bucket.as_ref() {
|
||||
let user_reservation = match user_bucket.try_reserve(
|
||||
direction,
|
||||
epoch,
|
||||
granted,
|
||||
&mut budget,
|
||||
) {
|
||||
Ok(reservation) => reservation,
|
||||
Err(error) => {
|
||||
if error.exhausted_reserve_budget() {
|
||||
self.limiter
|
||||
.user_scope
|
||||
.reserve_cas_retry_exhausted(direction);
|
||||
let user_reservation =
|
||||
match user_bucket.try_reserve(direction, epoch, granted, &mut budget) {
|
||||
Ok(reservation) => reservation,
|
||||
Err(error) => {
|
||||
if error.exhausted_reserve_budget() {
|
||||
self.limiter
|
||||
.user_scope
|
||||
.reserve_cas_retry_exhausted(direction);
|
||||
}
|
||||
return TrafficReservation {
|
||||
result: TrafficConsumeResult {
|
||||
granted: 0,
|
||||
blocked_user: false,
|
||||
blocked_cidr: false,
|
||||
},
|
||||
_binding: binding,
|
||||
user: None,
|
||||
cidr: None,
|
||||
cidr_user: None,
|
||||
};
|
||||
}
|
||||
return TrafficReservation {
|
||||
result: TrafficConsumeResult {
|
||||
granted: 0,
|
||||
blocked_user: false,
|
||||
blocked_cidr: false,
|
||||
},
|
||||
_binding: binding,
|
||||
user: None,
|
||||
cidr: None,
|
||||
cidr_user: None,
|
||||
};
|
||||
}
|
||||
};
|
||||
};
|
||||
user_debit = user_reservation.debit;
|
||||
if user_reservation.granted == 0 {
|
||||
self.limiter.observe_throttle(direction, true, false);
|
||||
@@ -107,9 +103,10 @@ impl TrafficLease {
|
||||
|
||||
let mut cidr_debit = None;
|
||||
let mut cidr_user_debit = None;
|
||||
if let (Some(cidr_bucket), Some(cidr_user_share)) =
|
||||
(binding.cidr_bucket.as_ref(), binding.cidr_user_share.as_ref())
|
||||
{
|
||||
if let (Some(cidr_bucket), Some(cidr_user_share)) = (
|
||||
binding.cidr_bucket.as_ref(),
|
||||
binding.cidr_user_share.as_ref(),
|
||||
) {
|
||||
let cidr_reservation = match cidr_bucket.try_reserve_for_user(
|
||||
direction,
|
||||
cidr_user_share,
|
||||
|
||||
@@ -330,14 +330,38 @@ impl TrafficLimiter {
|
||||
cidr_refund_down,
|
||||
] = values;
|
||||
for (counter, value) in [
|
||||
(&self.user_scope.contention_up.reserve_exhausted_total, user_reserve_up),
|
||||
(&self.user_scope.contention_down.reserve_exhausted_total, user_reserve_down),
|
||||
(&self.user_scope.contention_up.refund_exhausted_total, user_refund_up),
|
||||
(&self.user_scope.contention_down.refund_exhausted_total, user_refund_down),
|
||||
(&self.cidr_scope.contention_up.reserve_exhausted_total, cidr_reserve_up),
|
||||
(&self.cidr_scope.contention_down.reserve_exhausted_total, cidr_reserve_down),
|
||||
(&self.cidr_scope.contention_up.refund_exhausted_total, cidr_refund_up),
|
||||
(&self.cidr_scope.contention_down.refund_exhausted_total, cidr_refund_down),
|
||||
(
|
||||
&self.user_scope.contention_up.reserve_exhausted_total,
|
||||
user_reserve_up,
|
||||
),
|
||||
(
|
||||
&self.user_scope.contention_down.reserve_exhausted_total,
|
||||
user_reserve_down,
|
||||
),
|
||||
(
|
||||
&self.user_scope.contention_up.refund_exhausted_total,
|
||||
user_refund_up,
|
||||
),
|
||||
(
|
||||
&self.user_scope.contention_down.refund_exhausted_total,
|
||||
user_refund_down,
|
||||
),
|
||||
(
|
||||
&self.cidr_scope.contention_up.reserve_exhausted_total,
|
||||
cidr_reserve_up,
|
||||
),
|
||||
(
|
||||
&self.cidr_scope.contention_down.reserve_exhausted_total,
|
||||
cidr_reserve_down,
|
||||
),
|
||||
(
|
||||
&self.cidr_scope.contention_up.refund_exhausted_total,
|
||||
cidr_refund_up,
|
||||
),
|
||||
(
|
||||
&self.cidr_scope.contention_down.refund_exhausted_total,
|
||||
cidr_refund_down,
|
||||
),
|
||||
] {
|
||||
counter.store(value, Ordering::Relaxed);
|
||||
}
|
||||
|
||||
@@ -65,12 +65,7 @@ fn reserve_at(
|
||||
cap: u64,
|
||||
requested: u64,
|
||||
) -> Result<Option<DirectionDebit>, BucketReserveError> {
|
||||
bucket.try_reserve_at(
|
||||
epoch,
|
||||
cap,
|
||||
requested,
|
||||
&mut ReserveCasBudget::new(),
|
||||
)
|
||||
bucket.try_reserve_at(epoch, cap, requested, &mut ReserveCasBudget::new())
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -346,11 +341,7 @@ fn concurrent_first_use_counts_one_active_cidr_user() {
|
||||
let barrier = Arc::clone(&barrier);
|
||||
threads.push(std::thread::spawn(move || {
|
||||
barrier.wait();
|
||||
user.ensure_active(
|
||||
13,
|
||||
&bucket.active_users,
|
||||
&mut ReserveCasBudget::new(),
|
||||
)
|
||||
user.ensure_active(13, &bucket.active_users, &mut ReserveCasBudget::new())
|
||||
}));
|
||||
}
|
||||
let results: Vec<_> = threads
|
||||
|
||||
@@ -9,10 +9,7 @@ fn reserve_stops_after_the_attempt_limit() {
|
||||
|
||||
let reservation = bucket.try_reserve_at(1, 100, 1, &mut budget);
|
||||
|
||||
assert!(matches!(
|
||||
reservation,
|
||||
Err(BucketReserveError::Contended)
|
||||
));
|
||||
assert!(matches!(reservation, Err(BucketReserveError::Contended)));
|
||||
assert_eq!(
|
||||
bucket.reserve_cas_attempts(),
|
||||
RESERVE_CAS_ATTEMPT_LIMIT as u64
|
||||
@@ -32,7 +29,10 @@ fn reserve_succeeds_on_the_last_allowed_attempt() {
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(debit.commit_all(), 80);
|
||||
assert_eq!(bucket.reserve_cas_attempts(), RESERVE_CAS_ATTEMPT_LIMIT as u64);
|
||||
assert_eq!(
|
||||
bucket.reserve_cas_attempts(),
|
||||
RESERVE_CAS_ATTEMPT_LIMIT as u64
|
||||
);
|
||||
assert!(budget.is_exhausted());
|
||||
assert_eq!(bucket.used_at(1), Some(80));
|
||||
}
|
||||
@@ -121,15 +121,7 @@ fn lease_contention_is_not_reported_as_throttling() {
|
||||
let lease = limiter
|
||||
.acquire_lease("alice", "203.0.113.7".parse().unwrap())
|
||||
.unwrap();
|
||||
let bucket = Arc::clone(
|
||||
&lease
|
||||
.binding
|
||||
.load_full()
|
||||
.user_bucket
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.down,
|
||||
);
|
||||
let bucket = Arc::clone(&lease.binding.load_full().user_bucket.as_ref().unwrap().down);
|
||||
bucket.force_reserve_failures(RESERVE_CAS_ATTEMPT_LIMIT);
|
||||
|
||||
let result = lease.try_consume(RateDirection::Down, 1);
|
||||
@@ -187,12 +179,7 @@ fn cidr_contention_rolls_back_provisional_user_debits() {
|
||||
assert!(!result.blocked_user);
|
||||
assert!(!result.blocked_cidr);
|
||||
assert_eq!(
|
||||
binding
|
||||
.user_bucket
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.down
|
||||
.used_at(epoch),
|
||||
binding.user_bucket.as_ref().unwrap().down.used_at(epoch),
|
||||
Some(0)
|
||||
);
|
||||
assert_eq!(cidr_bucket.down.used.used_at(epoch), None);
|
||||
@@ -275,8 +262,7 @@ fn contention_snapshot_preserves_scope_direction_and_operation() {
|
||||
fn cidr_activation_consumes_one_shared_attempt_budget() {
|
||||
let bucket = CidrDirectionBucket::default();
|
||||
let user = CidrUserDirectionState::default();
|
||||
user.used
|
||||
.force_reserve_failures(RESERVE_CAS_ATTEMPT_LIMIT);
|
||||
user.used.force_reserve_failures(RESERVE_CAS_ATTEMPT_LIMIT);
|
||||
let mut budget = ReserveCasBudget::new();
|
||||
|
||||
let activation = user.ensure_active(13, &bucket.active_users, &mut budget);
|
||||
@@ -360,19 +346,11 @@ fn cidr_first_grants_preserve_the_current_soft_fair_share() {
|
||||
let first = CidrUserDirectionState::default();
|
||||
let second = CidrUserDirectionState::default();
|
||||
assert_eq!(
|
||||
first.ensure_active(
|
||||
17,
|
||||
&bucket.active_users,
|
||||
&mut ReserveCasBudget::new(),
|
||||
),
|
||||
first.ensure_active(17, &bucket.active_users, &mut ReserveCasBudget::new(),),
|
||||
Ok(true)
|
||||
);
|
||||
assert_eq!(
|
||||
second.ensure_active(
|
||||
17,
|
||||
&bucket.active_users,
|
||||
&mut ReserveCasBudget::new(),
|
||||
),
|
||||
second.ensure_active(17, &bucket.active_users, &mut ReserveCasBudget::new(),),
|
||||
Ok(true)
|
||||
);
|
||||
|
||||
@@ -391,21 +369,13 @@ fn cidr_first_grants_preserve_the_current_soft_fair_share() {
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.commit_all();
|
||||
first_reservation
|
||||
.user_debit
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.commit_all();
|
||||
first_reservation.user_debit.as_mut().unwrap().commit_all();
|
||||
second_reservation
|
||||
.aggregate_debit
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.commit_all();
|
||||
second_reservation
|
||||
.user_debit
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.commit_all();
|
||||
second_reservation.user_debit.as_mut().unwrap().commit_all();
|
||||
assert_eq!(bucket.used.used_at(17), Some(100));
|
||||
assert_eq!(first.used.used_at(17), Some(50));
|
||||
assert_eq!(second.used.used_at(17), Some(50));
|
||||
|
||||
@@ -335,8 +335,7 @@ impl UserAdmissionAuthority {
|
||||
record.incarnation = incarnation;
|
||||
if identity_changed {
|
||||
if previous.is_some() {
|
||||
self.quota_store
|
||||
.advance_preserving_usage(user, incarnation);
|
||||
self.quota_store.advance_preserving_usage(user, incarnation);
|
||||
} else {
|
||||
self.quota_store.activate_fresh(user, incarnation);
|
||||
}
|
||||
@@ -420,7 +419,8 @@ impl UserAdmissionAuthority {
|
||||
}
|
||||
let record = state.users.get(user)?;
|
||||
let effective = record.effective()?;
|
||||
(effective.enabled && effective.credential_id == credential_id).then_some(record.incarnation)
|
||||
(effective.enabled && effective.credential_id == credential_id)
|
||||
.then_some(record.incarnation)
|
||||
}
|
||||
|
||||
/// Starts a short publication critical section for one authenticated owner.
|
||||
@@ -456,10 +456,7 @@ impl UserAdmissionAuthority {
|
||||
}
|
||||
|
||||
/// Registers a legacy owner when no credential snapshot is available.
|
||||
pub(crate) fn register_legacy(
|
||||
self: &Arc<Self>,
|
||||
user: &str,
|
||||
) -> Option<UserSessionRegistration> {
|
||||
pub(crate) fn register_legacy(self: &Arc<Self>, user: &str) -> Option<UserSessionRegistration> {
|
||||
let credential_id = {
|
||||
let state = self.state.lock();
|
||||
if !state.initialized {
|
||||
@@ -520,9 +517,7 @@ pub(crate) fn credential_id_from_hex(secret: &str) -> Option<UserCredentialId> {
|
||||
Some(credential_id(&secret))
|
||||
}
|
||||
|
||||
fn cancel_owners(
|
||||
cancellations: Vec<(String, Vec<CancellationToken>)>,
|
||||
) -> Vec<(String, usize)> {
|
||||
fn cancel_owners(cancellations: Vec<(String, Vec<CancellationToken>)>) -> Vec<(String, usize)> {
|
||||
cancellations
|
||||
.into_iter()
|
||||
.map(|(user, tokens)| {
|
||||
|
||||
@@ -51,12 +51,7 @@ fn stale_candidate_cannot_overwrite_newer_mutation() {
|
||||
|
||||
assert!(
|
||||
authority
|
||||
.activate_config_source(
|
||||
2,
|
||||
Some(candidate_epoch),
|
||||
&users(secret),
|
||||
&HashMap::new(),
|
||||
)
|
||||
.activate_config_source(2, Some(candidate_epoch), &users(secret), &HashMap::new(),)
|
||||
.is_none()
|
||||
);
|
||||
assert!(!authority.is_user_enabled("alice"));
|
||||
@@ -105,9 +100,7 @@ fn registration_dropped_before_publication_cannot_leave_an_owner() {
|
||||
let secret = "00112233445566778899aabbccddeeff";
|
||||
authority.apply_config(&users(secret), &HashMap::new());
|
||||
let credential = credential_id_from_hex(secret).unwrap();
|
||||
let mut publication = authority
|
||||
.claim_authenticated("alice", credential)
|
||||
.unwrap();
|
||||
let mut publication = authority.claim_authenticated("alice", credential).unwrap();
|
||||
let registration = publication.take_registration().unwrap();
|
||||
|
||||
drop(registration);
|
||||
@@ -126,9 +119,7 @@ fn quota_identity_follows_credential_rotation_and_recreation() {
|
||||
let old_incarnation = authority
|
||||
.authenticated_incarnation("alice", credential_id_from_hex(old_secret).unwrap())
|
||||
.unwrap();
|
||||
let old_quota = quota_store
|
||||
.handle_exact("alice", old_incarnation)
|
||||
.unwrap();
|
||||
let old_quota = quota_store.handle_exact("alice", old_incarnation).unwrap();
|
||||
old_quota.charge(40);
|
||||
|
||||
let rotated = authority.stage_user("alice", new_secret, true).unwrap();
|
||||
|
||||
Reference in New Issue
Block a user