Experiment: seed ignore buffer and send 1st fake packet instantly

This commit is contained in:
yuhan6665 2024-09-04 00:06:51 -04:00
parent c0619e390a
commit 80ce4a20f6
3 changed files with 54 additions and 25 deletions

View File

@ -215,7 +215,7 @@ type VisionWriter struct {
addons *Addons addons *Addons
trafficState *TrafficState trafficState *TrafficState
ctx context.Context ctx context.Context
writeOnceUserUUID []byte writeOnceUserUUID *[]byte
scheduler *Scheduler scheduler *Scheduler
} }
@ -227,8 +227,8 @@ func NewVisionWriter(writer buf.Writer, addon *Addons, state *TrafficState, cont
addons: addon, addons: addon,
trafficState: state, trafficState: state,
ctx: context, ctx: context,
writeOnceUserUUID: w, writeOnceUserUUID: &w,
scheduler: NewScheduler(writer, addon, state, context), scheduler: NewScheduler(writer, addon, state, &w, context),
} }
} }
@ -239,7 +239,7 @@ func (w *VisionWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
} }
if w.trafficState.IsPadding && ShouldStartSeed(w.addons, w.trafficState){ if w.trafficState.IsPadding && ShouldStartSeed(w.addons, w.trafficState){
if len(mb) == 1 && mb[0] == nil { 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 { } else {
mb = ReshapeMultiBuffer(w.ctx, mb) mb = ReshapeMultiBuffer(w.ctx, mb)
longPadding := w.trafficState.IsTLS longPadding := w.trafficState.IsTLS
@ -258,12 +258,12 @@ func (w *VisionWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
w.trafficState.IsPadding = false 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 longPadding = false
continue continue
} else if !w.trafficState.IsTLS12orAbove && ShouldStopSeed(w.addons, w.trafficState) { } else if !w.trafficState.IsTLS12orAbove && ShouldStopSeed(w.addons, w.trafficState) {
w.trafficState.IsPadding = false 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 break
} }
var command byte = CommandPaddingContinue var command byte = CommandPaddingContinue
@ -273,7 +273,7 @@ func (w *VisionWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
command = CommandPaddingDirect 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)
} }
} }
} }

View File

@ -12,25 +12,29 @@ import (
) )
type Scheduler struct { type Scheduler struct {
Buffer chan buf.MultiBuffer Buffer chan buf.MultiBuffer
Trigger chan int Trigger chan int
Error chan error Error chan error
bufferReadLock *sync.Mutex closed chan int
writer buf.Writer bufferReadLock *sync.Mutex
addons *Addons writer buf.Writer
trafficState *TrafficState addons *Addons
ctx context.Context 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{ var s = Scheduler{
Buffer: make(chan buf.MultiBuffer, 100), Buffer: make(chan buf.MultiBuffer, 100),
Trigger: make(chan int), Trigger: make(chan int),
Error: make(chan error, 100), Error: make(chan error, 100),
closed: make(chan int),
bufferReadLock: new(sync.Mutex), bufferReadLock: new(sync.Mutex),
writer: w, writer: w,
addons: addon, addons: addon,
trafficState: state, trafficState: state,
writeOnceUserUUID: userUUID,
ctx: context, ctx: context,
} }
go s.mainLoop() go s.mainLoop()
@ -42,6 +46,9 @@ func NewScheduler(w buf.Writer, addon *Addons, state *TrafficState, context cont
func(s *Scheduler) mainLoop() { func(s *Scheduler) mainLoop() {
for trigger := range s.Trigger { for trigger := range s.Trigger {
if len(s.closed) > 0 {
return
}
go func() { // each trigger has independent delay, trigger does not block go func() { // each trigger has independent delay, trigger does not block
var d = 0 * time.Millisecond var d = 0 * time.Millisecond
if s.addons.Delay != nil { if s.addons.Delay != nil {
@ -58,12 +65,31 @@ func(s *Scheduler) mainLoop() {
if sending > 0 { if sending > 0 {
errors.LogDebug(s.ctx, "Scheduler Trigger for ", sending, " buffer(s) with ", d, " ", trigger) errors.LogDebug(s.ctx, "Scheduler Trigger for ", sending, " buffer(s) with ", d, " ", trigger)
for i := 0; i<sending; i++ { for i := 0; i<sending; i++ {
s.Error <- s.writer.WriteMultiBuffer(<-s.Buffer) err := s.writer.WriteMultiBuffer(<-s.Buffer)
if err != nil {
s.Error <- err
s.closed <- 1
return
}
} }
} else if trigger > 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) errors.LogDebug(s.ctx, "Scheduler Trigger for fake buffer with ", d, " ", trigger)
s.trafficState.NumberOfPacketSent += 1
mb := make(buf.MultiBuffer, 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() s.bufferReadLock.Unlock()
}() }()
@ -72,7 +98,10 @@ func(s *Scheduler) mainLoop() {
func(s *Scheduler) exampleIndependentScheduler() { func(s *Scheduler) exampleIndependentScheduler() {
for { for {
time.Sleep(500 * time.Millisecond) if len(s.closed) > 0 {
return
}
s.Trigger <- 1 // send fake buffer if no pending s.Trigger <- 1 // send fake buffer if no pending
time.Sleep(500 * time.Millisecond)
} }
} }

View File

@ -189,11 +189,11 @@ func PopulateSeed(seed string, addons *proxy.Addons) {
LongMin: 900, LongMin: 900,
LongMax: 1400, LongMax: 1400,
} }
addons.Delay = &proxy.DelayConfig{ // addons.Delay = &proxy.DelayConfig{
IsRandom: true, // IsRandom: true,
MinMillis: 100, // MinMillis: 100,
MaxMillis: 500, // MaxMillis: 500,
} // }
addons.Scheduler = &proxy.SchedulerConfig{ addons.Scheduler = &proxy.SchedulerConfig{
TimeoutMillis: 600, TimeoutMillis: 600,
} }