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

Slice UDP packet with ArrayBuffer.slice #285

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
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
33 changes: 16 additions & 17 deletions src/worker-vless.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ export default {


/**
*
* @param {import("@cloudflare/workers-types").Request} request
*/
async function vlessOverWSHandler(request) {
Expand All @@ -78,7 +77,7 @@ async function vlessOverWSHandler(request) {
const readableWebSocketStream = makeReadableWebSocketStream(webSocket, earlyDataHeader, log);

/** @type {{ value: import("@cloudflare/workers-types").Socket | null}}*/
let remoteSocketWapper = {
const remoteSocketWapper = {
value: null,
};
let udpStreamWrite = null;
Expand Down Expand Up @@ -272,7 +271,7 @@ function makeReadableWebSocketStream(webSocketServer, earlyDataHeader, log) {

/**
*
* @param { ArrayBuffer} vlessBuffer
* @param {ArrayBuffer} vlessBuffer
* @param {string} userID
* @returns
*/
Expand Down Expand Up @@ -393,15 +392,15 @@ function processVlessHeader(
*
* @param {import("@cloudflare/workers-types").Socket} remoteSocket
* @param {import("@cloudflare/workers-types").WebSocket} webSocket
* @param {ArrayBuffer} vlessResponseHeader
* @param {Uint8Array} vlessResponseHeader
* @param {(() => Promise<void>) | null} retry
* @param {*} log
*/
async function remoteSocketToWS(remoteSocket, webSocket, vlessResponseHeader, retry, log) {
// remote--> ws
let remoteChunkCount = 0;
let chunks = [];
/** @type {ArrayBuffer | null} */
/** @type {Uint8Array | null} */
let vlessHeader = vlessResponseHeader;
let hasIncomingData = false; // check if remoteSocket has incoming data
await remoteSocket.readable
Expand All @@ -423,7 +422,7 @@ async function remoteSocketToWS(remoteSocket, webSocket, vlessResponseHeader, re
);
}
if (vlessHeader) {
webSocket.send(await new Blob([vlessHeader, chunk]).arrayBuffer());
webSocket.send(new Uint8Array([...vlessHeader, ...chunk]).buffer);
vlessHeader = null;
} else {
// seems no need rate limit this, CF seems fix this??..
Expand Down Expand Up @@ -524,7 +523,7 @@ function stringify(arr, offset = 0) {
/**
*
* @param {import("@cloudflare/workers-types").WebSocket} webSocket
* @param {ArrayBuffer} vlessResponseHeader
* @param {Uint8Array} vlessResponseHeader
* @param {(string)=> void} log
*/
async function handleUDPOutBound(webSocket, vlessResponseHeader, log) {
Expand All @@ -534,15 +533,17 @@ async function handleUDPOutBound(webSocket, vlessResponseHeader, log) {
start(controller) {

},
/**
* @param {ArrayBuffer} chunk
* @param {TransformStreamDefaultController<ArrayBuffer>} controller
*/
transform(chunk, controller) {
// udp message 2 byte is the the length of udp data
// TODO: this should have bug, beacsue maybe udp chunk can be in two websocket message
// TODO: this should have bug, because maybe udp chunk can be in two websocket message
for (let index = 0; index < chunk.byteLength;) {
const lengthBuffer = chunk.slice(index, index + 2);
const udpPakcetLength = new DataView(lengthBuffer).getUint16(0);
const udpData = new Uint8Array(
chunk.slice(index + 2, index + 2 + udpPakcetLength)
);
const udpData = chunk.slice(index + 2, index + 2 + udpPakcetLength)
index = index + 2 + udpPakcetLength;
controller.enqueue(udpData);
}
Expand All @@ -553,6 +554,7 @@ async function handleUDPOutBound(webSocket, vlessResponseHeader, log) {

// only handle dns udp for now
transformStream.readable.pipeTo(new WritableStream({
/**@param {ArrayBuffer} chunk*/
async write(chunk) {
const resp = await fetch('https://1.1.1.1/dns-query',
{
Expand All @@ -569,9 +571,9 @@ async function handleUDPOutBound(webSocket, vlessResponseHeader, log) {
if (webSocket.readyState === WS_READY_STATE_OPEN) {
log(`doh success and dns message length is ${udpSize}`);
if (isVlessHeaderSent) {
webSocket.send(await new Blob([udpSizeBuffer, dnsQueryResult]).arrayBuffer());
webSocket.send(udpSizeBuffer.buffer);
} else {
webSocket.send(await new Blob([vlessResponseHeader, udpSizeBuffer, dnsQueryResult]).arrayBuffer());
webSocket.send(udpSizeBuffer.buffer);
isVlessHeaderSent = true;
}
}
Expand All @@ -583,10 +585,7 @@ async function handleUDPOutBound(webSocket, vlessResponseHeader, log) {
const writer = transformStream.writable.getWriter();

return {
/**
*
* @param {Uint8Array} chunk
*/
/**@param {ArrayBuffer} chunk */
write(chunk) {
writer.write(chunk);
}
Expand Down