This commit is contained in:
Alexey
2026-08-23 10:56:00 +03:00
parent 596149cab8
commit 840b6f563a
31 changed files with 232 additions and 346 deletions
+2 -4
View File
@@ -3,9 +3,9 @@ use std::sync::Arc;
use std::sync::atomic::Ordering;
use std::time::Duration;
use crate::proxy::shared_state::ConntrackClosePolicy;
use crate::web::frame::FrameType;
use crate::web::stream::WebLogicalStream;
use crate::proxy::shared_state::ConntrackClosePolicy;
use super::{WebSession, inbound_queue_cost};
@@ -70,9 +70,7 @@ impl WebSession {
});
(queued, reserved)
};
if reserved
&& let Some(manager) = self.manager.upgrade()
{
if reserved && let Some(manager) = self.manager.upgrade() {
manager.release_stream(
self.profile_key,
self.client_ip,
+11 -29
View File
@@ -3,8 +3,7 @@ use std::time::{Duration, Instant};
use bytes::{BufMut, Bytes, BytesMut};
use super::{
DownBatch, PendingClass, PollResult, QUEUE_ITEM_COST, QueuedFrame, SessionState,
WebSession,
DownBatch, PendingClass, PollResult, QUEUE_ITEM_COST, QueuedFrame, SessionState, WebSession,
};
use crate::config::WebCarrier;
use crate::web::frame::{self, FrameType};
@@ -117,9 +116,8 @@ impl WebSession {
.limits
.pending_bytes_per_session
.saturating_sub(self.limits.control_bytes_per_session);
let item_reserve = 16usize.saturating_add(
self.limits.max_streams_per_session.saturating_mul(3),
);
let item_reserve =
16usize.saturating_add(self.limits.max_streams_per_session.saturating_mul(3));
let data_item_limit = self
.limits
.pending_items_per_session
@@ -146,14 +144,11 @@ impl WebSession {
.pending_items
.saturating_sub(state.pending_control_items);
let (byte_limit, item_limit) = if class == PendingClass::Downlink {
let uplink_bytes = self
.limits
.max_body_bytes
.saturating_add(
self.limits
.max_frames_per_body
.saturating_mul(QUEUE_ITEM_COST),
);
let uplink_bytes = self.limits.max_body_bytes.saturating_add(
self.limits
.max_frames_per_body
.saturating_mul(QUEUE_ITEM_COST),
);
(
data_byte_limit.saturating_sub(uplink_bytes),
data_item_limit.saturating_sub(self.limits.max_frames_per_body),
@@ -172,12 +167,7 @@ impl WebSession {
let Some(manager) = self.manager.upgrade() else {
return false;
};
if !manager.try_reserve_pending(
bytes,
items,
control,
class == PendingClass::Downlink,
) {
if !manager.try_reserve_pending(bytes, items, control, class == PendingClass::Downlink) {
return false;
}
state.pending_bytes += bytes;
@@ -301,13 +291,7 @@ impl WebSession {
control: bool,
) -> bool {
if self.carrier() == WebCarrier::HttpsLanes {
return self.queue_lane_frame_locked(
state,
frame_type,
stream_id,
payload,
control,
);
return self.queue_lane_frame_locked(state, frame_type, stream_id, payload, control);
}
let cost = frame::HEADER_BYTES + payload.len() + QUEUE_ITEM_COST;
let class = if control {
@@ -425,9 +409,7 @@ mod tests {
use std::net::SocketAddr;
use std::sync::Arc;
use crate::config::{
WebLimitsConfig, WebRuntimeProfile, WebSecretMode, WebTimeoutsConfig,
};
use crate::config::{WebLimitsConfig, WebRuntimeProfile, WebSecretMode, WebTimeoutsConfig};
use crate::web::manager::WebProcessRuntime;
fn session() -> Arc<WebSession> {
+15 -18
View File
@@ -7,8 +7,8 @@ use subtle::ConstantTimeEq;
use super::uplink::{inbound_reservation, validate_batch};
use super::{
CarrierLane, DownBatch, PendingClass, PollResult, QUEUE_ITEM_COST, QueuedFrame,
SessionState, WebSession, remember_closed,
CarrierLane, DownBatch, PendingClass, PollResult, QUEUE_ITEM_COST, QueuedFrame, SessionState,
WebSession, remember_closed,
};
use crate::config::{WebCarrier, WebLimitsConfig};
use crate::web::frame::{self, Frame, FrameType};
@@ -32,9 +32,11 @@ impl WebSession {
return Err(ManagerError::Protocol);
}
};
if frames.iter().copied().any(|value| {
value.stream_id != lane_id || frame::validate_client_shape(value).is_err()
}) {
if frames
.iter()
.copied()
.any(|value| value.stream_id != lane_id || frame::validate_client_shape(value).is_err())
{
self.close();
return Err(ManagerError::Protocol);
}
@@ -48,13 +50,17 @@ impl WebSession {
state.last_activity = Instant::now();
if !state.carrier_lanes.contains_key(&lane_id) {
if lane_id != 0
&& frames.first().is_some_and(|value| value.frame_type != FrameType::Open)
&& frames
.first()
.is_some_and(|value| value.frame_type != FrameType::Open)
&& only_late_frames(&frames)
{
return Ok(sequence);
}
if lane_id == 0
|| frames.first().is_none_or(|value| value.frame_type != FrameType::Open)
|| frames
.first()
.is_none_or(|value| value.frame_type != FrameType::Open)
{
drop(state);
self.close();
@@ -182,12 +188,7 @@ impl WebSession {
};
if let Some(batch) = acknowledged {
self.release_locked(&mut state, batch.data_bytes, batch.data_items, false);
self.release_locked(
&mut state,
batch.control_bytes,
batch.control_items,
true,
);
self.release_locked(&mut state, batch.control_bytes, batch.control_items, true);
if let Some(stream) = state.streams.get_mut(&lane_id)
&& let Some(waker) = stream.write_waker.take()
{
@@ -402,11 +403,7 @@ impl WebSession {
}
pub(super) fn remember_closed_locked(&self, state: &mut SessionState, stream_id: u32) {
let evicted = remember_closed(
state,
stream_id,
self.limits.max_tombstones_per_session,
);
let evicted = remember_closed(state, stream_id, self.limits.max_tombstones_per_session);
if self.carrier() != WebCarrier::HttpsLanes {
return;
}
+8 -7
View File
@@ -4,9 +4,7 @@ use std::sync::Arc;
use bytes::BytesMut;
use super::*;
use crate::config::{
WebRuntimeProfile, WebSecretMode, WebTimeoutsConfig,
};
use crate::config::{WebRuntimeProfile, WebSecretMode, WebTimeoutsConfig};
use crate::web::manager::WebProcessRuntime;
fn session_with_limits(limits: WebLimitsConfig) -> Arc<WebSession> {
@@ -103,15 +101,18 @@ fn tombstone_eviction_releases_lane_budget_and_accepts_late_frames() {
state.carrier_lanes.insert(7, CarrierLane::new());
let encoded = frame::encode(FrameType::Close, 7, &[]);
let cost = encoded.len() + QUEUE_ITEM_COST;
state.carrier_lanes.get_mut(&7).unwrap().pending_frames.push_back(
QueuedFrame {
state
.carrier_lanes
.get_mut(&7)
.unwrap()
.pending_frames
.push_back(QueuedFrame {
encoded: BytesMut::from(encoded.as_ref()),
frame_type: FrameType::Close,
stream_id: 7,
control: true,
cost,
},
);
});
state.pending_bytes = cost;
state.pending_items = 1;
state.pending_control_bytes = cost;
+9 -21
View File
@@ -138,12 +138,8 @@ impl WebSession {
FrameType::Open => {
let Some(peer_port) = self.reserve_stream_locked(state) else {
self.remember_closed_locked(state, value.stream_id);
if !self.queue_control_locked(
state,
FrameType::Close,
value.stream_id,
&[],
) {
if !self.queue_control_locked(state, FrameType::Close, value.stream_id, &[])
{
return false;
}
continue;
@@ -169,8 +165,8 @@ impl WebSession {
bytes: Bytes::copy_from_slice(value.payload),
offset: 0,
});
*unused_bytes = unused_bytes
.saturating_sub(value.payload.len() + QUEUE_ITEM_COST);
*unused_bytes =
unused_bytes.saturating_sub(value.payload.len() + QUEUE_ITEM_COST);
*unused_items = unused_items.saturating_sub(1);
if let Some(waker) = stream.read_waker.take() {
waker.wake();
@@ -256,8 +252,8 @@ pub(super) fn validate_batch(state: &SessionState, frames: &[Frame<'_>]) -> bool
}
continue;
}
let was_closed = state.closed_streams.contains(&value.stream_id)
|| closed.contains(&value.stream_id);
let was_closed =
state.closed_streams.contains(&value.stream_id) || closed.contains(&value.stream_id);
match value.frame_type {
FrameType::Open => {
if live.contains_key(&value.stream_id) || was_closed {
@@ -308,10 +304,7 @@ pub(super) fn validate_batch(state: &SessionState, frames: &[Frame<'_>]) -> bool
true
}
pub(super) fn inbound_reservation(
state: &SessionState,
frames: &[Frame<'_>],
) -> (usize, usize) {
pub(super) fn inbound_reservation(state: &SessionState, frames: &[Frame<'_>]) -> (usize, usize) {
let mut live = state.streams.keys().copied().collect::<HashSet<_>>();
let mut bytes = 0usize;
let mut items = 0usize;
@@ -338,9 +331,7 @@ mod tests {
use super::*;
use std::net::SocketAddr;
use crate::config::{
WebLimitsConfig, WebRuntimeProfile, WebSecretMode, WebTimeoutsConfig,
};
use crate::config::{WebLimitsConfig, WebRuntimeProfile, WebSecretMode, WebTimeoutsConfig};
use crate::web::manager::WebProcessRuntime;
fn session() -> Arc<WebSession> {
@@ -383,10 +374,7 @@ mod tests {
let session = session();
let body = frame::encode(FrameType::Pong, 0, &[]);
session.up_active.store(true, Ordering::Release);
assert_eq!(
session.process_up(1, &body),
Err(ManagerError::Concurrent)
);
assert_eq!(session.process_up(1, &body), Err(ManagerError::Concurrent));
assert_eq!(session.state.lock().last_up_sequence, 0);
session.up_active.store(false, Ordering::Release);
assert_eq!(session.process_up(1, &body), Ok(1));