Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Major update: port mapping, vless outbound, and more #190

Open
wants to merge 44 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
23eb8b7
Abstract worker-vless.js, create launcher for node
Jun 27, 2023
c7ee1a0
Fix indentation
Jun 27, 2023
0a6d83a
Move NodeJS launcher to a separated folder
Jun 27, 2023
d7cf50e
Archieve worker-vless.js and prepare to revert
Jun 27, 2023
30c01a8
Abstract socks5 version
Jun 27, 2023
7b9b464
Better logging
Jun 27, 2023
40100e1
Revert worker-vless.js
Jun 27, 2023
6869e32
Introduce fallback and globalConfig
Jun 28, 2023
3e70643
Add fallback and code clean up
Jun 28, 2023
00f4d39
Better websocket close logic
Jun 28, 2023
eaeb94a
Fix tryOutbound
Jun 28, 2023
6dad634
Add vless header maker
Jun 28, 2023
2e4208f
Impl Vless client without error handling
Jun 28, 2023
c69f300
Add some error handling to vless
Jun 28, 2023
7adaeef
Add Vless string parser
Jun 28, 2023
89a5bc9
Better Vless outbound
Jun 29, 2023
d1c4fca
More comments
Jun 29, 2023
f6eecad
Fix vless on workers
Jun 29, 2023
6a1ae11
Allowing the worker to push log to a remote server
Jun 30, 2023
7637d59
Support UDP tunneling via vless
Jul 1, 2023
29542c5
Add UDP outbound support if run on node
Jul 3, 2023
e54a093
Support IPv6 UDP outbound
Jul 3, 2023
f8434ba
Simply DNS over TCP implementation
Jul 6, 2023
85301ea
Fix indentation
Jul 9, 2023
54734bd
Fix UDP outbound on discontinued streams
Jul 10, 2023
d0ce27a
Fix DNS over TCP
Jul 10, 2023
a88b9fb
Use Uint8Array throughout the code
Jul 16, 2023
2dbb1cf
Fix earlydata
rikkagcp1 Jul 16, 2023
a63c7d3
Remove the use of Blob
Jul 17, 2023
217ddb3
better shadowrocket compatiblity
Jul 25, 2023
ad473ba
Code clean-up
Jul 25, 2023
d171ec9
More clean up
Jul 25, 2023
1c64027
Less verbose log
Jul 25, 2023
a58b6b2
More code clean up
Jul 25, 2023
ead7a93
Massive code clean-up, add type annotations.
Dec 1, 2023
3d332fb
Restore worker-with-socks5-experimental.js
Dec 1, 2023
6988af0
Add websocket message processor
Dec 2, 2023
9527803
Delay the instantiation of response processor
Dec 2, 2023
d69aad5
Add deno support, improve node support
Dec 3, 2023
dd33548
Fix IPv6 UDP on deno
Dec 3, 2023
c2334b2
Fix IPv6 inbound
Dec 6, 2023
41a7e75
Move type definition, better outbound impl
Dec 12, 2023
06334a4
Fix no 0rtt
Dec 12, 2023
43c2330
Fix zero-length earlyData handling
Dec 12, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
More comments
rikkagcp1 committed Jun 29, 2023
commit d1c4fcadbd03674c3e073d86ded338cfd2c52316
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -5,3 +5,4 @@ node_modules
*.log
dist
src/package.json
node/config.js
24 changes: 21 additions & 3 deletions node/index.js
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ import http from 'http';
import net from 'net';
import WebSocket from 'ws';

import {globalConfig, vlessOverWSHandler, platformAPI, getVLESSConfig} from '../src/worker-with-socks5-experimental.js';
import {globalConfig, platformAPI, setConfigFromEnv, vlessOverWSHandler, getVLESSConfig} from '../src/worker-with-socks5-experimental.js';

