Dokodemo TPROXY: Interrupt UDP download if upload timeouts

https://github.com/XTLS/Xray-core/issues/4194#issuecomment-2564156340

Fixes https://github.com/XTLS/Xray-core/issues/4194
This commit is contained in:
RPRX 2024-12-28 04:06:49 +00:00 committed by GitHub
parent 42aea01fb5
commit a8559a1b46
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -2,6 +2,7 @@ package dokodemo
import ( import (
"context" "context"
"runtime"
"sync/atomic" "sync/atomic"
"github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common"
@ -147,10 +148,6 @@ func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn st
return nil return nil
} }
tproxyRequest := func() error {
return nil
}
var writer buf.Writer var writer buf.Writer
if network == net.Network_TCP { if network == net.Network_TCP {
writer = buf.NewWriter(conn) writer = buf.NewWriter(conn)
@ -180,7 +177,12 @@ func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn st
return err return err
} }
writer = NewPacketWriter(pConn, &dest, mark, back) writer = NewPacketWriter(pConn, &dest, mark, back)
defer writer.(*PacketWriter).Close() defer func() {
runtime.Gosched()
common.Interrupt(link.Reader) // maybe duplicated
runtime.Gosched()
writer.(*PacketWriter).Close() // close fake UDP conns
}()
/* /*
sockopt := &internet.SocketConfig{ sockopt := &internet.SocketConfig{
Tproxy: internet.SocketConfig_TProxy, Tproxy: internet.SocketConfig_TProxy,
@ -219,17 +221,24 @@ func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn st
responseDone := func() error { responseDone := func() error {
defer timer.SetTimeout(plcy.Timeouts.UplinkOnly) defer timer.SetTimeout(plcy.Timeouts.UplinkOnly)
if network == net.Network_UDP && destinationOverridden {
buf.Copy(link.Reader, writer) // respect upload's timeout
return nil
}
if err := buf.Copy(link.Reader, writer, buf.UpdateActivity(timer)); err != nil { if err := buf.Copy(link.Reader, writer, buf.UpdateActivity(timer)); err != nil {
return errors.New("failed to transport response").Base(err) return errors.New("failed to transport response").Base(err)
} }
return nil return nil
} }
if err := task.Run(ctx, task.OnSuccess(func() error { if err := task.Run(ctx,
return task.Run(ctx, requestDone, tproxyRequest) task.OnSuccess(func() error { return task.Run(ctx, requestDone) }, task.Close(link.Writer)),
}, task.Close(link.Writer)), responseDone); err != nil { responseDone); err != nil {
common.Interrupt(link.Reader) runtime.Gosched()
common.Interrupt(link.Writer) common.Interrupt(link.Writer)
runtime.Gosched()
common.Interrupt(link.Reader)
return errors.New("connection ends").Base(err) return errors.New("connection ends").Base(err)
} }