github.com/xraypb/Xray-core@v1.8.1/common/session/context.go (about)

     1  package session
     2  
     3  import (
     4  	"context"
     5  	_ "unsafe"
     6  
     7  	"github.com/xraypb/Xray-core/features/routing"
     8  )
     9  
    10  //go:linkname IndependentCancelCtx context.newCancelCtx
    11  func IndependentCancelCtx(parent context.Context) context.Context
    12  
    13  type sessionKey int
    14  
    15  const (
    16  	idSessionKey sessionKey = iota
    17  	inboundSessionKey
    18  	outboundSessionKey
    19  	contentSessionKey
    20  	muxPreferedSessionKey
    21  	sockoptSessionKey
    22  	trackedConnectionErrorKey
    23  	dispatcherKey
    24  	timeoutOnlyKey
    25  )
    26  
    27  // ContextWithID returns a new context with the given ID.
    28  func ContextWithID(ctx context.Context, id ID) context.Context {
    29  	return context.WithValue(ctx, idSessionKey, id)
    30  }
    31  
    32  // IDFromContext returns ID in this context, or 0 if not contained.
    33  func IDFromContext(ctx context.Context) ID {
    34  	if id, ok := ctx.Value(idSessionKey).(ID); ok {
    35  		return id
    36  	}
    37  	return 0
    38  }
    39  
    40  func ContextWithInbound(ctx context.Context, inbound *Inbound) context.Context {
    41  	return context.WithValue(ctx, inboundSessionKey, inbound)
    42  }
    43  
    44  func InboundFromContext(ctx context.Context) *Inbound {
    45  	if inbound, ok := ctx.Value(inboundSessionKey).(*Inbound); ok {
    46  		return inbound
    47  	}
    48  	return nil
    49  }
    50  
    51  func ContextWithOutbound(ctx context.Context, outbound *Outbound) context.Context {
    52  	return context.WithValue(ctx, outboundSessionKey, outbound)
    53  }
    54  
    55  func OutboundFromContext(ctx context.Context) *Outbound {
    56  	if outbound, ok := ctx.Value(outboundSessionKey).(*Outbound); ok {
    57  		return outbound
    58  	}
    59  	return nil
    60  }
    61  
    62  func ContextWithContent(ctx context.Context, content *Content) context.Context {
    63  	return context.WithValue(ctx, contentSessionKey, content)
    64  }
    65  
    66  func ContentFromContext(ctx context.Context) *Content {
    67  	if content, ok := ctx.Value(contentSessionKey).(*Content); ok {
    68  		return content
    69  	}
    70  	return nil
    71  }
    72  
    73  // ContextWithMuxPrefered returns a new context with the given bool
    74  func ContextWithMuxPrefered(ctx context.Context, forced bool) context.Context {
    75  	return context.WithValue(ctx, muxPreferedSessionKey, forced)
    76  }
    77  
    78  // MuxPreferedFromContext returns value in this context, or false if not contained.
    79  func MuxPreferedFromContext(ctx context.Context) bool {
    80  	if val, ok := ctx.Value(muxPreferedSessionKey).(bool); ok {
    81  		return val
    82  	}
    83  	return false
    84  }
    85  
    86  // ContextWithSockopt returns a new context with Socket configs included
    87  func ContextWithSockopt(ctx context.Context, s *Sockopt) context.Context {
    88  	return context.WithValue(ctx, sockoptSessionKey, s)
    89  }
    90  
    91  // SockoptFromContext returns Socket configs in this context, or nil if not contained.
    92  func SockoptFromContext(ctx context.Context) *Sockopt {
    93  	if sockopt, ok := ctx.Value(sockoptSessionKey).(*Sockopt); ok {
    94  		return sockopt
    95  	}
    96  	return nil
    97  }
    98  
    99  func GetForcedOutboundTagFromContext(ctx context.Context) string {
   100  	if ContentFromContext(ctx) == nil {
   101  		return ""
   102  	}
   103  	return ContentFromContext(ctx).Attribute("forcedOutboundTag")
   104  }
   105  
   106  func SetForcedOutboundTagToContext(ctx context.Context, tag string) context.Context {
   107  	if contentFromContext := ContentFromContext(ctx); contentFromContext == nil {
   108  		ctx = ContextWithContent(ctx, &Content{})
   109  	}
   110  	ContentFromContext(ctx).SetAttribute("forcedOutboundTag", tag)
   111  	return ctx
   112  }
   113  
   114  type TrackedRequestErrorFeedback interface {
   115  	SubmitError(err error)
   116  }
   117  
   118  func SubmitOutboundErrorToOriginator(ctx context.Context, err error) {
   119  	if errorTracker := ctx.Value(trackedConnectionErrorKey); errorTracker != nil {
   120  		errorTracker := errorTracker.(TrackedRequestErrorFeedback)
   121  		errorTracker.SubmitError(err)
   122  	}
   123  }
   124  
   125  func TrackedConnectionError(ctx context.Context, tracker TrackedRequestErrorFeedback) context.Context {
   126  	return context.WithValue(ctx, trackedConnectionErrorKey, tracker)
   127  }
   128  
   129  func ContextWithDispatcher(ctx context.Context, dispatcher routing.Dispatcher) context.Context {
   130  	return context.WithValue(ctx, dispatcherKey, dispatcher)
   131  }
   132  
   133  func DispatcherFromContext(ctx context.Context) routing.Dispatcher {
   134  	if dispatcher, ok := ctx.Value(dispatcherKey).(routing.Dispatcher); ok {
   135  		return dispatcher
   136  	}
   137  	return nil
   138  }
   139  
   140  func ContextWithTimeoutOnly(ctx context.Context, only bool) context.Context {
   141  	return context.WithValue(ctx, timeoutOnlyKey, only)
   142  }
   143  
   144  func TimeoutOnlyFromContext(ctx context.Context) bool {
   145  	if val, ok := ctx.Value(timeoutOnlyKey).(bool); ok {
   146  		return val
   147  	}
   148  	return false
   149  }