Optional TLS Record fragmentation
A user writes,
TLS record fragmentation is unprivileged and easy to implement (blog, code).
An reference patch for simple-socks:
--- a/src/socks5.js
+++ b/src/socks5.js
@@ -11,6 +11,50 @@
import binary from 'binary';
import domain from 'domain';
import net from 'net';
+import stream from 'stream';
+
+function isClientHello(a){
+ if((a[0]<<16|a[1]<<8|a[2])===0x160301){
+ if((a[3]<<8|a[4])===(a.length-5)){
+ if(a[5]===0x01){
+ return true
+ }
+ }
+ }
+ return false
+}
+/**
+ * @param {Buffer} chunk
+ * @returns {Buffer}
+ */
+function split(chunk){
+ const head=chunk.subarray(0,3)
+ //const size=Math.ceil((chunk.length-5)/2)
+ const size=1
+ const record1=chunk.subarray(5,5+size)
+ const record2=chunk.subarray(5+size)
+
+ let largeB=Buffer.alloc(chunk.length+5)
+ head.copy(largeB)
+ largeB.writeUInt16BE(size,3)
+ record1.copy(largeB,5)
+
+ head.copy(largeB,5+size)
+ largeB.writeUInt16BE(record2.length,5+3+size)
+ record2.copy(largeB,5+3+size+2)
+ return largeB
+}
+
+class haha extends stream.Transform{
+ _transform(chunk,encoding,cb){
+ if(isClientHello(chunk)){
+ this.push(split(chunk))
+ }else{
+ this.push(chunk)
+ }
+ cb()
+ }
+}
// module specific events
const
@@ -248,7 +292,8 @@
socket.write(responseBuffer, () => {
// listen for data bi-directionally
destination.pipe(socket);
- socket.pipe(destination);
+ let t=new haha()
+ socket.pipe(t).pipe(destination);
});
}),
destinationInfo = {
this strategy may break some TLS implementations, so I'd like a switch in settings.
@ignoramous 🤔Outline-sdk contains a flexible (but complex) dialer that supports TLS Record fragmentation. Will you integrate that dialer or write a simpler dialer?
Yes, we should implement all possible censorship bypass techniques possible without root / requiring a proxy.
Also: github/Jigsaw-Code/Intra@ede31e60 / mirror.
UI changes pending.