mirror of
https://github.com/XTLS/Xray-core.git
synced 2025-03-14 10:30:43 +00:00
Mux server: Clone the session.Content attached on ctx as well
https://github.com/XTLS/Xray-core/pull/3908#issuecomment-2696911994 Fixes https://github.com/XTLS/Xray-core/pull/3904 for good
This commit is contained in:
parent
dde0a4f272
commit
16eee1b89c
@ -324,6 +324,7 @@ func (w *udpWorker) callback(b *buf.Buffer, source net.Destination, originalDest
|
|||||||
if w.sniffingConfig != nil {
|
if w.sniffingConfig != nil {
|
||||||
content.SniffingRequest.Enabled = w.sniffingConfig.Enabled
|
content.SniffingRequest.Enabled = w.sniffingConfig.Enabled
|
||||||
content.SniffingRequest.OverrideDestinationForProtocol = w.sniffingConfig.DestinationOverride
|
content.SniffingRequest.OverrideDestinationForProtocol = w.sniffingConfig.DestinationOverride
|
||||||
|
content.SniffingRequest.ExcludeForDomain = w.sniffingConfig.DomainsExcluded
|
||||||
content.SniffingRequest.MetadataOnly = w.sniffingConfig.MetadataOnly
|
content.SniffingRequest.MetadataOnly = w.sniffingConfig.MetadataOnly
|
||||||
content.SniffingRequest.RouteOnly = w.sniffingConfig.RouteOnly
|
content.SniffingRequest.RouteOnly = w.sniffingConfig.RouteOnly
|
||||||
}
|
}
|
||||||
|
@ -120,7 +120,7 @@ func (w *ServerWorker) handleStatusKeepAlive(meta *FrameMetadata, reader *buf.Bu
|
|||||||
func (w *ServerWorker) handleStatusNew(ctx context.Context, meta *FrameMetadata, reader *buf.BufferedReader) error {
|
func (w *ServerWorker) handleStatusNew(ctx context.Context, meta *FrameMetadata, reader *buf.BufferedReader) error {
|
||||||
// deep-clone outbounds because it is going to be mutated concurrently
|
// deep-clone outbounds because it is going to be mutated concurrently
|
||||||
// (Target and OriginalTarget)
|
// (Target and OriginalTarget)
|
||||||
ctx = session.ContextCloneOutbounds(ctx)
|
ctx = session.ContextCloneOutboundsAndContent(ctx)
|
||||||
errors.LogInfo(ctx, "received request for ", meta.Target)
|
errors.LogInfo(ctx, "received request for ", meta.Target)
|
||||||
{
|
{
|
||||||
msg := &log.AccessMessage{
|
msg := &log.AccessMessage{
|
||||||
|
@ -63,7 +63,7 @@ func SniffHTTP(b []byte, c context.Context) (*SniffHeader, error) {
|
|||||||
ShouldSniffAttr := true
|
ShouldSniffAttr := true
|
||||||
// If content.Attributes have information, that means it comes from HTTP inbound PlainHTTP mode.
|
// If content.Attributes have information, that means it comes from HTTP inbound PlainHTTP mode.
|
||||||
// It will set attributes, so skip it.
|
// It will set attributes, so skip it.
|
||||||
if content == nil || content.AttributeLen() != 0 {
|
if content == nil || len(content.Attributes) != 0 {
|
||||||
ShouldSniffAttr = false
|
ShouldSniffAttr = false
|
||||||
}
|
}
|
||||||
if err := beginWithHTTPMethod(b); err != nil {
|
if err := beginWithHTTPMethod(b); err != nil {
|
||||||
|
@ -42,7 +42,7 @@ func ContextWithOutbounds(ctx context.Context, outbounds []*Outbound) context.Co
|
|||||||
return context.WithValue(ctx, outboundSessionKey, outbounds)
|
return context.WithValue(ctx, outboundSessionKey, outbounds)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ContextCloneOutbounds(ctx context.Context) context.Context {
|
func ContextCloneOutboundsAndContent(ctx context.Context) context.Context {
|
||||||
outbounds := OutboundsFromContext(ctx)
|
outbounds := OutboundsFromContext(ctx)
|
||||||
newOutbounds := make([]*Outbound, len(outbounds))
|
newOutbounds := make([]*Outbound, len(outbounds))
|
||||||
for i, ob := range outbounds {
|
for i, ob := range outbounds {
|
||||||
@ -55,7 +55,15 @@ func ContextCloneOutbounds(ctx context.Context) context.Context {
|
|||||||
newOutbounds[i] = &v
|
newOutbounds[i] = &v
|
||||||
}
|
}
|
||||||
|
|
||||||
return ContextWithOutbounds(ctx, newOutbounds)
|
content := ContentFromContext(ctx)
|
||||||
|
newContent := Content{}
|
||||||
|
if content != nil {
|
||||||
|
newContent = *content
|
||||||
|
if content.Attributes != nil {
|
||||||
|
panic("content.Attributes != nil")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ContextWithContent(ContextWithOutbounds(ctx, newOutbounds), &newContent)
|
||||||
}
|
}
|
||||||
|
|
||||||
func OutboundsFromContext(ctx context.Context) []*Outbound {
|
func OutboundsFromContext(ctx context.Context) []*Outbound {
|
||||||
|
@ -4,7 +4,6 @@ package session // import "github.com/xtls/xray-core/common/session"
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"sync"
|
|
||||||
|
|
||||||
c "github.com/xtls/xray-core/common/ctx"
|
c "github.com/xtls/xray-core/common/ctx"
|
||||||
"github.com/xtls/xray-core/common/errors"
|
"github.com/xtls/xray-core/common/errors"
|
||||||
@ -75,8 +74,8 @@ type Outbound struct {
|
|||||||
|
|
||||||
// SniffingRequest controls the behavior of content sniffing.
|
// SniffingRequest controls the behavior of content sniffing.
|
||||||
type SniffingRequest struct {
|
type SniffingRequest struct {
|
||||||
ExcludeForDomain []string
|
ExcludeForDomain []string // read-only once set
|
||||||
OverrideDestinationForProtocol []string
|
OverrideDestinationForProtocol []string // read-only once set
|
||||||
Enabled bool
|
Enabled bool
|
||||||
MetadataOnly bool
|
MetadataOnly bool
|
||||||
RouteOnly bool
|
RouteOnly bool
|
||||||
@ -92,10 +91,6 @@ type Content struct {
|
|||||||
Attributes map[string]string
|
Attributes map[string]string
|
||||||
|
|
||||||
SkipDNSResolve bool
|
SkipDNSResolve bool
|
||||||
|
|
||||||
mu sync.Mutex
|
|
||||||
|
|
||||||
isLocked bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sockopt is the settings for socket connection.
|
// Sockopt is the settings for socket connection.
|
||||||
@ -104,22 +99,8 @@ type Sockopt struct {
|
|||||||
Mark int32
|
Mark int32
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some how when using mux, there will be a same ctx between different requests
|
|
||||||
// This will cause problem as it's designed for single request, like concurrent map writes
|
|
||||||
// Add a Mutex as a temp solution
|
|
||||||
|
|
||||||
// SetAttribute attaches additional string attributes to content.
|
// SetAttribute attaches additional string attributes to content.
|
||||||
func (c *Content) SetAttribute(name string, value string) {
|
func (c *Content) SetAttribute(name string, value string) {
|
||||||
if c.isLocked {
|
|
||||||
errors.LogError(context.Background(), "Multiple goroutines are tring to access one routing content, tring to write ", name, ":", value)
|
|
||||||
}
|
|
||||||
c.mu.Lock()
|
|
||||||
c.isLocked = true
|
|
||||||
defer func() {
|
|
||||||
c.isLocked = false
|
|
||||||
c.mu.Unlock()
|
|
||||||
}()
|
|
||||||
|
|
||||||
if c.Attributes == nil {
|
if c.Attributes == nil {
|
||||||
c.Attributes = make(map[string]string)
|
c.Attributes = make(map[string]string)
|
||||||
}
|
}
|
||||||
@ -128,24 +109,8 @@ func (c *Content) SetAttribute(name string, value string) {
|
|||||||
|
|
||||||
// Attribute retrieves additional string attributes from content.
|
// Attribute retrieves additional string attributes from content.
|
||||||
func (c *Content) Attribute(name string) string {
|
func (c *Content) Attribute(name string) string {
|
||||||
c.mu.Lock()
|
|
||||||
c.isLocked = true
|
|
||||||
defer func() {
|
|
||||||
c.isLocked = false
|
|
||||||
c.mu.Unlock()
|
|
||||||
}()
|
|
||||||
if c.Attributes == nil {
|
if c.Attributes == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
return c.Attributes[name]
|
return c.Attributes[name]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Content) AttributeLen() int {
|
|
||||||
c.mu.Lock()
|
|
||||||
c.isLocked = true
|
|
||||||
defer func() {
|
|
||||||
c.isLocked = false
|
|
||||||
c.mu.Unlock()
|
|
||||||
}()
|
|
||||||
return len(c.Attributes)
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user