feat(smart-proxy): add UDP transport support with QUIC/HTTP3 routing and datagram handler relay
This commit is contained in:
@@ -74,6 +74,14 @@ export interface IMetrics {
|
||||
topByErrors(limit?: number): Array<{ backend: string; errors: number }>;
|
||||
};
|
||||
|
||||
// UDP metrics
|
||||
udp: {
|
||||
activeSessions(): number;
|
||||
totalSessions(): number;
|
||||
datagramsIn(): number;
|
||||
datagramsOut(): number;
|
||||
};
|
||||
|
||||
// Performance metrics
|
||||
percentiles: {
|
||||
connectionDuration(): { p50: number; p95: number; p99: number };
|
||||
|
||||
@@ -20,9 +20,15 @@ export type TSocketHandler = (socket: plugins.net.Socket, context: IRouteContext
|
||||
export type TTlsMode = 'passthrough' | 'terminate' | 'terminate-and-reencrypt';
|
||||
|
||||
/**
|
||||
* Port range specification format
|
||||
* Transport protocol for route matching
|
||||
*/
|
||||
export type TPortRange = number | number[] | Array<{ from: number; to: number }>;
|
||||
export type TTransportProtocol = 'tcp' | 'udp' | 'all';
|
||||
|
||||
/**
|
||||
* Port range specification format.
|
||||
* Supports: single number, array of numbers, array of ranges, or mixed arrays.
|
||||
*/
|
||||
export type TPortRange = number | Array<number | { from: number; to: number }>;
|
||||
|
||||
/**
|
||||
* Route match criteria for incoming requests
|
||||
@@ -31,6 +37,9 @@ export interface IRouteMatch {
|
||||
// Listen on these ports (required)
|
||||
ports: TPortRange;
|
||||
|
||||
// Transport protocol: 'tcp' (default), 'udp', or 'all' (both TCP and UDP)
|
||||
transport?: TTransportProtocol;
|
||||
|
||||
// Optional domain patterns to match (default: all domains)
|
||||
domains?: string | string[];
|
||||
|
||||
@@ -39,7 +48,7 @@ export interface IRouteMatch {
|
||||
clientIp?: string[]; // Match specific client IPs
|
||||
tlsVersion?: string[]; // Match specific TLS versions
|
||||
headers?: Record<string, string | RegExp>; // Match specific HTTP headers
|
||||
protocol?: 'http' | 'tcp'; // Match specific protocol (http includes h2 + websocket upgrades)
|
||||
protocol?: 'http' | 'tcp' | 'udp' | 'quic' | 'http3'; // Match specific protocol
|
||||
}
|
||||
|
||||
|
||||
@@ -72,6 +81,9 @@ export interface IRouteTarget {
|
||||
headers?: IRouteHeaders; // Override route-level headers
|
||||
advanced?: IRouteAdvanced; // Override route-level advanced settings
|
||||
|
||||
// Override transport for backend connection (e.g., receive QUIC but forward as HTTP/1.1 via TCP)
|
||||
backendTransport?: 'tcp' | 'udp';
|
||||
|
||||
// Priority for matching (higher values are checked first, default: 0)
|
||||
priority?: number;
|
||||
}
|
||||
@@ -262,7 +274,7 @@ export interface IRouteAction {
|
||||
|
||||
// Additional options for backend-specific settings
|
||||
options?: {
|
||||
backendProtocol?: 'http1' | 'http2' | 'auto';
|
||||
backendProtocol?: 'http1' | 'http2' | 'http3' | 'auto';
|
||||
[key: string]: any;
|
||||
};
|
||||
|
||||
@@ -274,9 +286,15 @@ export interface IRouteAction {
|
||||
|
||||
// Socket handler function (when type is 'socket-handler')
|
||||
socketHandler?: TSocketHandler;
|
||||
|
||||
|
||||
// Datagram handler function for UDP (when type is 'socket-handler' and transport is 'udp')
|
||||
datagramHandler?: TDatagramHandler;
|
||||
|
||||
// PROXY protocol support (default for all targets, can be overridden per target)
|
||||
sendProxyProtocol?: boolean;
|
||||
|
||||
// UDP-specific settings (session tracking, datagram limits, QUIC config)
|
||||
udp?: IRouteUdp;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -356,4 +374,64 @@ export interface IRouteConfig {
|
||||
enabled?: boolean; // Whether the route is active (default: true)
|
||||
}
|
||||
|
||||
// ─── UDP & QUIC Types ─────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* Handler for individual UDP datagrams.
|
||||
* Called for each incoming datagram on a socket-handler route with UDP transport.
|
||||
*/
|
||||
export type TDatagramHandler = (
|
||||
datagram: Buffer,
|
||||
info: IDatagramInfo,
|
||||
reply: (data: Buffer) => void
|
||||
) => void | Promise<void>;
|
||||
|
||||
/**
|
||||
* Metadata for a received UDP datagram
|
||||
*/
|
||||
export interface IDatagramInfo {
|
||||
/** Source IP address */
|
||||
sourceIp: string;
|
||||
/** Source port */
|
||||
sourcePort: number;
|
||||
/** Destination (local) port the datagram arrived on */
|
||||
destPort: number;
|
||||
/** Route context */
|
||||
context: IRouteContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* UDP-specific settings for route actions
|
||||
*/
|
||||
export interface IRouteUdp {
|
||||
/** Idle timeout for a UDP session/flow (keyed by src IP:port), in ms. Default: 60000 */
|
||||
sessionTimeout?: number;
|
||||
/** Max concurrent UDP sessions per source IP. Default: 1000 */
|
||||
maxSessionsPerIP?: number;
|
||||
/** Max accepted datagram size in bytes. Oversized datagrams are dropped. Default: 65535 */
|
||||
maxDatagramSize?: number;
|
||||
/** QUIC-specific configuration. When present, traffic is treated as QUIC. */
|
||||
quic?: IRouteQuic;
|
||||
}
|
||||
|
||||
/**
|
||||
* QUIC and HTTP/3 settings
|
||||
*/
|
||||
export interface IRouteQuic {
|
||||
/** QUIC connection idle timeout in ms. Default: 30000 */
|
||||
maxIdleTimeout?: number;
|
||||
/** Max concurrent bidirectional streams per QUIC connection. Default: 100 */
|
||||
maxConcurrentBidiStreams?: number;
|
||||
/** Max concurrent unidirectional streams per QUIC connection. Default: 100 */
|
||||
maxConcurrentUniStreams?: number;
|
||||
/** Enable HTTP/3 over this QUIC endpoint. Default: false */
|
||||
enableHttp3?: boolean;
|
||||
/** Port to advertise in Alt-Svc header on TCP HTTP responses. Default: listening port */
|
||||
altSvcPort?: number;
|
||||
/** Max age for Alt-Svc advertisement in seconds. Default: 86400 */
|
||||
altSvcMaxAge?: number;
|
||||
/** Initial congestion window size in bytes. Default: implementation-defined */
|
||||
initialCongestionWindow?: number;
|
||||
}
|
||||
|
||||
// Configuration moved to models/interfaces.ts as ISmartProxyOptions
|
||||
Reference in New Issue
Block a user