From bcb4b6b7351c8fa194e6b3426f13fc617de2243c Mon Sep 17 00:00:00 2001 From: yuhan6665 <1588741+yuhan6665@users.noreply.github.com> Date: Wed, 4 Sep 2024 00:06:51 -0400 Subject: [PATCH] Experiment: seed ignore buffer and send 1st fake packet instantly --- proxy/proxy.go | 14 ++++----- proxy/scheduler.go | 55 ++++++++++++++++++++++++++-------- proxy/vless/encoding/addons.go | 10 +++---- 3 files changed, 54 insertions(+), 25 deletions(-) diff --git a/proxy/proxy.go b/proxy/proxy.go index b39c70051e76..a69148bb33bd 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -206,7 +206,7 @@ type VisionWriter struct { addons *Addons trafficState *TrafficState ctx context.Context - writeOnceUserUUID []byte + writeOnceUserUUID *[]byte scheduler *Scheduler } @@ -218,8 +218,8 @@ func NewVisionWriter(writer buf.Writer, addon *Addons, state *TrafficState, cont addons: addon, trafficState: state, ctx: context, - writeOnceUserUUID: w, - scheduler: NewScheduler(writer, addon, state, context), + writeOnceUserUUID: &w, + scheduler: NewScheduler(writer, addon, state, &w, context), } } @@ -230,7 +230,7 @@ func (w *VisionWriter) WriteMultiBuffer(mb buf.MultiBuffer) error { } if w.trafficState.IsPadding && ShouldStartSeed(w.addons, w.trafficState){ if len(mb) == 1 && mb[0] == nil { - mb[0] = XtlsPadding(nil, CommandPaddingContinue, &w.writeOnceUserUUID, true, w.addons, w.ctx) // we do a long padding to hide vless header + mb[0] = XtlsPadding(nil, CommandPaddingContinue, w.writeOnceUserUUID, true, w.addons, w.ctx) // we do a long padding to hide vless header } else { mb = ReshapeMultiBuffer(w.ctx, mb) longPadding := w.trafficState.IsTLS @@ -249,12 +249,12 @@ func (w *VisionWriter) WriteMultiBuffer(mb buf.MultiBuffer) error { w.trafficState.IsPadding = false } } - mb[i] = XtlsPadding(b, command, &w.writeOnceUserUUID, true, w.addons, w.ctx) + mb[i] = XtlsPadding(b, command, w.writeOnceUserUUID, true, w.addons, w.ctx) longPadding = false continue } else if !w.trafficState.IsTLS12orAbove && ShouldStopSeed(w.addons, w.trafficState) { w.trafficState.IsPadding = false - mb[i] = XtlsPadding(b, CommandPaddingEnd, &w.writeOnceUserUUID, longPadding, w.addons, w.ctx) + mb[i] = XtlsPadding(b, CommandPaddingEnd, w.writeOnceUserUUID, longPadding, w.addons, w.ctx) break } var command byte = CommandPaddingContinue @@ -264,7 +264,7 @@ func (w *VisionWriter) WriteMultiBuffer(mb buf.MultiBuffer) error { command = CommandPaddingDirect } } - mb[i] = XtlsPadding(b, command, &w.writeOnceUserUUID, longPadding, w.addons, w.ctx) + mb[i] = XtlsPadding(b, command, w.writeOnceUserUUID, longPadding, w.addons, w.ctx) } } } diff --git a/proxy/scheduler.go b/proxy/scheduler.go index dec1f4be7e26..24c59888d500 100644 --- a/proxy/scheduler.go +++ b/proxy/scheduler.go @@ -12,25 +12,29 @@ import ( ) type Scheduler struct { - Buffer chan buf.MultiBuffer - Trigger chan int - Error chan error - bufferReadLock *sync.Mutex - writer buf.Writer - addons *Addons - trafficState *TrafficState - ctx context.Context + Buffer chan buf.MultiBuffer + Trigger chan int + Error chan error + closed chan int + bufferReadLock *sync.Mutex + writer buf.Writer + addons *Addons + trafficState *TrafficState + writeOnceUserUUID *[]byte + ctx context.Context } -func NewScheduler(w buf.Writer, addon *Addons, state *TrafficState, context context.Context) *Scheduler { +func NewScheduler(w buf.Writer, addon *Addons, state *TrafficState, userUUID *[]byte, context context.Context) *Scheduler { var s = Scheduler{ Buffer: make(chan buf.MultiBuffer, 100), Trigger: make(chan int), Error: make(chan error, 100), + closed: make(chan int), bufferReadLock: new(sync.Mutex), writer: w, addons: addon, trafficState: state, + writeOnceUserUUID: userUUID, ctx: context, } go s.mainLoop() @@ -42,6 +46,9 @@ func NewScheduler(w buf.Writer, addon *Addons, state *TrafficState, context cont func(s *Scheduler) mainLoop() { for trigger := range s.Trigger { + if len(s.closed) > 0 { + return + } go func() { // each trigger has independent delay, trigger does not block var d = 0 * time.Millisecond if s.addons.Delay != nil { @@ -58,12 +65,31 @@ func(s *Scheduler) mainLoop() { if sending > 0 { errors.LogDebug(s.ctx, "Scheduler Trigger for ", sending, " buffer(s) with ", d, " ", trigger) for i := 0; i 0 { + } else if trigger > 0 && s.trafficState.IsPadding && ShouldStartSeed(s.addons, s.trafficState) && !ShouldStopSeed(s.addons, s.trafficState) { errors.LogDebug(s.ctx, "Scheduler Trigger for fake buffer with ", d, " ", trigger) + s.trafficState.NumberOfPacketSent += 1 mb := make(buf.MultiBuffer, 1) - s.Error <- s.writer.WriteMultiBuffer(mb) + mb[0] = XtlsPadding(nil, CommandPaddingContinue, s.writeOnceUserUUID, true, s.addons, s.ctx) + s.trafficState.ByteSent += int64(mb.Len()) + if s.trafficState.StartTime.IsZero() { + s.trafficState.StartTime = time.Now() + } + err := s.writer.WriteMultiBuffer(mb) + if err != nil { + s.Error <- err + s.closed <- 1 + return + } + if buffered, ok := s.writer.(*buf.BufferedWriter); ok { + buffered.SetBuffered(false) + } } s.bufferReadLock.Unlock() }() @@ -72,7 +98,10 @@ func(s *Scheduler) mainLoop() { func(s *Scheduler) exampleIndependentScheduler() { for { - time.Sleep(500 * time.Millisecond) + if len(s.closed) > 0 { + return + } s.Trigger <- 1 // send fake buffer if no pending + time.Sleep(500 * time.Millisecond) } } diff --git a/proxy/vless/encoding/addons.go b/proxy/vless/encoding/addons.go index 403ffe299341..feee6e87ffcc 100644 --- a/proxy/vless/encoding/addons.go +++ b/proxy/vless/encoding/addons.go @@ -189,11 +189,11 @@ func PopulateSeed(seed string, addons *proxy.Addons) { LongMin: 900, LongMax: 1400, } - addons.Delay = &proxy.DelayConfig{ - IsRandom: true, - MinMillis: 100, - MaxMillis: 500, - } + // addons.Delay = &proxy.DelayConfig{ + // IsRandom: true, + // MinMillis: 100, + // MaxMillis: 500, + // } addons.Scheduler = &proxy.SchedulerConfig{ TimeoutMillis: 600, }