Refactor tunnel stability protocol

This commit is contained in:
elky
2026-06-01 01:36:49 +08:00
parent 392353ffff
commit 37413c0211
21 changed files with 1960 additions and 132 deletions
File diff suppressed because it is too large Load Diff
@@ -88,8 +88,13 @@ pub(crate) async fn open_direct_relay_stream(
let stream = state
.hub
.open_local_stream(node_id, &meta)
.await
.map_err(|error| format!("connect: {error}"))?;
if let Err(error) = state.hub.push_local_request_body(stream.id, body, true) {
if let Err(error) = state
.hub
.push_local_request_body(stream.id, body, true)
.await
{
state.hub.cancel_local_stream(stream.id, &error);
return Err(format!("connect: {error}"));
}
@@ -259,7 +264,7 @@ pub async fn relay_request(
continue;
};
let opened_stream = match state.hub.open_local_stream(&node_id, &parsed_meta) {
let opened_stream = match state.hub.open_local_stream(&node_id, &parsed_meta).await {
Ok(stream) => stream,
Err(error) => {
return release_permit_response(
@@ -271,10 +276,10 @@ pub async fn relay_request(
if envelope_buf.len() > body_offset {
let first_body_chunk = Bytes::copy_from_slice(&envelope_buf[body_offset..]);
if let Err(error) =
state
.hub
.push_local_request_body(opened_stream.id, first_body_chunk, false)
if let Err(error) = state
.hub
.push_local_request_body(opened_stream.id, first_body_chunk, false)
.await
{
state.hub.cancel_local_stream(opened_stream.id, &error);
return release_permit_response(
@@ -296,6 +301,7 @@ pub async fn relay_request(
if let Err(error) = state
.hub
.push_local_request_body(active_stream.id, chunk, false)
.await
{
state.hub.cancel_local_stream(active_stream.id, &error);
return release_permit_response(
@@ -322,6 +328,7 @@ pub async fn relay_request(
if let Err(error) = state
.hub
.push_local_request_body(stream.id, Bytes::new(), true)
.await
{
state.hub.cancel_local_stream(stream.id, &error);
return release_permit_response(
@@ -376,6 +376,7 @@ fn resolve_proxy_protocol_version(headers: &HeaderMap) -> u8 {
.and_then(|value| value.to_str().ok())
.and_then(|value| value.parse::<u8>().ok())
.filter(|value| *value >= 1)
.map(|value| value.min(aether_contracts::tunnel::CURRENT_TUNNEL_PROTOCOL_VERSION))
.unwrap_or(1)
}
@@ -1,10 +1,14 @@
use bytes::Bytes;
pub use aether_contracts::tunnel::{
decode_payload, encode_frame, encode_goaway, encode_ping, encode_pong, encode_stream_error,
frame_payload_by_header, FrameHeader, RequestMeta, ResponseMeta, FLAG_END_STREAM,
FLAG_GZIP_COMPRESSED, GOAWAY, HEADER_SIZE, HEARTBEAT_ACK, HEARTBEAT_DATA, PING, PONG,
REQUEST_BODY, REQUEST_HEADERS, RESPONSE_BODY, RESPONSE_HEADERS, STREAM_END, STREAM_ERROR,
decode_payload, encode_connection_close, encode_frame, encode_goaway, encode_goaway_v3,
encode_hello, encode_load_report, encode_ping, encode_pong, encode_reset_stream,
encode_settings, encode_stream_error, encode_window_update, frame_payload_by_header,
ConnectionClosePayload, FrameHeader, GoAwayPayload, HelloPayload, LoadReportPayload,
RequestMeta, ResetStreamPayload, ResponseMeta, SettingsPayload, WindowUpdatePayload,
CONNECTION_CLOSE, FLAG_END_STREAM, FLAG_GZIP_COMPRESSED, GOAWAY, HEADER_SIZE, HEARTBEAT_ACK,
HEARTBEAT_DATA, HELLO, LOAD_REPORT, PING, PONG, REQUEST_BODY, REQUEST_HEADERS, RESET_STREAM,
RESPONSE_BODY, RESPONSE_HEADERS, SETTINGS, STREAM_END, STREAM_ERROR, WINDOW_UPDATE,
};
pub fn compress_payload(payload: &[u8]) -> Result<(Vec<u8>, u8), std::io::Error> {
@@ -182,7 +182,9 @@ pub async fn handle_proxy_connection(
loop {
tokio::time::sleep(ping_interval).await;
let ping = protocol::encode_ping();
let status = ping_conn.send(Message::Binary(ping.into()));
let status = ping_conn
.send_wait(Message::Binary(ping.into()), Duration::from_millis(250))
.await;
if !matches!(status, SendStatus::Queued) {
let snapshot = ping_conn.outbound.snapshot();
match status {
+3 -2
View File
@@ -535,12 +535,13 @@ impl EmbeddedTunnelState {
http1_only: false,
transport_profile: None,
};
let stream = self.inner.hub.open_local_stream(node_id, &meta)?;
let stream = self.inner.hub.open_local_stream(node_id, &meta).await?;
let stream_id = stream.id;
let result = async {
self.inner
.hub
.push_local_request_body(stream_id, Bytes::new(), true)?;
.push_local_request_body(stream_id, Bytes::new(), true)
.await?;
let response = stream
.wait_headers(Duration::from_secs(timeout_secs))
.await?;