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 }