task engine for all proxies

This commit is contained in:
Darien Raymond
2016-12-30 00:32:20 +01:00
parent 690d71b16e
commit 609dbc1f13
10 changed files with 304 additions and 174 deletions
+5 -6
View File
@@ -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
}
+45 -53
View File
@@ -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)
}