|  | @@ -15,7 +15,6 @@ import (
 | 
	
		
			
				|  |  |  	"v2ray.com/core/common/buf"
 | 
	
		
			
				|  |  |  	"v2ray.com/core/common/errors"
 | 
	
		
			
				|  |  |  	"v2ray.com/core/common/net"
 | 
	
		
			
				|  |  | -	"v2ray.com/core/common/signal"
 | 
	
		
			
				|  |  |  	"v2ray.com/core/proxy"
 | 
	
		
			
				|  |  |  	"v2ray.com/core/transport/ray"
 | 
	
		
			
				|  |  |  )
 | 
	
	
		
			
				|  | @@ -147,7 +146,7 @@ func fetchInput(ctx context.Context, s *Session, output buf.Writer) {
 | 
	
		
			
				|  |  |  		log.Trace(newError("failed to write first payload").Base(err))
 | 
	
		
			
				|  |  |  		return
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | -	if err := buf.Copy(signal.BackgroundTimer(), s.input, writer); err != nil {
 | 
	
		
			
				|  |  | +	if err := buf.Copy(s.input, writer); err != nil {
 | 
	
		
			
				|  |  |  		log.Trace(newError("failed to fetch all input").Base(err))
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -175,22 +174,10 @@ func (m *Client) Dispatch(ctx context.Context, outboundRay ray.OutboundRay) bool
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  func drain(reader *Reader) error {
 | 
	
		
			
				|  |  | -	data, err := reader.Read()
 | 
	
		
			
				|  |  | -	if err != nil {
 | 
	
		
			
				|  |  | -		return err
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	data.Release()
 | 
	
		
			
				|  |  | +	buf.Copy(reader, buf.Discard)
 | 
	
		
			
				|  |  |  	return nil
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -func pipe(reader *Reader, writer buf.Writer) error {
 | 
	
		
			
				|  |  | -	data, err := reader.Read()
 | 
	
		
			
				|  |  | -	if err != nil {
 | 
	
		
			
				|  |  | -		return err
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	return writer.Write(data)
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  func (m *Client) handleStatueKeepAlive(meta *FrameMetadata, reader *Reader) error {
 | 
	
		
			
				|  |  |  	if meta.Option.Has(OptionData) {
 | 
	
		
			
				|  |  |  		return drain(reader)
 | 
	
	
		
			
				|  | @@ -211,7 +198,7 @@ func (m *Client) handleStatusKeep(meta *FrameMetadata, reader *Reader) error {
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	if s, found := m.sessionManager.Get(meta.SessionID); found {
 | 
	
		
			
				|  |  | -		return pipe(reader, s.output)
 | 
	
		
			
				|  |  | +		return buf.Copy(reader, s.output, buf.IgnoreWriterError())
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  	return drain(reader)
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -303,7 +290,7 @@ type ServerWorker struct {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  func handle(ctx context.Context, s *Session, output buf.Writer) {
 | 
	
		
			
				|  |  |  	writer := NewResponseWriter(s.ID, output)
 | 
	
		
			
				|  |  | -	if err := buf.Copy(signal.BackgroundTimer(), s.input, writer); err != nil {
 | 
	
		
			
				|  |  | +	if err := buf.Copy(s.input, writer); err != nil {
 | 
	
		
			
				|  |  |  		log.Trace(newError("session ", s.ID, " ends: ").Base(err))
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  	writer.Close()
 | 
	
	
		
			
				|  | @@ -335,7 +322,7 @@ func (w *ServerWorker) handleStatusNew(ctx context.Context, meta *FrameMetadata,
 | 
	
		
			
				|  |  |  	w.sessionManager.Add(s)
 | 
	
		
			
				|  |  |  	go handle(ctx, s, w.outboundRay.OutboundOutput())
 | 
	
		
			
				|  |  |  	if meta.Option.Has(OptionData) {
 | 
	
		
			
				|  |  | -		return pipe(reader, s.output)
 | 
	
		
			
				|  |  | +		return buf.Copy(reader, s.output, buf.IgnoreWriterError())
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  	return nil
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -345,7 +332,7 @@ func (w *ServerWorker) handleStatusKeep(meta *FrameMetadata, reader *Reader) err
 | 
	
		
			
				|  |  |  		return nil
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  	if s, found := w.sessionManager.Get(meta.SessionID); found {
 | 
	
		
			
				|  |  | -		return pipe(reader, s.output)
 | 
	
		
			
				|  |  | +		return buf.Copy(reader, s.output, buf.IgnoreWriterError())
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  	return drain(reader)
 | 
	
		
			
				|  |  |  }
 |