| 
					
				 | 
			
			
				@@ -12,11 +12,25 @@ import ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	"v2ray.com/core/common/signal" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// NewRay creates a new Ray for direct traffic transport. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-func NewRay(ctx context.Context) Ray { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+type Option func(*Stream) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+type addInt64 interface { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	Add(int64) int64 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func WithStatCounter(c addInt64) Option { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return func(s *Stream) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		s.onDataSize = append(s.onDataSize, func(delta uint64) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			c.Add(int64(delta)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// New creates a new Ray for direct traffic transport. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func New(ctx context.Context, opts ...Option) Ray { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return &directRay{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		Input:  NewStream(ctx), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		Output: NewStream(ctx), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		Input:  NewStream(ctx, opts...), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		Output: NewStream(ctx, opts...), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -60,18 +74,23 @@ type Stream struct { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	ctx         context.Context 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	readSignal  *signal.Notifier 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	writeSignal *signal.Notifier 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	onDataSize  []func(uint64) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	close       bool 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	err         bool 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 // NewStream creates a new Stream. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-func NewStream(ctx context.Context) *Stream { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	return &Stream{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func NewStream(ctx context.Context, opts ...Option) *Stream { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	s := &Stream{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		ctx:         ctx, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		readSignal:  signal.NewNotifier(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		writeSignal: signal.NewNotifier(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		size:        0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for _, opt := range opts { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		opt(s) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return s 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 func (s *Stream) getData() (buf.MultiBuffer, error) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -201,8 +220,13 @@ func (s *Stream) WriteMultiBuffer(data buf.MultiBuffer) error { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		s.data = buf.NewMultiBufferCap(128) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	dataSize := uint64(data.Len()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for _, f := range s.onDataSize { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		f(dataSize) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	s.data.AppendMulti(data) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	s.size += uint64(data.Len()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	s.size += dataSize 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	s.writeSignal.Signal() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	return nil 
			 |