* Handles outbound TCP connections. * * @param {any} remoteSocket * @param {string} addressRemote The remote address to connect to. * @param {number} portRemote The remote port to connect to. * @param {Uint8Array} rawClientData The raw client data to write. * @param {import("@cloudflare/worke
(remoteSocket, addressRemote, portRemote, rawClientData, webSocket, vlessResponseHeader, log,)
| 267 | * @returns {Promise<void>} The remote socket. |
| 268 | */ |
| 269 | async function handleTCPOutBound(remoteSocket, addressRemote, portRemote, rawClientData, webSocket, vlessResponseHeader, log,) { |
| 270 | |
| 271 | /** |
| 272 | * Connects to a given address and port and writes data to the socket. |
| 273 | * @param {string} address The address to connect to. |
| 274 | * @param {number} port The port to connect to. |
| 275 | * @returns {Promise<import("@cloudflare/workers-types").Socket>} A Promise that resolves to the connected socket. |
| 276 | */ |
| 277 | async function connectAndWrite(address, port) { |
| 278 | /** @type {import("@cloudflare/workers-types").Socket} */ |
| 279 | const tcpSocket = connect({ |
| 280 | hostname: address, |
| 281 | port: port, |
| 282 | }); |
| 283 | remoteSocket.value = tcpSocket; |
| 284 | log(`connected to ${address}:${port}`); |
| 285 | const writer = tcpSocket.writable.getWriter(); |
| 286 | await writer.write(rawClientData); // first write, nomal is tls client hello |
| 287 | writer.releaseLock(); |
| 288 | return tcpSocket; |
| 289 | } |
| 290 | |
| 291 | /** |
| 292 | * Retries connecting to the remote address and port if the Cloudflare socket has no incoming data. |
| 293 | * @returns {Promise<void>} A Promise that resolves when the retry is complete. |
| 294 | */ |
| 295 | async function retry() { |
| 296 | const tcpSocket = await connectAndWrite(proxyIP || addressRemote, portRemote) |
| 297 | tcpSocket.closed.catch(error => { |
| 298 | console.log('retry tcpSocket closed error', error); |
| 299 | }).finally(() => { |
| 300 | safeCloseWebSocket(webSocket); |
| 301 | }) |
| 302 | remoteSocketToWS(tcpSocket, webSocket, vlessResponseHeader, null, log); |
| 303 | } |
| 304 | |
| 305 | const tcpSocket = await connectAndWrite(addressRemote, portRemote); |
| 306 | |
| 307 | // when remoteSocket is ready, pass to websocket |
| 308 | // remote--> ws |
| 309 | remoteSocketToWS(tcpSocket, webSocket, vlessResponseHeader, retry, log); |
| 310 | } |
| 311 | |
| 312 | /** |
| 313 | * Creates a readable stream from a WebSocket server, allowing for data to be read from the WebSocket. |
no test coverage detected