How CFnew Uses the Cloudflare Workers `cloudflare:sockets` API for TCP Proxying
CFnew imports connect from cloudflare:sockets to open raw TCP connections from within a Cloudflare Worker, enabling bidirectional data streaming between client WebSockets and remote ProxyIP servers.
CFnew is an open‑source Cloudflare Worker script (byJoey/cfnew) that proxies VLESS, Trojan, and xhttp traffic by bridging WebSocket connections to backend TCP servers. Because standard Workers cannot initiate raw TCP connections, the project leverages the native cloudflare:sockets API to establish low‑latency outbound sockets required for transparent traffic forwarding.
Importing the Sockets API in the Main Worker File
The socket functionality is initialized at the very top of the main source file 明文源吗 with a direct ES module import:
import { connect } from 'cloudflare:sockets';
This single import is the only Cloudflare‑specific dependency in the codebase. All other networking logic—region selection, KV configuration, and protocol handling—is pure JavaScript that executes inside the Worker runtime.
Resolving the Target Address
Before opening a socket, CFnew determines the destination ProxyIP using several helper functions defined in the same file:
detectWorkerRegion– Identifies the geographic region of the incoming request.getBestBackupIP– Selects a fallback IP when the primary is unreachable.getSmartRegionSelection– Implements latency‑based routing logic.parseAddressAndPort– Extracts hostname and port from configuration strings.
These functions compute a target address such as ProxyIP.HK.CMLiussss.net on port 443, which is then passed to the socket constructor.
Opening Raw TCP Connections with connect
When the worker receives a WebSocket upgrade request, the private handleWsRequest function invokes the Sockets API to establish the outbound tunnel:
const outbound = await connect(address, port);
The connect method returns a bidirectional TCP stream that the Worker uses to communicate with the remote server. To prevent the socket from closing prematurely, CFnew registers it with the request context:
ctx.waitUntil(outbound.closed);
This ensures the underlying socket remains alive for the duration of the session, even if the initial fetch promise resolves.
Piping Data Between WebSocket and TCP Socket
CFnew acts as a transparent proxy by streaming data in both directions between the client WebSocket (ws) and the outbound TCP socket:
await Promise.all([
pipeTo(ws.readable, outbound.writable), // Client → Remote
pipeTo(outbound.readable, ws.writable), // Remote → Client
]);
This piping architecture allows the Worker to forward arbitrary TCP traffic—including TLS handshakes and application‑layer data—without inspecting or buffering the payload.
SOCKS5 Fallback and TLS Handling
For environments where direct TCP egress is restricted, CFnew implements a SOCKS5 fallback mechanism. If the initial connect call throws an error, the script catches the exception and attempts a proxied connection:
let outbound;
try {
outbound = await connect(address, port);
} catch (e) {
if (isSocksEnabled) {
outbound = await connectSocks5(parsedSocks5Config, address, port);
} else {
throw e;
}
}
The script also respects the disableNonTLS flag, ensuring that only TLS‑wrapped connections are permitted when the configuration demands it. Error conditions such as E_WS_NOT_OPEN or E_SOCKS_CONN_FAIL are caught and converted into HTTP 500 responses, providing clear feedback to the client.
Required Configuration in wrangler.toml
To enable the Sockets API, the deployment configuration must declare the workers-sockets binding. In the repository’s [wrangler.toml](https://github.com/byJoey/cfnew/blob/main/wrangler.toml), this permission is specified so the runtime allows raw TCP egress.
Without this binding, the import statement would fail at deploy time, making the entry file 明文源吗 unloadable.
Summary
- CFnew imports
connectfromcloudflare:socketsin明文源吗to open raw TCP connections from within a Worker. - Target selection uses
detectWorkerRegion,getBestBackupIP, andparseAddressAndPortto resolve ProxyIP addresses. - The
handleWsRequestfunction pipes data bidirectionally between the client WebSocket and the outbound socket usingws.readable,outbound.writable, andpipeTo. ctx.waitUntil(outbound.closed)keeps the socket alive for the full session duration.- SOCKS5 fallback via
connectSocks5and error codes likeE_SOCKS_CONN_FAILprovide resilience when direct connections fail. - The
wrangler.tomlfile must include theworkers-socketsbinding to authorize TCP egress.
Frequently Asked Questions
What is the cloudflare:sockets API?
The cloudflare:sockets API is a native Workers runtime module that exposes the connect function for opening raw TCP connections. It allows JavaScript running in a Worker to establish outbound sockets to arbitrary IP addresses and ports, bypassing the traditional HTTP‑only fetch interface.
Why does CFnew need raw TCP sockets?
CFnew functions as a proxy that forwards traffic from client WebSockets to backend VLESS or Trojan servers (ProxyIPs). These protocols require native TCP transport rather than HTTP. By using connect, the Worker can stream opaque binary data directly to the destination without terminating TLS or parsing the application layer.
How does CFnew handle connection failures?
When connect rejects, CFnew checks if SOCKS5 is enabled via the socks5Config variable. If enabled, it attempts a fallback connection through connectSocks5. If disabled, it propagates the error and returns an HTTP 500 response with error codes like E_WS_NOT_OPEN or E_SOCKS_CONN_FAIL to aid debugging.
Where is the main socket logic located?
The primary implementation resides in the file named 明文源吗. An obfuscated version with identical logic is available in 少年你相信光吗, and minimal examples are stored in the snippets/ directory.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →