mirror of
https://github.com/telemt/telemt.git
synced 2026-10-31 04:50:35 +03:00
Bridge Request/Buffers/Recovery
Co-Authored-By: brekotis <93345790+brekotis@users.noreply.github.com>
This commit is contained in:
@@ -24,7 +24,7 @@ impl WebProcessRuntime {
|
||||
client_ip: IpAddr,
|
||||
) -> std::result::Result<BootstrapResult, ManagerError> {
|
||||
let generation = self.active_generation();
|
||||
self.issue_bootstrap_inner(&generation, profile, client_ip, None, false)
|
||||
self.issue_bootstrap_inner(&generation, profile, client_ip, None, false, None)
|
||||
}
|
||||
|
||||
/// Issues one bootstrap against the generation that selected the bridge profile.
|
||||
@@ -35,7 +35,7 @@ impl WebProcessRuntime {
|
||||
profile: Arc<WebRuntimeProfile>,
|
||||
client_ip: IpAddr,
|
||||
) -> std::result::Result<BootstrapResult, ManagerError> {
|
||||
self.issue_bootstrap_inner(generation, profile, client_ip, None, false)
|
||||
self.issue_bootstrap_inner(generation, profile, client_ip, None, false, None)
|
||||
}
|
||||
|
||||
/// Issues one bridge bootstrap with bounded non-secret request metadata.
|
||||
@@ -46,7 +46,7 @@ impl WebProcessRuntime {
|
||||
client_ip: IpAddr,
|
||||
user_agent: Option<&str>,
|
||||
) -> std::result::Result<BootstrapResult, ManagerError> {
|
||||
self.issue_bootstrap_inner(generation, profile, client_ip, user_agent, false)
|
||||
self.issue_bootstrap_inner(generation, profile, client_ip, user_agent, false, None)
|
||||
}
|
||||
|
||||
/// Issues one recovery bootstrap with the same positive-only admission boundary.
|
||||
@@ -56,8 +56,16 @@ impl WebProcessRuntime {
|
||||
profile: Arc<WebRuntimeProfile>,
|
||||
client_ip: IpAddr,
|
||||
user_agent: Option<&str>,
|
||||
predecessor_session_id: Option<u64>,
|
||||
) -> std::result::Result<BootstrapResult, ManagerError> {
|
||||
self.issue_bootstrap_inner(generation, profile, client_ip, user_agent, true)
|
||||
self.issue_bootstrap_inner(
|
||||
generation,
|
||||
profile,
|
||||
client_ip,
|
||||
user_agent,
|
||||
true,
|
||||
predecessor_session_id,
|
||||
)
|
||||
}
|
||||
|
||||
fn issue_bootstrap_inner(
|
||||
@@ -67,6 +75,7 @@ impl WebProcessRuntime {
|
||||
client_ip: IpAddr,
|
||||
user_agent: Option<&str>,
|
||||
recovery: bool,
|
||||
predecessor_session_id: Option<u64>,
|
||||
) -> std::result::Result<BootstrapResult, ManagerError> {
|
||||
let config = generation.config();
|
||||
let profile = config
|
||||
@@ -170,6 +179,7 @@ impl WebProcessRuntime {
|
||||
session_ip_learning_eligible: false,
|
||||
used: false,
|
||||
recovery,
|
||||
predecessor_session_id,
|
||||
},
|
||||
);
|
||||
*state.bootstraps_per_ip.entry(client_ip).or_insert(0) += 1;
|
||||
@@ -183,14 +193,32 @@ impl WebProcessRuntime {
|
||||
self.telemetry
|
||||
.record_bridge_recovery(WebBridgeRecoveryEvent::BootstrapIssued);
|
||||
}
|
||||
self.trace.record_profile_lifecycle(
|
||||
client_ip,
|
||||
Some(trace_session_id),
|
||||
&profile,
|
||||
crate::web::trace::TraceLifecycleEvent::BridgeIssued,
|
||||
None,
|
||||
None,
|
||||
);
|
||||
if recovery {
|
||||
self.trace.record_lifecycle_with_context(
|
||||
None,
|
||||
Some(client_ip),
|
||||
crate::web::trace::TraceIdentity::from_optional_profile(
|
||||
Some(trace_session_id),
|
||||
&profile,
|
||||
),
|
||||
crate::web::trace::TraceLifecycleEvent::BridgeIssued,
|
||||
None,
|
||||
None,
|
||||
crate::web::trace::TraceLifecycleContext {
|
||||
peer_gap_ms: None,
|
||||
predecessor_session_id,
|
||||
},
|
||||
);
|
||||
} else {
|
||||
self.trace.record_profile_lifecycle(
|
||||
client_ip,
|
||||
Some(trace_session_id),
|
||||
&profile,
|
||||
crate::web::trace::TraceLifecycleEvent::BridgeIssued,
|
||||
None,
|
||||
None,
|
||||
);
|
||||
}
|
||||
Ok(BootstrapResult {
|
||||
token,
|
||||
trace_session_id,
|
||||
@@ -227,13 +255,28 @@ impl WebProcessRuntime {
|
||||
hash: TokenHash,
|
||||
host: &str,
|
||||
) -> std::result::Result<Arc<WebSession>, ManagerError> {
|
||||
self.state
|
||||
.lock()
|
||||
let state = self.state.lock();
|
||||
if let Some(session) = state
|
||||
.sessions
|
||||
.get(&hash)
|
||||
.cloned()
|
||||
.filter(|session| session.matches_host(host))
|
||||
.ok_or(ManagerError::Authentication)
|
||||
{
|
||||
return Ok(session);
|
||||
}
|
||||
let retired_carrier = state
|
||||
.closed_tokens
|
||||
.get(&hash)
|
||||
.filter(|closed| closed.host == host)
|
||||
.map(|closed| closed.carrier);
|
||||
drop(state);
|
||||
if let Some(carrier) = retired_carrier {
|
||||
self.telemetry.record_session_observation(
|
||||
carrier,
|
||||
crate::web::telemetry::WebSessionLifecycleObservation::RequestAfterClose,
|
||||
);
|
||||
}
|
||||
Err(ManagerError::Authentication)
|
||||
}
|
||||
|
||||
/// Resolves a current bearer only when it belongs to the recovering profile.
|
||||
|
||||
@@ -82,9 +82,7 @@ impl WebProcessRuntime {
|
||||
&mut state,
|
||||
hash,
|
||||
profile_host,
|
||||
session.trace_session_id(),
|
||||
session.carrier(),
|
||||
reason,
|
||||
closed_token_lifetime,
|
||||
self.limits.max_sessions_global.saturating_mul(16),
|
||||
);
|
||||
|
||||
@@ -339,7 +339,14 @@ impl WebProcessRuntime {
|
||||
state.sessions.insert(session_hash, Arc::clone(&session));
|
||||
*state.sessions_per_ip.entry(client_ip).or_insert(0) += 1;
|
||||
*state.sessions_per_profile.entry(profile_key).or_insert(0) += 1;
|
||||
let (issuance_ip, candidate_count, user_agent, user_agent_id, recovery) = {
|
||||
let (
|
||||
issuance_ip,
|
||||
candidate_count,
|
||||
user_agent,
|
||||
user_agent_id,
|
||||
recovery,
|
||||
predecessor_session_id,
|
||||
) = {
|
||||
let entry = state
|
||||
.bootstraps
|
||||
.get_mut(&bootstrap_hash)
|
||||
@@ -367,6 +374,7 @@ impl WebProcessRuntime {
|
||||
entry.user_agent.clone(),
|
||||
entry.user_agent_id,
|
||||
entry.recovery,
|
||||
entry.predecessor_session_id,
|
||||
)
|
||||
};
|
||||
decrement_map(&mut state.bootstraps_per_ip, &issuance_ip);
|
||||
@@ -422,13 +430,17 @@ impl WebProcessRuntime {
|
||||
scores,
|
||||
None,
|
||||
);
|
||||
self.trace.record_lifecycle(
|
||||
self.trace.record_lifecycle_with_context(
|
||||
None,
|
||||
Some(client_ip),
|
||||
identity,
|
||||
TraceLifecycleEvent::SessionCreated,
|
||||
None,
|
||||
None,
|
||||
crate::web::trace::TraceLifecycleContext {
|
||||
peer_gap_ms: None,
|
||||
predecessor_session_id,
|
||||
},
|
||||
);
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
@@ -98,9 +98,7 @@ impl WebProcessRuntime {
|
||||
&mut state,
|
||||
old_hash,
|
||||
&replacement.profile.host,
|
||||
replacement.old_session.trace_session_id(),
|
||||
replacement.old_session.carrier(),
|
||||
crate::web::session::SessionCloseReason::CarrierSuperseded,
|
||||
Duration::from_secs(replacement.old_session.timeouts().bootstrap_lifetime_secs),
|
||||
self.limits.max_sessions_global.saturating_mul(16),
|
||||
);
|
||||
@@ -126,6 +124,9 @@ impl WebProcessRuntime {
|
||||
self.telemetry.record_bridge_recovery(
|
||||
crate::web::telemetry::WebBridgeRecoveryEvent::SessionCreated,
|
||||
);
|
||||
self.telemetry.record_bridge_recovery(
|
||||
crate::web::telemetry::WebBridgeRecoveryEvent::ClosedBeforeCommit,
|
||||
);
|
||||
}
|
||||
self.telemetry.record_session_closed(
|
||||
replacement.old_session.carrier(),
|
||||
|
||||
@@ -88,6 +88,8 @@ pub(super) struct Bootstrap {
|
||||
pub(super) used: bool,
|
||||
/// Whether this credential was issued by the post-commit recovery representation.
|
||||
pub(super) recovery: bool,
|
||||
/// Previous logical session authenticated by the recovery request, if current.
|
||||
pub(super) predecessor_session_id: Option<u64>,
|
||||
}
|
||||
|
||||
/// Bounded replay marker for one explicitly or naturally closed session token.
|
||||
@@ -96,12 +98,8 @@ pub(super) struct ClosedToken {
|
||||
pub(super) expires_at: Instant,
|
||||
/// Canonical host that owned the session.
|
||||
pub(super) host: String,
|
||||
/// Non-secret logical trace owner retained for exact late-request diagnostics.
|
||||
pub(super) trace_session_id: u64,
|
||||
/// Carrier that owned the retired bearer.
|
||||
pub(super) carrier: WebCarrier,
|
||||
/// First-writer terminal cause for the retired bearer.
|
||||
pub(super) reason: crate::web::session::SessionCloseReason,
|
||||
}
|
||||
|
||||
/// Current logical-session owner stored without exposing bearer credentials.
|
||||
@@ -363,9 +361,7 @@ pub(super) fn remember_closed_token_locked(
|
||||
state: &mut ManagerState,
|
||||
hash: TokenHash,
|
||||
host: &str,
|
||||
trace_session_id: u64,
|
||||
carrier: WebCarrier,
|
||||
reason: crate::web::session::SessionCloseReason,
|
||||
lifetime: Duration,
|
||||
capacity: usize,
|
||||
) {
|
||||
@@ -374,9 +370,7 @@ pub(super) fn remember_closed_token_locked(
|
||||
ClosedToken {
|
||||
expires_at: Instant::now() + lifetime,
|
||||
host: host.to_string(),
|
||||
trace_session_id,
|
||||
carrier,
|
||||
reason,
|
||||
},
|
||||
);
|
||||
while state.closed_tokens.len() > capacity {
|
||||
|
||||
Reference in New Issue
Block a user