mirror of
https://github.com/v2ray/v2ray-core.git
synced 2026-11-01 16:18:24 +00:00
task engine for all proxies
This commit is contained in:
@@ -137,7 +137,6 @@ func transferRequest(session *encoding.ServerSession, request *protocol.RequestH
|
||||
defer bodyReader.Release()
|
||||
|
||||
if err := buf.PipeUntilEOF(bodyReader, output); err != nil {
|
||||
log.Debug("VMess|Inbound: Error when sending data to outbound: ", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -160,7 +159,6 @@ func transferResponse(session *encoding.ServerSession, request *protocol.Request
|
||||
}
|
||||
|
||||
if err := buf.PipeUntilEOF(input, bodyWriter); err != nil {
|
||||
log.Debug("VMess|Inbound: Error when sending data to downstream: ", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -201,13 +199,13 @@ func (v *VMessInboundHandler) HandleConnection(connection internet.Connection) {
|
||||
if err != nil {
|
||||
if errors.Cause(err) != io.EOF {
|
||||
log.Access(connection.RemoteAddr(), "", log.AccessRejected, err)
|
||||
log.Info("VMessIn: Invalid request from ", connection.RemoteAddr(), ": ", err)
|
||||
log.Info("VMess|Inbound: Invalid request from ", connection.RemoteAddr(), ": ", err)
|
||||
}
|
||||
connection.SetReusable(false)
|
||||
return
|
||||
}
|
||||
log.Access(connection.RemoteAddr(), request.Destination(), log.AccessAccepted, "")
|
||||
log.Info("VMessIn: Received request for ", request.Destination())
|
||||
log.Info("VMess|Inbound: Received request for ", request.Destination())
|
||||
|
||||
connection.SetReusable(request.Option.Has(protocol.RequestOptionConnectionReuse))
|
||||
|
||||
@@ -245,13 +243,14 @@ func (v *VMessInboundHandler) HandleConnection(connection internet.Connection) {
|
||||
return transferResponse(session, request, response, output, writer)
|
||||
})
|
||||
|
||||
err = signal.ErrorOrFinish2(requestDone, responseDone)
|
||||
if err != nil {
|
||||
if err := signal.ErrorOrFinish2(requestDone, responseDone); err != nil {
|
||||
log.Info("VMess|Inbound: Connection ending with ", err)
|
||||
connection.SetReusable(false)
|
||||
return
|
||||
}
|
||||
|
||||
if err := writer.Flush(); err != nil {
|
||||
log.Info("VMess|Inbound: Failed to flush remain data: ", err)
|
||||
connection.SetReusable(false)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package outbound
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"v2ray.com/core/app"
|
||||
"v2ray.com/core/common"
|
||||
"v2ray.com/core/common/buf"
|
||||
@@ -12,6 +10,7 @@ import (
|
||||
"v2ray.com/core/common/protocol"
|
||||
"v2ray.com/core/common/retry"
|
||||
"v2ray.com/core/common/serial"
|
||||
"v2ray.com/core/common/signal"
|
||||
"v2ray.com/core/proxy"
|
||||
"v2ray.com/core/proxy/vmess"
|
||||
"v2ray.com/core/proxy/vmess/encoding"
|
||||
@@ -28,6 +27,7 @@ type VMessOutboundHandler struct {
|
||||
|
||||
// Dispatch implements OutboundHandler.Dispatch().
|
||||
func (v *VMessOutboundHandler) Dispatch(target v2net.Destination, payload *buf.Buffer, ray ray.OutboundRay) {
|
||||
defer payload.Release()
|
||||
defer ray.OutboundInput().Release()
|
||||
defer ray.OutboundOutput().Close()
|
||||
|
||||
@@ -80,73 +80,65 @@ func (v *VMessOutboundHandler) Dispatch(target v2net.Destination, payload *buf.B
|
||||
input := ray.OutboundInput()
|
||||
output := ray.OutboundOutput()
|
||||
|
||||
var requestFinish, responseFinish sync.Mutex
|
||||
requestFinish.Lock()
|
||||
responseFinish.Lock()
|
||||
|
||||
session := encoding.NewClientSession(protocol.DefaultIDHash)
|
||||
|
||||
go v.handleRequest(session, conn, request, payload, input, &requestFinish)
|
||||
go v.handleResponse(session, conn, request, rec.Destination(), output, &responseFinish)
|
||||
requestDone := signal.ExecuteAsync(func() error {
|
||||
defer input.Release()
|
||||
|
||||
requestFinish.Lock()
|
||||
responseFinish.Lock()
|
||||
return
|
||||
}
|
||||
writer := bufio.NewWriter(conn)
|
||||
defer writer.Release()
|
||||
|
||||
func (v *VMessOutboundHandler) handleRequest(session *encoding.ClientSession, conn internet.Connection, request *protocol.RequestHeader, payload *buf.Buffer, input buf.Reader, finish *sync.Mutex) {
|
||||
defer finish.Unlock()
|
||||
session.EncodeRequestHeader(request, writer)
|
||||
|
||||
writer := bufio.NewWriter(conn)
|
||||
defer writer.Release()
|
||||
session.EncodeRequestHeader(request, writer)
|
||||
bodyWriter := session.EncodeRequestBody(request, writer)
|
||||
defer bodyWriter.Release()
|
||||
|
||||
bodyWriter := session.EncodeRequestBody(request, writer)
|
||||
defer bodyWriter.Release()
|
||||
|
||||
if !payload.IsEmpty() {
|
||||
if err := bodyWriter.Write(payload); err != nil {
|
||||
log.Info("VMess|Outbound: Failed to write payload. Disabling connection reuse.", err)
|
||||
conn.SetReusable(false)
|
||||
if !payload.IsEmpty() {
|
||||
if err := bodyWriter.Write(payload); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
payload.Release()
|
||||
}
|
||||
writer.SetBuffered(false)
|
||||
writer.SetBuffered(false)
|
||||
|
||||
if err := buf.PipeUntilEOF(input, bodyWriter); err != nil {
|
||||
conn.SetReusable(false)
|
||||
}
|
||||
if err := buf.PipeUntilEOF(input, bodyWriter); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if request.Option.Has(protocol.RequestOptionChunkStream) {
|
||||
err := bodyWriter.Write(buf.NewLocal(8))
|
||||
if request.Option.Has(protocol.RequestOptionChunkStream) {
|
||||
if err := bodyWriter.Write(buf.NewLocal(8)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
responseDone := signal.ExecuteAsync(func() error {
|
||||
defer output.Close()
|
||||
|
||||
reader := bufio.NewReader(conn)
|
||||
defer reader.Release()
|
||||
|
||||
header, err := session.DecodeResponseHeader(reader)
|
||||
if err != nil {
|
||||
conn.SetReusable(false)
|
||||
return err
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
v.handleCommand(rec.Destination(), header.Command)
|
||||
|
||||
func (v *VMessOutboundHandler) handleResponse(session *encoding.ClientSession, conn internet.Connection, request *protocol.RequestHeader, dest v2net.Destination, output buf.Writer, finish *sync.Mutex) {
|
||||
defer finish.Unlock()
|
||||
conn.SetReusable(header.Option.Has(protocol.ResponseOptionConnectionReuse))
|
||||
|
||||
reader := bufio.NewReader(conn)
|
||||
defer reader.Release()
|
||||
reader.SetBuffered(false)
|
||||
bodyReader := session.DecodeResponseBody(request, reader)
|
||||
defer bodyReader.Release()
|
||||
|
||||
header, err := session.DecodeResponseHeader(reader)
|
||||
if err != nil {
|
||||
conn.SetReusable(false)
|
||||
log.Warning("VMess|Outbound: Failed to read response from ", request.Destination(), ": ", err)
|
||||
return
|
||||
}
|
||||
v.handleCommand(dest, header.Command)
|
||||
if err := buf.PipeUntilEOF(bodyReader, output); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
conn.SetReusable(header.Option.Has(protocol.ResponseOptionConnectionReuse))
|
||||
return nil
|
||||
})
|
||||
|
||||
reader.SetBuffered(false)
|
||||
bodyReader := session.DecodeResponseBody(request, reader)
|
||||
defer bodyReader.Release()
|
||||
|
||||
if err := buf.PipeUntilEOF(bodyReader, output); err != nil {
|
||||
if err := signal.ErrorOrFinish2(requestDone, responseDone); err != nil {
|
||||
log.Info("VMess|Outbound: Connection ending with ", err)
|
||||
conn.SetReusable(false)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user