mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-07-16 12:59:39 +03:00
Skip kickWriteHandshake for server first protocols
This commit is contained in:
@@ -13,6 +13,7 @@ import (
|
|||||||
|
|
||||||
"github.com/sagernet/sing-box/adapter"
|
"github.com/sagernet/sing-box/adapter"
|
||||||
"github.com/sagernet/sing-box/common/dialer"
|
"github.com/sagernet/sing-box/common/dialer"
|
||||||
|
"github.com/sagernet/sing-box/common/sniff"
|
||||||
"github.com/sagernet/sing-box/common/tlsfragment"
|
"github.com/sagernet/sing-box/common/tlsfragment"
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
"github.com/sagernet/sing/common"
|
"github.com/sagernet/sing/common"
|
||||||
@@ -128,11 +129,12 @@ func (m *ConnectionManager) NewConnection(ctx context.Context, this N.Dialer, co
|
|||||||
if metadata.TLSFragment || metadata.TLSRecordFragment {
|
if metadata.TLSFragment || metadata.TLSRecordFragment {
|
||||||
remoteConn = tf.NewConn(remoteConn, ctx, metadata.TLSFragment, metadata.TLSRecordFragment, metadata.TLSFragmentFallbackDelay)
|
remoteConn = tf.NewConn(remoteConn, ctx, metadata.TLSFragment, metadata.TLSRecordFragment, metadata.TLSFragmentFallbackDelay)
|
||||||
}
|
}
|
||||||
|
serverFirst := sniff.Skip(&metadata)
|
||||||
var done atomic.Bool
|
var done atomic.Bool
|
||||||
if m.kickWriteHandshake(ctx, conn, remoteConn, false, &done, onClose) {
|
if m.kickWriteHandshake(ctx, conn, remoteConn, serverFirst, false, &done, onClose) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if m.kickWriteHandshake(ctx, remoteConn, conn, true, &done, onClose) {
|
if m.kickWriteHandshake(ctx, remoteConn, conn, serverFirst, true, &done, onClose) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
go m.connectionCopy(ctx, conn, remoteConn, false, &done, onClose)
|
go m.connectionCopy(ctx, conn, remoteConn, false, &done, onClose)
|
||||||
@@ -293,37 +295,43 @@ func (m *ConnectionManager) connectionCopy(ctx context.Context, source net.Conn,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ConnectionManager) kickWriteHandshake(ctx context.Context, source net.Conn, destination net.Conn, direction bool, done *atomic.Bool, onClose N.CloseHandlerFunc) bool {
|
func (m *ConnectionManager) kickWriteHandshake(ctx context.Context, source net.Conn, destination net.Conn, serverFirst bool, direction bool, done *atomic.Bool, onClose N.CloseHandlerFunc) bool {
|
||||||
if !N.NeedHandshakeForWrite(destination) {
|
if !N.NeedHandshakeForWrite(destination) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
cachedBuffer *buf.Buffer
|
err error
|
||||||
wrotePayload bool
|
wrotePayload bool
|
||||||
)
|
)
|
||||||
sourceReader, readCounters := N.UnwrapCountReader(source, nil)
|
if serverFirst {
|
||||||
destinationWriter, writeCounters := N.UnwrapCountWriter(destination, nil)
|
|
||||||
if cachedReader, ok := sourceReader.(N.CachedReader); ok {
|
|
||||||
cachedBuffer = cachedReader.ReadCached()
|
|
||||||
}
|
|
||||||
var err error
|
|
||||||
if cachedBuffer != nil {
|
|
||||||
wrotePayload = true
|
|
||||||
dataLen := cachedBuffer.Len()
|
|
||||||
_, err = destinationWriter.Write(cachedBuffer.Bytes())
|
|
||||||
cachedBuffer.Release()
|
|
||||||
if err == nil {
|
|
||||||
for _, counter := range readCounters {
|
|
||||||
counter(int64(dataLen))
|
|
||||||
}
|
|
||||||
for _, counter := range writeCounters {
|
|
||||||
counter(int64(dataLen))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
_ = destination.SetWriteDeadline(time.Now().Add(C.ReadPayloadTimeout))
|
_ = destination.SetWriteDeadline(time.Now().Add(C.ReadPayloadTimeout))
|
||||||
_, err = destinationWriter.Write(nil)
|
_, err = destination.Write(nil)
|
||||||
_ = destination.SetWriteDeadline(time.Time{})
|
_ = destination.SetWriteDeadline(time.Time{})
|
||||||
|
} else {
|
||||||
|
var cachedBuffer *buf.Buffer
|
||||||
|
sourceReader, readCounters := N.UnwrapCountReader(source, nil)
|
||||||
|
destinationWriter, writeCounters := N.UnwrapCountWriter(destination, nil)
|
||||||
|
if cachedReader, ok := sourceReader.(N.CachedReader); ok {
|
||||||
|
cachedBuffer = cachedReader.ReadCached()
|
||||||
|
}
|
||||||
|
if cachedBuffer != nil {
|
||||||
|
wrotePayload = true
|
||||||
|
dataLen := cachedBuffer.Len()
|
||||||
|
_, err = destinationWriter.Write(cachedBuffer.Bytes())
|
||||||
|
cachedBuffer.Release()
|
||||||
|
if err == nil {
|
||||||
|
for _, counter := range readCounters {
|
||||||
|
counter(int64(dataLen))
|
||||||
|
}
|
||||||
|
for _, counter := range writeCounters {
|
||||||
|
counter(int64(dataLen))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_ = destination.SetWriteDeadline(time.Now().Add(C.ReadPayloadTimeout))
|
||||||
|
_, err = destinationWriter.Write(nil)
|
||||||
|
_ = destination.SetWriteDeadline(time.Time{})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return false
|
return false
|
||||||
|
|||||||
Reference in New Issue
Block a user