github.com/xmplusdev/xmcore@v1.8.11-0.20240412132628-5518b55526af/features/policy/policy.go (about)

     1  package policy
     2  
     3  import (
     4  	"context"
     5  	"runtime"
     6  	"time"
     7  
     8  	"github.com/xmplusdev/xmcore/common/platform"
     9  	"github.com/xmplusdev/xmcore/features"
    10  )
    11  
    12  // Timeout contains limits for connection timeout.
    13  type Timeout struct {
    14  	// Timeout for handshake phase in a connection.
    15  	Handshake time.Duration
    16  	// Timeout for connection being idle, i.e., there is no egress or ingress traffic in this connection.
    17  	ConnectionIdle time.Duration
    18  	// Timeout for an uplink only connection, i.e., the downlink of the connection has been closed.
    19  	UplinkOnly time.Duration
    20  	// Timeout for an downlink only connection, i.e., the uplink of the connection has been closed.
    21  	DownlinkOnly time.Duration
    22  }
    23  
    24  // Stats contains settings for stats counters.
    25  type Stats struct {
    26  	// Whether or not to enable stat counter for user uplink traffic.
    27  	UserUplink bool
    28  	// Whether or not to enable stat counter for user downlink traffic.
    29  	UserDownlink bool
    30  }
    31  
    32  // Buffer contains settings for internal buffer.
    33  type Buffer struct {
    34  	// Size of buffer per connection, in bytes. -1 for unlimited buffer.
    35  	PerConnection int32
    36  }
    37  
    38  // SystemStats contains stat policy settings on system level.
    39  type SystemStats struct {
    40  	// Whether or not to enable stat counter for uplink traffic in inbound handlers.
    41  	InboundUplink bool
    42  	// Whether or not to enable stat counter for downlink traffic in inbound handlers.
    43  	InboundDownlink bool
    44  	// Whether or not to enable stat counter for uplink traffic in outbound handlers.
    45  	OutboundUplink bool
    46  	// Whether or not to enable stat counter for downlink traffic in outbound handlers.
    47  	OutboundDownlink bool
    48  }
    49  
    50  // System contains policy settings at system level.
    51  type System struct {
    52  	Stats  SystemStats
    53  	Buffer Buffer
    54  }
    55  
    56  // Session is session based settings for controlling Xray requests. It contains various settings (or limits) that may differ for different users in the context.
    57  type Session struct {
    58  	Timeouts Timeout // Timeout settings
    59  	Stats    Stats
    60  	Buffer   Buffer
    61  }
    62  
    63  // Manager is a feature that provides Policy for the given user by its id or level.
    64  //
    65  // xray:api:stable
    66  type Manager interface {
    67  	features.Feature
    68  
    69  	// ForLevel returns the Session policy for the given user level.
    70  	ForLevel(level uint32) Session
    71  
    72  	// ForSystem returns the System policy for Xray system.
    73  	ForSystem() System
    74  }
    75  
    76  // ManagerType returns the type of Manager interface. Can be used to implement common.HasType.
    77  //
    78  // xray:api:stable
    79  func ManagerType() interface{} {
    80  	return (*Manager)(nil)
    81  }
    82  
    83  var defaultBufferSize int32
    84  
    85  func init() {
    86  	const defaultValue = -17
    87  	size := platform.NewEnvFlag(platform.BufferSize).GetValueAsInt(defaultValue)
    88  
    89  	switch size {
    90  	case 0:
    91  		defaultBufferSize = -1 // For pipe to use unlimited size
    92  	case defaultValue: // Env flag not defined. Use default values per CPU-arch.
    93  		switch runtime.GOARCH {
    94  		case "arm", "mips", "mipsle":
    95  			defaultBufferSize = 0
    96  		case "arm64", "mips64", "mips64le":
    97  			defaultBufferSize = 4 * 1024 // 4k cache for low-end devices
    98  		default:
    99  			defaultBufferSize = 512 * 1024
   100  		}
   101  	default:
   102  		defaultBufferSize = int32(size) * 1024 * 1024
   103  	}
   104  }
   105  
   106  func defaultBufferPolicy() Buffer {
   107  	return Buffer{
   108  		PerConnection: defaultBufferSize,
   109  	}
   110  }
   111  
   112  // SessionDefault returns the Policy when user is not specified.
   113  func SessionDefault() Session {
   114  	return Session{
   115  		Timeouts: Timeout{
   116  			// Align Handshake timeout with nginx client_header_timeout
   117  			// So that this value will not indicate server identity
   118  			Handshake:      time.Second * 60,
   119  			ConnectionIdle: time.Second * 300,
   120  			UplinkOnly:     time.Second * 1,
   121  			DownlinkOnly:   time.Second * 1,
   122  		},
   123  		Stats: Stats{
   124  			UserUplink:   false,
   125  			UserDownlink: false,
   126  		},
   127  		Buffer: defaultBufferPolicy(),
   128  	}
   129  }
   130  
   131  type policyKey int32
   132  
   133  const (
   134  	bufferPolicyKey policyKey = 0
   135  )
   136  
   137  func ContextWithBufferPolicy(ctx context.Context, p Buffer) context.Context {
   138  	return context.WithValue(ctx, bufferPolicyKey, p)
   139  }
   140  
   141  func BufferPolicyFromContext(ctx context.Context) Buffer {
   142  	pPolicy := ctx.Value(bufferPolicyKey)
   143  	if pPolicy == nil {
   144  		return defaultBufferPolicy()
   145  	}
   146  	return pPolicy.(Buffer)
   147  }