feat(udp,http3): add UDP datagram handler relay support and stream HTTP/3 request bodies to backends
This commit is contained in:
@@ -20,7 +20,6 @@ use rustproxy_metrics::MetricsCollector;
|
||||
use rustproxy_routing::{MatchContext, RouteManager};
|
||||
|
||||
use crate::connection_tracker::ConnectionTracker;
|
||||
use crate::forwarder::ForwardMetricsCtx;
|
||||
|
||||
/// Create a QUIC server endpoint on the given port with the provided TLS config.
|
||||
///
|
||||
@@ -116,7 +115,7 @@ pub async fn quic_accept_loop(
|
||||
let cancel = cancel.child_token();
|
||||
|
||||
tokio::spawn(async move {
|
||||
match handle_quic_connection(incoming, route, port, &metrics, &cancel).await {
|
||||
match handle_quic_connection(incoming, route, port, Arc::clone(&metrics), &cancel).await {
|
||||
Ok(()) => debug!("QUIC connection from {} completed", remote_addr),
|
||||
Err(e) => debug!("QUIC connection from {} error: {}", remote_addr, e),
|
||||
}
|
||||
@@ -138,7 +137,7 @@ async fn handle_quic_connection(
|
||||
incoming: quinn::Incoming,
|
||||
route: RouteConfig,
|
||||
port: u16,
|
||||
metrics: &MetricsCollector,
|
||||
metrics: Arc<MetricsCollector>,
|
||||
cancel: &CancellationToken,
|
||||
) -> anyhow::Result<()> {
|
||||
let connection = incoming.await?;
|
||||
@@ -155,7 +154,7 @@ async fn handle_quic_connection(
|
||||
// Phase 5: dispatch to H3ProxyService
|
||||
// For now, log and accept streams for basic handling
|
||||
debug!("HTTP/3 enabled for route {:?}, dispatching to H3 handler", route.name);
|
||||
handle_h3_connection(connection, route, port, metrics, cancel).await
|
||||
handle_h3_connection(connection, route, port, &metrics, cancel).await
|
||||
} else {
|
||||
// Non-HTTP3 QUIC: bidirectional stream forwarding to TCP backend
|
||||
handle_quic_stream_forwarding(connection, route, port, metrics, cancel).await
|
||||
@@ -171,11 +170,12 @@ async fn handle_quic_stream_forwarding(
|
||||
connection: quinn::Connection,
|
||||
route: RouteConfig,
|
||||
port: u16,
|
||||
_metrics: &MetricsCollector,
|
||||
metrics: Arc<MetricsCollector>,
|
||||
cancel: &CancellationToken,
|
||||
) -> anyhow::Result<()> {
|
||||
let remote_addr = connection.remote_address();
|
||||
let route_id = route.name.as_deref().or(route.id.as_deref());
|
||||
let metrics_arc = metrics;
|
||||
|
||||
// Resolve backend target
|
||||
let target = route.action.targets.as_ref()
|
||||
@@ -203,11 +203,8 @@ async fn handle_quic_stream_forwarding(
|
||||
|
||||
let backend_addr = backend_addr.clone();
|
||||
let ip_str = remote_addr.ip().to_string();
|
||||
let _fwd_ctx = ForwardMetricsCtx {
|
||||
collector: Arc::new(MetricsCollector::new()), // TODO: share real metrics
|
||||
route_id: route_id.map(|s| s.to_string()),
|
||||
source_ip: Some(ip_str),
|
||||
};
|
||||
let stream_metrics = Arc::clone(&metrics_arc);
|
||||
let stream_route_id = route_id.map(|s| s.to_string());
|
||||
|
||||
// Spawn a task for each QUIC stream → TCP bidirectional forwarding
|
||||
tokio::spawn(async move {
|
||||
@@ -217,6 +214,11 @@ async fn handle_quic_stream_forwarding(
|
||||
&backend_addr,
|
||||
).await {
|
||||
Ok((bytes_in, bytes_out)) => {
|
||||
stream_metrics.record_bytes(
|
||||
bytes_in, bytes_out,
|
||||
stream_route_id.as_deref(),
|
||||
Some(&ip_str),
|
||||
);
|
||||
debug!("QUIC stream forwarded: {}B in, {}B out", bytes_in, bytes_out);
|
||||
}
|
||||
Err(e) => {
|
||||
|
||||
Reference in New Issue
Block a user