// Create an HTTP server
const server = http.createServer((req, res) => {
@@ -51,6 +51,7 @@ function buf2hex(buffer) { // buffer is an ArrayBuffer
*/
platformAPI.connect = async (address, port, useTLS) => {
const socket = net.createConnection(port, address);
// TODO: Implement TLS support?

let readableStreamCancel = false;
const readableStream = new ReadableStream({
@@ -126,5 +127,22 @@ platformAPI.connect = async (address, port, useTLS) => {

platformAPI.newWebSocket = (url) => new WebSocket(url);

import {customConfig} from './config.js';
globalConfig.outbounds = customConfig.outbounds;
async function loadModule() {
try {
const customConfig = await import('./config.js');

if (customConfig.useCustomOutbound) {
globalConfig.outbounds = customConfig.outbounds;
} else {
setConfigFromEnv(customConfig.env);
if (customConfig.forceProxy) {
globalConfig.outbounds = globalConfig.outbounds.filter(obj => obj.protocol !== "freedom");
}
}
console.log(JSON.stringify(globalConfig.outbounds));
} catch (err) {
console.error('Failed to load the module', err);
}
}

loadModule();
2 changes: 1 addition & 1 deletion node/setup.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#!/bin/sh
npm install ws
echo '{"type": "module"}' > ../src/package.json
echo '{"type": "module"}' > ../src/package.json
25 changes: 17 additions & 8 deletions src/worker-with-socks5-experimental.js
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@

// How to generate your own UUID:
// [Windows] Press "Win + R", input cmd and run: Powershell -NoExit -Command "[guid]::NewGuid()"
// [Linux] Run uuidgen in terminal
export let globalConfig = {
userID: 'd342d11e-d424-4583-b36e-524ab1f0afa4',

@@ -13,9 +14,11 @@ export let globalConfig = {
]
};

// If you use this file as an ES module, you should set all fields below.
export let platformAPI = {
/**
* A wrapper for the TCP API, should return a Cloudflare Worker compatible socket.
* The result is wrapped in a Promise, as in some platforms, the socket creation is async.
* See: https://developers.cloudflare.com/workers/runtime-apis/tcp-sockets/
* @type {(host: string, port: number, log: function) => Promise<
* {
@@ -106,10 +109,10 @@ function getOutbound(curPos) {
* This is the simplest case and should be preferred where possible.
* @param {{
* UUID: string,
* PROXYIP: string,
* PORTMAP: string,
* VLESS: string,
* SOCKS5: string
* PROXYIP: string, // E.g. 114.51.4.0
* PORTMAP: string, // E.g. {443:8443}
* VLESS: string, // E.g. vless://[email protected]:port?type=ws&security=tls
* SOCKS5: string // E.g. user:pass@host:port or host:port
* }} env
*/
export function setConfigFromEnv(env) {
@@ -225,6 +228,7 @@ export function setConfigFromEnv(env) {
}
}

// Cloudflare Workers entry
export default {
/**
* @param {import("@cloudflare/workers-types").Request} request
@@ -288,6 +292,8 @@ try {
}

/**
* If you use this file as an ES module, you call this function whenever your Websocket server accepts a new connection.
*
* @param {WebSocket} webSocket The established websocket connection to the client, must be an accepted
* @param {string} earlyDataHeader for ws 0rtt, an optional field "sec-websocket-protocol" in the request header
* may contain some base64 encoded data.
@@ -319,7 +325,10 @@ export function vlessOverWSHandler(webSocket, earlyDataHeader) {
if (isDns) {
return await handleDNSQuery(chunk, webSocket, null, log);
}

if (remoteSocketWapper.writableStream) {
// After we parse the header and send the first chunk to the remote destination
// We assume that after the handshake, the stream only contains the original traffic.
const writer = remoteSocketWapper.writableStream.getWriter();
await writer.write(chunk);
writer.releaseLock();
@@ -766,10 +775,10 @@ function processVlessHeader(


/**
*
* @param {ReadableStream} remoteSocketReader
* @param {import("@cloudflare/workers-types").WebSocket} webSocket
* @param {ArrayBuffer} vlessResponseHeader
* Stream data from the remote destination (any) to the client side (Websocket)
* @param {ReadableStream} remoteSocketReader from the remote destination
* @param {import("@cloudflare/workers-types").WebSocket} webSocket to the client side
* @param {ArrayBuffer} vlessResponseHeader header that should be send to the client side
* @param {(() => Promise<void>) | null} retry
* @param {*} log
*/