Skip to content

Feature/kcp transport#126

Draft
ErQrYfkrju wants to merge 3 commits into
cfal:masterfrom
ErQrYfkrju:feature/kcp-transport
Draft

Feature/kcp transport#126
ErQrYfkrju wants to merge 3 commits into
cfal:masterfrom
ErQrYfkrju:feature/kcp-transport

Conversation

@ErQrYfkrju
Copy link
Copy Markdown

This pull request reffers to #125
Code was added with support of copilot vscode feature (Claude Sonnet 4.6).

- Add Transport::Kcp variant to the Transport enum
- Add KcpSettings config struct (mode, send_window, recv_window, mtu)
- Add KcpMode enum (normal, fast, turbo, gaming, file_transfer)
- Add kcp_settings field to ServerConfig and ClientConfig
- Implement kcp_server.rs: KcpStreamWrapper + start_kcp_servers()
- Implement kcp_stream.rs: AsyncStream wrapper for kcp_tokio::KcpStream
- Update tcp_server.rs: dispatch Transport::Kcp to start_kcp_servers
- Update socket_connector_impl.rs: KCP client connection support
- Add validation in validate.rs for kcp_settings/transport consistency

Example YAML configuration:
  - address: 0.0.0.0:12345
    transport: kcp
    kcp_settings:
      mode: fast
    protocol:
      type: socks
Add KCP (KCP reliable UDP protocol) as a new transport layer, enabling
use of KCP-based proxying alongside the existing TCP and QUIC transports.

## Overview

KCP is a reliable ARQ (Automatic Repeat reQuest) protocol that runs over
UDP. It provides lower latency than TCP at the cost of higher bandwidth
usage, making it suitable for latency-sensitive proxy scenarios.

## Implementation

### New files
- src/kcp_server.rs   -- KCP listener, per-connection tokio::spawn, maps
                         KcpSettings/KcpMode config into KcpConfig presets
- src/kcp_stream.rs   -- KcpStreamWrapper: wraps kcp_tokio::KcpStream to
                         implement AsyncStream (AsyncRead + AsyncWrite + AsyncPing)

### KcpStreamWrapper::poll_shutdown behaviour
KCP has no half-close concept. Calling KcpStream::close() sets closed=true
which causes poll_read to immediately return 0 bytes (EOF). This breaks
Vision VLESS where copy_bidirectional calls shutdown on the write side
while the read side is still waiting for the VLESS response.

Fix: poll_shutdown only flushes pending writes. The KCP connection is
fully closed when KcpStreamWrapper is dropped, which happens naturally
once both directions are done. TCP and QUIC transports are unaffected.

### stream_mode
kcp-tokio default (stream_mode=false / message mode) is preserved for
Normal, Fast, Turbo, and Gaming presets. Only FileTransfer explicitly
enables stream_mode=true (already done by KcpConfig::file_transfer()).
Message mode avoids unnecessary window-probe (WASK) packets that appear
as a flood of 24-byte UDP datagrams in tcpdump when stream_mode=true.

### Config extensions
- Transport enum: new Kcp variant
- ServerConfig, ClientConfig: new kcp_settings: Option<KcpSettings> field
- KcpSettings: mode, send_window, recv_window, mtu
- KcpMode: Normal | Fast | Turbo | Gaming | FileTransfer
- All existing test initialisers updated with kcp_settings: None

### main.rs
- tracing_subscriber wired up so kcp-tokio/kcp-core tracing events
  are visible via RUST_LOG=kcp_tokio=debug,kcp_core=debug
@ErQrYfkrju ErQrYfkrju marked this pull request as draft April 11, 2026 10:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant