Darien Raymond пре 8 година
родитељ
комит
e678000c44

+ 0 - 5
app/dispatcher/impl/default.go

@@ -44,11 +44,6 @@ func (v *DefaultDispatcher) Initialize(space app.Space) error {
 	return nil
 }
 
-// Release implements common.Releasable.Release().
-func (v *DefaultDispatcher) Release() {
-
-}
-
 func (v *DefaultDispatcher) DispatchToOutbound(session *proxy.SessionInfo) ray.InboundRay {
 	dispatcher := v.ohm.GetDefaultHandler()
 	destination := session.Destination

+ 0 - 4
app/dns/server/server.go

@@ -66,10 +66,6 @@ func NewCacheServer(space app.Space, config *dns.Config) *CacheServer {
 	return server
 }
 
-func (v *CacheServer) Release() {
-
-}
-
 // Private: Visible for testing.
 func (v *CacheServer) GetCached(domain string) []net.IP {
 	v.RLock()

+ 1 - 8
app/proxy/proxy.go

@@ -54,11 +54,6 @@ func (v *OutboundProxy) Dial(src v2net.Address, dest v2net.Destination, options
 	return NewConnection(src, dest, stream), nil
 }
 
-// Release implements common.Releasable.Release().
-func (v *OutboundProxy) Release() {
-
-}
-
 type Connection struct {
 	stream     ray.Ray
 	closed     bool
@@ -105,9 +100,7 @@ func (v *Connection) Write(b []byte) (int, error) {
 func (v *Connection) Close() error {
 	v.closed = true
 	v.stream.InboundInput().Close()
-	v.stream.InboundOutput().Release()
-	v.reader.Release()
-	v.writer.Release()
+	v.stream.InboundOutput().ForceClose()
 	return nil
 }
 

+ 1 - 4
app/proxyman/outbound/outbound.go

@@ -2,6 +2,7 @@ package outbound
 
 import (
 	"sync"
+
 	"v2ray.com/core/app"
 	"v2ray.com/core/app/proxyman"
 	"v2ray.com/core/common/serial"
@@ -20,10 +21,6 @@ func New() *DefaultOutboundHandlerManager {
 	}
 }
 
-func (v *DefaultOutboundHandlerManager) Release() {
-
-}
-
 func (v *DefaultOutboundHandlerManager) GetDefaultHandler() proxy.OutboundHandler {
 	v.RLock()
 	defer v.RUnlock()

+ 0 - 4
app/router/router.go

@@ -52,10 +52,6 @@ func NewRouter(config *Config, space app.Space) *Router {
 	return r
 }
 
-func (v *Router) Release() {
-
-}
-
 // Private: Visible for testing.
 func (v *Router) ResolveIP(dest v2net.Destination) []v2net.Destination {
 	ips := v.dnsServer.Get(dest.Address.Domain())

+ 1 - 5
app/space.go

@@ -1,9 +1,6 @@
 package app
 
-import (
-	"v2ray.com/core/common"
-	"v2ray.com/core/common/errors"
-)
+import "v2ray.com/core/common/errors"
 
 type ID int
 
@@ -17,7 +14,6 @@ type Caller interface {
 }
 
 type Application interface {
-	common.Releasable
 }
 
 type ApplicationInitializer func() error

+ 1 - 5
app/web/web.go

@@ -1,15 +1,11 @@
 package web
 
-import (
-	"v2ray.com/core/app"
-	"v2ray.com/core/common"
-)
+import "v2ray.com/core/app"
 
 const (
 	APP_ID = app.ID(8)
 )
 
 type WebServer interface {
-	common.Releasable
 	Handle()
 }

+ 0 - 2
common/buf/io.go

@@ -8,14 +8,12 @@ import (
 
 // Reader extends io.Reader with alloc.Buffer.
 type Reader interface {
-	Release()
 	// Read reads content from underlying reader, and put it into an alloc.Buffer.
 	Read() (*Buffer, error)
 }
 
 // Writer extends io.Writer with alloc.Buffer.
 type Writer interface {
-	Release()
 	// Write writes an alloc.Buffer into underlying writer.
 	Write(*Buffer) error
 }

+ 0 - 13
common/buf/reader.go

@@ -1,7 +1,6 @@
 package buf
 
 import "io"
-import "v2ray.com/core/common"
 
 // BytesToBufferReader is a Reader that adjusts its reading speed automatically.
 type BytesToBufferReader struct {
@@ -44,11 +43,6 @@ func (v *BytesToBufferReader) Read() (*Buffer, error) {
 	return buffer, nil
 }
 
-// Release implements Releasable.Release().
-func (v *BytesToBufferReader) Release() {
-	common.Release(v.reader)
-}
-
 type BufferToBytesReader struct {
 	stream  Reader
 	current *Buffer
@@ -84,10 +78,3 @@ func (v *BufferToBytesReader) Read(b []byte) (int, error) {
 	}
 	return nBytes, err
 }
-
-// Release implements Releasable.Release().
-func (v *BufferToBytesReader) Release() {
-	v.eof = true
-	v.current.Release()
-	v.current = nil
-}

+ 0 - 11
common/buf/writer.go

@@ -1,7 +1,6 @@
 package buf
 
 import "io"
-import "v2ray.com/core/common"
 
 // BufferToBytesWriter is a Writer that writes alloc.Buffer into underlying writer.
 type BufferToBytesWriter struct {
@@ -24,11 +23,6 @@ func (v *BufferToBytesWriter) Write(buffer *Buffer) error {
 	return nil
 }
 
-// Release implements Releasable.Release().
-func (v *BufferToBytesWriter) Release() {
-	common.Release(v.writer)
-}
-
 type BytesToBufferWriter struct {
 	writer Writer
 }
@@ -50,8 +44,3 @@ func (v *BytesToBufferWriter) Write(payload []byte) (int, error) {
 
 	return bytesWritten, nil
 }
-
-// Release implements Releasable.Release()
-func (v *BytesToBufferWriter) Release() {
-	v.writer.Release()
-}

+ 1 - 12
common/bufio/reader.go

@@ -3,7 +3,6 @@ package bufio
 import (
 	"io"
 
-	"v2ray.com/core/common"
 	"v2ray.com/core/common/buf"
 )
 
@@ -18,21 +17,11 @@ type BufferedReader struct {
 func NewReader(rawReader io.Reader) *BufferedReader {
 	return &BufferedReader{
 		reader:   rawReader,
-		buffer:   buf.New(),
+		buffer:   buf.NewLocal(1024),
 		buffered: true,
 	}
 }
 
-// Release implements Releasable.Release().
-func (v *BufferedReader) Release() {
-	if v.buffer != nil {
-		v.buffer.Release()
-		v.buffer = nil
-	}
-
-	common.Release(v.reader)
-}
-
 // IsBuffered returns true if the internal cache is effective.
 func (v *BufferedReader) IsBuffered() bool {
 	return v.buffered

+ 1 - 15
common/bufio/writer.go

@@ -3,7 +3,6 @@ package bufio
 import (
 	"io"
 
-	"v2ray.com/core/common"
 	"v2ray.com/core/common/buf"
 	"v2ray.com/core/common/errors"
 )
@@ -20,7 +19,7 @@ type BufferedWriter struct {
 func NewWriter(rawWriter io.Writer) *BufferedWriter {
 	return &BufferedWriter{
 		writer:   rawWriter,
-		buffer:   buf.NewSmall(),
+		buffer:   buf.NewLocal(1024),
 		buffered: true,
 	}
 }
@@ -91,16 +90,3 @@ func (v *BufferedWriter) SetBuffered(cached bool) {
 		v.Flush()
 	}
 }
-
-// Release implements common.Releasable.Release().
-func (v *BufferedWriter) Release() {
-	if !v.buffer.IsEmpty() {
-		v.Flush()
-	}
-
-	if v.buffer != nil {
-		v.buffer.Release()
-		v.buffer = nil
-	}
-	common.Release(v.writer)
-}

+ 4 - 4
common/bufio/writer_test.go

@@ -40,14 +40,14 @@ func TestBufferedWriterLargePayload(t *testing.T) {
 	payload := make([]byte, 64*1024)
 	rand.Read(payload)
 
-	nBytes, err := writer.Write(payload[:1024])
-	assert.Int(nBytes).Equals(1024)
+	nBytes, err := writer.Write(payload[:512])
+	assert.Int(nBytes).Equals(512)
 	assert.Error(err).IsNil()
 
 	assert.Bool(content.IsEmpty()).IsTrue()
 
-	nBytes, err = writer.Write(payload[1024:])
+	nBytes, err = writer.Write(payload[512:])
 	assert.Error(err).IsNil()
-	assert.Int(nBytes).Equals(63 * 1024)
+	assert.Int(nBytes).Equals(64*1024 - 512)
 	assert.Bytes(content.Bytes()).Equals(payload)
 }

+ 0 - 13
common/common.go

@@ -13,19 +13,6 @@ var (
 	ErrDuplicatedName   = errors.New("Duplicated name.")
 )
 
-// Releasable interface is for those types that can release its members.
-type Releasable interface {
-	// Release releases all references to accelerate garbage collection.
-	Release()
-}
-
-// Release tries to release the given object.
-func Release(v interface{}) {
-	if releasable, ok := v.(Releasable); ok {
-		releasable.Release()
-	}
-}
-
 // Must panics if err is not nil.
 func Must(err error) {
 	if err != nil {

+ 0 - 13
common/crypto/io.go

@@ -3,8 +3,6 @@ package crypto
 import (
 	"crypto/cipher"
 	"io"
-
-	"v2ray.com/core/common"
 )
 
 type CryptionReader struct {
@@ -27,11 +25,6 @@ func (v *CryptionReader) Read(data []byte) (int, error) {
 	return nBytes, err
 }
 
-func (v *CryptionReader) Release() {
-	common.Release(v.reader)
-	common.Release(v.stream)
-}
-
 type CryptionWriter struct {
 	stream cipher.Stream
 	writer io.Writer
@@ -50,9 +43,3 @@ func (v *CryptionWriter) Write(data []byte) (int, error) {
 	v.stream.XORKeyStream(data, data)
 	return v.writer.Write(data)
 }
-
-// Release implements common.Releasable.Release().
-func (v *CryptionWriter) Release() {
-	common.Release(v.writer)
-	common.Release(v.stream)
-}

+ 0 - 14
common/log/internal/log_entry.go

@@ -4,12 +4,10 @@ import (
 	"fmt"
 	"strings"
 
-	"v2ray.com/core/common"
 	"v2ray.com/core/common/serial"
 )
 
 type LogEntry interface {
-	common.Releasable
 	fmt.Stringer
 }
 
@@ -18,12 +16,6 @@ type ErrorLog struct {
 	Values []interface{}
 }
 
-func (v *ErrorLog) Release() {
-	for _, val := range v.Values {
-		common.Release(val)
-	}
-}
-
 func (v *ErrorLog) String() string {
 	return v.Prefix + serial.Concat(v.Values...)
 }
@@ -35,12 +27,6 @@ type AccessLog struct {
 	Reason interface{}
 }
 
-func (v *AccessLog) Release() {
-	common.Release(v.From)
-	common.Release(v.To)
-	common.Release(v.Reason)
-}
-
 func (v *AccessLog) String() string {
 	return strings.Join([]string{serial.ToString(v.From), v.Status, serial.ToString(v.To), serial.ToString(v.Reason)}, " ")
 }

+ 1 - 5
common/log/internal/log_writer.go

@@ -17,9 +17,7 @@ type LogWriter interface {
 type NoOpLogWriter struct {
 }
 
-func (v *NoOpLogWriter) Log(entry LogEntry) {
-	entry.Release()
-}
+func (v *NoOpLogWriter) Log(entry LogEntry) {}
 
 func (v *NoOpLogWriter) Close() {
 }
@@ -38,7 +36,6 @@ func NewStdOutLogWriter() LogWriter {
 
 func (v *StdOutLogWriter) Log(log LogEntry) {
 	v.logger.Print(log.String() + platform.LineSeparator())
-	log.Release()
 }
 
 func (v *StdOutLogWriter) Close() {
@@ -58,7 +55,6 @@ func (v *FileLogWriter) Log(log LogEntry) {
 	default:
 		// We don't expect this to happen, but don't want to block main thread as well.
 	}
-	log.Release()
 }
 
 func (v *FileLogWriter) run() {

+ 0 - 7
common/net/timed_io.go

@@ -4,8 +4,6 @@ import (
 	"io"
 	"net"
 	"time"
-
-	"v2ray.com/core/common"
 )
 
 var (
@@ -52,11 +50,6 @@ func (reader *TimeOutReader) SetTimeOut(value uint32) {
 	}
 }
 
-func (reader *TimeOutReader) Release() {
-	common.Release(reader.connection)
-	common.Release(reader.worker)
-}
-
 type timedReaderWorker struct {
 	timeout    uint32
 	connection net.Conn

+ 1 - 6
common/protocol/user_validator.go

@@ -1,12 +1,7 @@
 package protocol
 
-import (
-	"v2ray.com/core/common"
-)
-
 type UserValidator interface {
-	common.Releasable
-
 	Add(user *User) error
 	Get(timeHash []byte) (*User, Timestamp, bool)
+	Release()
 }

+ 1 - 1
proxy/blackhole/blackhole.go

@@ -31,7 +31,7 @@ func (v *Handler) Dispatch(destination v2net.Destination, ray ray.OutboundRay) {
 	v.response.WriteTo(ray.OutboundOutput())
 	ray.OutboundOutput().Close()
 
-	ray.OutboundInput().Release()
+	ray.OutboundInput().ForceClose()
 }
 
 // Factory is an utility for creating blackhole handlers.

+ 0 - 3
proxy/dokodemo/dokodemo.go

@@ -172,13 +172,11 @@ func (v *DokodemoDoor) HandleTCPConnection(conn internet.Connection) {
 	defer output.ForceClose()
 
 	reader := v2net.NewTimeOutReader(v.config.Timeout, conn)
-	defer reader.Release()
 
 	requestDone := signal.ExecuteAsync(func() error {
 		defer ray.InboundInput().Close()
 
 		v2reader := buf.NewReader(reader)
-		defer v2reader.Release()
 
 		if err := buf.PipeUntilEOF(v2reader, ray.InboundInput()); err != nil {
 			log.Info("Dokodemo: Failed to transport all TCP request: ", err)
@@ -192,7 +190,6 @@ func (v *DokodemoDoor) HandleTCPConnection(conn internet.Connection) {
 		defer output.ForceClose()
 
 		v2writer := buf.NewWriter(conn)
-		defer v2writer.Release()
 
 		if err := buf.PipeUntilEOF(output, v2writer); err != nil {
 			log.Info("Dokodemo: Failed to transport all TCP response: ", err)

+ 0 - 4
proxy/freedom/freedom.go

@@ -99,8 +99,6 @@ func (v *Handler) Dispatch(destination v2net.Destination, ray ray.OutboundRay) {
 		defer input.ForceClose()
 
 		v2writer := buf.NewWriter(conn)
-		defer v2writer.Release()
-
 		if err := buf.PipeUntilEOF(input, v2writer); err != nil {
 			return err
 		}
@@ -121,8 +119,6 @@ func (v *Handler) Dispatch(destination v2net.Destination, ray ray.OutboundRay) {
 		defer output.Close()
 
 		v2reader := buf.NewReader(reader)
-		defer v2reader.Release()
-
 		if err := buf.PipeUntilEOF(v2reader, output); err != nil {
 			return err
 		}

+ 0 - 6
proxy/http/server.go

@@ -162,8 +162,6 @@ func (v *Server) handleConnect(request *http.Request, session *proxy.SessionInfo
 		defer ray.InboundInput().Close()
 
 		v2reader := buf.NewReader(reader)
-		defer v2reader.Release()
-
 		if err := buf.PipeUntilEOF(v2reader, ray.InboundInput()); err != nil {
 			return err
 		}
@@ -174,8 +172,6 @@ func (v *Server) handleConnect(request *http.Request, session *proxy.SessionInfo
 		defer ray.InboundOutput().ForceClose()
 
 		v2writer := buf.NewWriter(writer)
-		defer v2writer.Release()
-
 		if err := buf.PipeUntilEOF(ray.InboundOutput(), v2writer); err != nil {
 			return err
 		}
@@ -248,8 +244,6 @@ func (v *Server) handlePlainHTTP(request *http.Request, session *proxy.SessionIn
 		defer input.Close()
 
 		requestWriter := bufio.NewWriter(buf.NewBytesWriter(ray.InboundInput()))
-		defer requestWriter.Release()
-
 		err := request.Write(requestWriter)
 		if err != nil {
 			return err

+ 0 - 4
proxy/shadowsocks/client.go

@@ -87,11 +87,7 @@ func (v *Client) Dispatch(destination v2net.Destination, ray ray.OutboundRay) {
 
 	if request.Command == protocol.RequestCommandTCP {
 		bufferedWriter := bufio.NewWriter(conn)
-		defer bufferedWriter.Release()
-
 		bodyWriter, err := WriteTCPRequest(request, bufferedWriter)
-		defer bodyWriter.Release()
-
 		if err != nil {
 			log.Info("Shadowsocks|Client: Failed to write request: ", err)
 			return

+ 0 - 11
proxy/shadowsocks/ota.go

@@ -6,7 +6,6 @@ import (
 	"crypto/sha1"
 	"io"
 
-	"v2ray.com/core/common"
 	"v2ray.com/core/common/buf"
 	"v2ray.com/core/common/errors"
 	"v2ray.com/core/common/serial"
@@ -70,11 +69,6 @@ func NewChunkReader(reader io.Reader, auth *Authenticator) *ChunkReader {
 	}
 }
 
-func (v *ChunkReader) Release() {
-	common.Release(v.reader)
-	common.Release(v.auth)
-}
-
 func (v *ChunkReader) Read() (*buf.Buffer, error) {
 	buffer := buf.New()
 	if err := buffer.AppendSupplier(buf.ReadFullFrom(v.reader, 2)); err != nil {
@@ -124,11 +118,6 @@ func NewChunkWriter(writer io.Writer, auth *Authenticator) *ChunkWriter {
 	}
 }
 
-func (v *ChunkWriter) Release() {
-	common.Release(v.writer)
-	common.Release(v.auth)
-}
-
 func (v *ChunkWriter) Write(payload *buf.Buffer) error {
 	totalLength := payload.Len()
 	serial.Uint16ToBytes(uint16(totalLength), v.buffer[:0])

+ 0 - 7
proxy/shadowsocks/protocol.go

@@ -378,9 +378,6 @@ func (v *UDPReader) Read() (*buf.Buffer, error) {
 	return payload, nil
 }
 
-func (v *UDPReader) Release() {
-}
-
 type UDPWriter struct {
 	Writer  io.Writer
 	Request *protocol.RequestHeader
@@ -395,7 +392,3 @@ func (v *UDPWriter) Write(buffer *buf.Buffer) error {
 	payload.Release()
 	return err
 }
-
-func (v *UDPWriter) Release() {
-
-}

+ 0 - 8
proxy/shadowsocks/server.go

@@ -147,18 +147,13 @@ func (v *Server) handleConnection(conn internet.Connection) {
 	conn.SetReusable(false)
 
 	timedReader := v2net.NewTimeOutReader(16, conn)
-	defer timedReader.Release()
-
 	bufferedReader := bufio.NewReader(timedReader)
-	defer bufferedReader.Release()
-
 	request, bodyReader, err := ReadTCPSession(v.user, bufferedReader)
 	if err != nil {
 		log.Access(conn.RemoteAddr(), "", log.AccessRejected, err)
 		log.Info("Shadowsocks|Server: Failed to create request from: ", conn.RemoteAddr(), ": ", err)
 		return
 	}
-	defer bodyReader.Release()
 
 	bufferedReader.SetBuffered(false)
 
@@ -182,14 +177,11 @@ func (v *Server) handleConnection(conn internet.Connection) {
 		defer ray.InboundOutput().ForceClose()
 
 		bufferedWriter := bufio.NewWriter(conn)
-		defer bufferedWriter.Release()
-
 		responseWriter, err := WriteTCPResponse(request, bufferedWriter)
 		if err != nil {
 			log.Warning("Shadowsocks|Server: Failed to write response: ", err)
 			return err
 		}
-		defer responseWriter.Release()
 
 		payload, err := ray.InboundOutput().Read()
 		if err != nil {

+ 0 - 5
proxy/socks/server.go

@@ -105,7 +105,6 @@ func (v *Server) handleConnection(connection internet.Connection) {
 
 	timedReader := v2net.NewTimeOutReader(v.config.Timeout, connection)
 	reader := bufio.NewReader(timedReader)
-	defer reader.Release()
 
 	session := &ServerSession{
 		config: v.config,
@@ -159,8 +158,6 @@ func (v *Server) transport(reader io.Reader, writer io.Writer, session *proxy.Se
 		defer input.Close()
 
 		v2reader := buf.NewReader(reader)
-		defer v2reader.Release()
-
 		if err := buf.PipeUntilEOF(v2reader, input); err != nil {
 			log.Info("Socks|Server: Failed to transport all TCP request: ", err)
 			return err
@@ -172,8 +169,6 @@ func (v *Server) transport(reader io.Reader, writer io.Writer, session *proxy.Se
 		defer output.ForceClose()
 
 		v2writer := buf.NewWriter(writer)
-		defer v2writer.Release()
-
 		if err := buf.PipeUntilEOF(output, v2writer); err != nil {
 			log.Info("Socks|Server: Failed to transport all TCP response: ", err)
 			return err

+ 0 - 10
proxy/vmess/encoding/server.go

@@ -37,16 +37,6 @@ func NewServerSession(validator protocol.UserValidator) *ServerSession {
 	}
 }
 
-// Release implements common.Releaseable.
-func (v *ServerSession) Release() {
-	v.userValidator = nil
-	v.requestBodyIV = nil
-	v.requestBodyKey = nil
-	v.responseBodyIV = nil
-	v.responseBodyKey = nil
-	v.responseWriter = nil
-}
-
 func (v *ServerSession) DecodeRequestHeader(reader io.Reader) (*protocol.RequestHeader, error) {
 	buffer := make([]byte, 512)
 

+ 2 - 12
proxy/vmess/inbound/inbound.go

@@ -87,15 +87,15 @@ func (v *VMessInboundHandler) Port() v2net.Port {
 }
 
 func (v *VMessInboundHandler) Close() {
+	v.Lock()
 	v.accepting = false
 	if v.listener != nil {
-		v.Lock()
 		v.listener.Close()
 		v.listener = nil
 		v.clients.Release()
 		v.clients = nil
-		v.Unlock()
 	}
+	v.Unlock()
 }
 
 func (v *VMessInboundHandler) GetUser(email string) *protocol.User {
@@ -134,8 +134,6 @@ func transferRequest(session *encoding.ServerSession, request *protocol.RequestH
 	defer output.Close()
 
 	bodyReader := session.DecodeRequestBody(request, input)
-	defer bodyReader.Release()
-
 	if err := buf.PipeUntilEOF(bodyReader, output); err != nil {
 		return err
 	}
@@ -180,19 +178,13 @@ func (v *VMessInboundHandler) HandleConnection(connection internet.Connection) {
 	}
 
 	connReader := v2net.NewTimeOutReader(8, connection)
-	defer connReader.Release()
-
 	reader := bufio.NewReader(connReader)
-	defer reader.Release()
-
 	v.RLock()
 	if !v.accepting {
 		v.RUnlock()
 		return
 	}
 	session := encoding.NewServerSession(v.clients)
-	defer session.Release()
-
 	request, err := session.DecodeRequestHeader(reader)
 	v.RUnlock()
 
@@ -229,8 +221,6 @@ func (v *VMessInboundHandler) HandleConnection(connection internet.Connection) {
 	})
 
 	writer := bufio.NewWriter(connection)
-	defer writer.Release()
-
 	response := &protocol.ResponseHeader{
 		Command: v.generateCommand(request),
 	}

+ 0 - 8
proxy/vmess/outbound/outbound.go

@@ -88,13 +88,9 @@ func (v *VMessOutboundHandler) Dispatch(target v2net.Destination, outboundRay ra
 		defer input.ForceClose()
 
 		writer := bufio.NewWriter(conn)
-		defer writer.Release()
-
 		session.EncodeRequestHeader(request, writer)
 
 		bodyWriter := session.EncodeRequestBody(request, writer)
-		defer bodyWriter.Release()
-
 		firstPayload, err := input.ReadTimeout(time.Millisecond * 500)
 		if err != nil && err != ray.ErrReadTimeout {
 			return errors.Base(err).Message("VMess|Outbound: Failed to get first payload.")
@@ -124,8 +120,6 @@ func (v *VMessOutboundHandler) Dispatch(target v2net.Destination, outboundRay ra
 		defer output.Close()
 
 		reader := bufio.NewReader(conn)
-		defer reader.Release()
-
 		header, err := session.DecodeResponseHeader(reader)
 		if err != nil {
 			return err
@@ -136,8 +130,6 @@ func (v *VMessOutboundHandler) Dispatch(target v2net.Destination, outboundRay ra
 
 		reader.SetBuffered(false)
 		bodyReader := session.DecodeResponseBody(request, reader)
-		defer bodyReader.Release()
-
 		if err := buf.PipeUntilEOF(bodyReader, output); err != nil {
 			return err
 		}

+ 1 - 2
transport/internet/kcp/segment.go

@@ -1,7 +1,6 @@
 package kcp
 
 import (
-	"v2ray.com/core/common"
 	"v2ray.com/core/common/buf"
 	"v2ray.com/core/common/serial"
 )
@@ -27,7 +26,7 @@ const (
 )
 
 type Segment interface {
-	common.Releasable
+	Release()
 	Conversation() uint16
 	Command() Command
 	ByteSize() int

+ 1 - 1
transport/internet/udp/udp_server.go

@@ -88,7 +88,7 @@ func (v *TimedInboundRay) Release() {
 	}
 	v.server = nil
 	v.inboundRay.InboundInput().Close()
-	v.inboundRay.InboundOutput().Release()
+	v.inboundRay.InboundOutput().ForceClose()
 	v.inboundRay = nil
 }