github.com/moqsien/xraycore@v1.8.5/common/session/context.go (about)

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