mirror of
https://github.com/v2fly/v2ray-core.git
synced 2026-06-18 08:49:54 -04:00
use stream instead of raw chan
This commit is contained in:
@@ -1,10 +1,7 @@
|
||||
package blackhole
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/v2ray/v2ray-core/app"
|
||||
v2io "github.com/v2ray/v2ray-core/common/io"
|
||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||
"github.com/v2ray/v2ray-core/proxy"
|
||||
"github.com/v2ray/v2ray-core/proxy/internal"
|
||||
@@ -20,14 +17,14 @@ func NewBlackHole() *BlackHole {
|
||||
}
|
||||
|
||||
func (this *BlackHole) Dispatch(firstPacket v2net.Packet, ray ray.OutboundRay) error {
|
||||
if chunk := firstPacket.Chunk(); chunk != nil {
|
||||
chunk.Release()
|
||||
}
|
||||
firstPacket.Release()
|
||||
|
||||
ray.OutboundOutput().Close()
|
||||
ray.OutboundOutput().Release()
|
||||
|
||||
ray.OutboundInput().Close()
|
||||
ray.OutboundInput().Release()
|
||||
|
||||
close(ray.OutboundOutput())
|
||||
if firstPacket.MoreChunks() {
|
||||
v2io.ChanToRawWriter(ioutil.Discard, ray.OutboundInput())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package dokodemo
|
||||
|
||||
import (
|
||||
"io"
|
||||
"sync"
|
||||
|
||||
"github.com/v2ray/v2ray-core/app/dispatcher"
|
||||
@@ -126,25 +125,23 @@ func (this *DokodemoDoor) HandleTCPConnection(conn *hub.TCPConn) {
|
||||
|
||||
packet := v2net.NewPacket(v2net.TCPDestination(this.address, this.port), nil, true)
|
||||
ray := this.packetDispatcher.DispatchToOutbound(packet)
|
||||
defer ray.InboundOutput().Release()
|
||||
|
||||
var inputFinish, outputFinish sync.Mutex
|
||||
inputFinish.Lock()
|
||||
outputFinish.Lock()
|
||||
|
||||
reader := v2net.NewTimeOutReader(this.config.Timeout, conn)
|
||||
go dumpInput(reader, ray.InboundInput(), &inputFinish)
|
||||
go dumpOutput(conn, ray.InboundOutput(), &outputFinish)
|
||||
go func() {
|
||||
v2io.Pipe(v2io.NewAdaptiveReader(reader), ray.InboundInput())
|
||||
inputFinish.Unlock()
|
||||
ray.InboundInput().Close()
|
||||
}()
|
||||
|
||||
go func() {
|
||||
v2io.Pipe(ray.InboundOutput(), v2io.NewAdaptiveWriter(conn))
|
||||
outputFinish.Unlock()
|
||||
}()
|
||||
|
||||
outputFinish.Lock()
|
||||
}
|
||||
|
||||
func dumpInput(reader io.Reader, input chan<- *alloc.Buffer, finish *sync.Mutex) {
|
||||
v2io.RawReaderToChan(input, reader)
|
||||
finish.Unlock()
|
||||
close(input)
|
||||
}
|
||||
|
||||
func dumpOutput(writer io.Writer, output <-chan *alloc.Buffer, finish *sync.Mutex) {
|
||||
v2io.ChanToRawWriter(writer, output)
|
||||
finish.Unlock()
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ func TestDokodemoTCP(t *testing.T) {
|
||||
tcpClient.Write([]byte(data2Send))
|
||||
tcpClient.CloseWrite()
|
||||
|
||||
lastPacket := <-testPacketDispatcher.LastPacket
|
||||
destination := <-testPacketDispatcher.Destination
|
||||
|
||||
response := make([]byte, 1024)
|
||||
nBytes, err := tcpClient.Read(response)
|
||||
@@ -51,9 +51,9 @@ func TestDokodemoTCP(t *testing.T) {
|
||||
tcpClient.Close()
|
||||
|
||||
assert.StringLiteral("Processed: " + data2Send).Equals(string(response[:nBytes]))
|
||||
assert.Bool(lastPacket.Destination().IsTCP()).IsTrue()
|
||||
netassert.Address(lastPacket.Destination().Address()).Equals(v2net.IPAddress([]byte{1, 2, 3, 4}))
|
||||
netassert.Port(lastPacket.Destination().Port()).Equals(128)
|
||||
assert.Bool(destination.IsTCP()).IsTrue()
|
||||
netassert.Address(destination.Address()).Equals(v2net.IPAddress([]byte{1, 2, 3, 4}))
|
||||
netassert.Port(destination.Port()).Equals(128)
|
||||
}
|
||||
|
||||
func TestDokodemoUDP(t *testing.T) {
|
||||
@@ -86,10 +86,9 @@ func TestDokodemoUDP(t *testing.T) {
|
||||
udpClient.Write([]byte(data2Send))
|
||||
udpClient.Close()
|
||||
|
||||
lastPacket := <-testPacketDispatcher.LastPacket
|
||||
destination := <-testPacketDispatcher.Destination
|
||||
|
||||
assert.StringLiteral(data2Send).Equals(string(lastPacket.Chunk().Value))
|
||||
assert.Bool(lastPacket.Destination().IsUDP()).IsTrue()
|
||||
netassert.Address(lastPacket.Destination().Address()).Equals(v2net.IPAddress([]byte{5, 6, 7, 8}))
|
||||
netassert.Port(lastPacket.Destination().Port()).Equals(256)
|
||||
assert.Bool(destination.IsUDP()).IsTrue()
|
||||
netassert.Address(destination.Address()).Equals(v2net.IPAddress([]byte{5, 6, 7, 8}))
|
||||
netassert.Port(destination.Port()).Equals(256)
|
||||
}
|
||||
|
||||
@@ -19,6 +19,9 @@ type FreedomConnection struct {
|
||||
func (this *FreedomConnection) Dispatch(firstPacket v2net.Packet, ray ray.OutboundRay) error {
|
||||
log.Info("Freedom: Opening connection to ", firstPacket.Destination())
|
||||
|
||||
defer firstPacket.Release()
|
||||
defer ray.OutboundInput().Release()
|
||||
|
||||
var conn net.Conn
|
||||
err := retry.Timed(5, 100).On(func() error {
|
||||
rawConn, err := dialer.Dial(firstPacket.Destination())
|
||||
@@ -29,7 +32,6 @@ func (this *FreedomConnection) Dispatch(firstPacket v2net.Packet, ray ray.Outbou
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
close(ray.OutboundOutput())
|
||||
log.Error("Freedom: Failed to open connection to ", firstPacket.Destination(), ": ", err)
|
||||
return err
|
||||
}
|
||||
@@ -43,21 +45,20 @@ func (this *FreedomConnection) Dispatch(firstPacket v2net.Packet, ray ray.Outbou
|
||||
|
||||
if chunk := firstPacket.Chunk(); chunk != nil {
|
||||
conn.Write(chunk.Value)
|
||||
chunk.Release()
|
||||
}
|
||||
|
||||
if !firstPacket.MoreChunks() {
|
||||
writeMutex.Unlock()
|
||||
} else {
|
||||
go func() {
|
||||
v2io.ChanToRawWriter(conn, input)
|
||||
v2io.Pipe(input, v2io.NewAdaptiveWriter(conn))
|
||||
writeMutex.Unlock()
|
||||
}()
|
||||
}
|
||||
|
||||
go func() {
|
||||
defer readMutex.Unlock()
|
||||
defer close(output)
|
||||
defer output.Close()
|
||||
|
||||
var reader io.Reader = conn
|
||||
|
||||
@@ -65,7 +66,7 @@ func (this *FreedomConnection) Dispatch(firstPacket v2net.Packet, ray ray.Outbou
|
||||
reader = v2net.NewTimeOutReader(16 /* seconds */, conn)
|
||||
}
|
||||
|
||||
v2io.RawReaderToChan(output, reader)
|
||||
v2io.Pipe(v2io.NewAdaptiveReader(reader), output)
|
||||
}()
|
||||
|
||||
writeMutex.Lock()
|
||||
|
||||
@@ -37,15 +37,12 @@ func TestSinglePacket(t *testing.T) {
|
||||
|
||||
err = freedom.Dispatch(packet, traffic)
|
||||
assert.Error(err).IsNil()
|
||||
close(traffic.InboundInput())
|
||||
traffic.InboundInput().Close()
|
||||
|
||||
respPayload := <-traffic.InboundOutput()
|
||||
defer respPayload.Release()
|
||||
respPayload, err := traffic.InboundOutput().Read()
|
||||
assert.Error(err).IsNil()
|
||||
assert.Bytes(respPayload.Value).Equals([]byte("Processed: Data to be sent to remote"))
|
||||
|
||||
_, open := <-traffic.InboundOutput()
|
||||
assert.Bool(open).IsFalse()
|
||||
|
||||
tcpServer.Close()
|
||||
}
|
||||
|
||||
@@ -60,7 +57,4 @@ func TestUnreachableDestination(t *testing.T) {
|
||||
|
||||
err := freedom.Dispatch(packet, traffic)
|
||||
assert.Error(err).IsNotNil()
|
||||
|
||||
_, open := <-traffic.InboundOutput()
|
||||
assert.Bool(open).IsFalse()
|
||||
}
|
||||
|
||||
@@ -4,15 +4,16 @@ import (
|
||||
"io"
|
||||
|
||||
"github.com/v2ray/v2ray-core/common/alloc"
|
||||
v2io "github.com/v2ray/v2ray-core/common/io"
|
||||
)
|
||||
|
||||
type ChanReader struct {
|
||||
stream <-chan *alloc.Buffer
|
||||
stream v2io.Reader
|
||||
current *alloc.Buffer
|
||||
eof bool
|
||||
}
|
||||
|
||||
func NewChanReader(stream <-chan *alloc.Buffer) *ChanReader {
|
||||
func NewChanReader(stream v2io.Reader) *ChanReader {
|
||||
this := &ChanReader{
|
||||
stream: stream,
|
||||
}
|
||||
@@ -21,9 +22,9 @@ func NewChanReader(stream <-chan *alloc.Buffer) *ChanReader {
|
||||
}
|
||||
|
||||
func (this *ChanReader) fill() {
|
||||
b, open := <-this.stream
|
||||
b, err := this.stream.Read()
|
||||
this.current = b
|
||||
if !open {
|
||||
if err != nil {
|
||||
this.eof = true
|
||||
this.current = nil
|
||||
}
|
||||
|
||||
@@ -154,13 +154,14 @@ func (this *HttpProxyServer) transport(input io.Reader, output io.Writer, ray ra
|
||||
defer wg.Wait()
|
||||
|
||||
go func() {
|
||||
v2io.RawReaderToChan(ray.InboundInput(), input)
|
||||
close(ray.InboundInput())
|
||||
v2io.Pipe(v2io.NewAdaptiveReader(input), ray.InboundInput())
|
||||
ray.InboundInput().Close()
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
go func() {
|
||||
v2io.ChanToRawWriter(output, ray.InboundOutput())
|
||||
v2io.Pipe(ray.InboundOutput(), v2io.NewAdaptiveWriter(output))
|
||||
ray.InboundOutput().Release()
|
||||
wg.Done()
|
||||
}()
|
||||
}
|
||||
@@ -222,7 +223,7 @@ func (this *HttpProxyServer) handlePlainHTTP(request *http.Request, dest v2net.D
|
||||
|
||||
packet := v2net.NewPacket(dest, requestBuffer, true)
|
||||
ray := this.packetDispatcher.DispatchToOutbound(packet)
|
||||
defer close(ray.InboundInput())
|
||||
defer ray.InboundInput().Close()
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
|
||||
@@ -204,7 +204,7 @@ func (this *Shadowsocks) handleConnection(conn *hub.TCPConn) {
|
||||
var writeFinish sync.Mutex
|
||||
writeFinish.Lock()
|
||||
go func() {
|
||||
if payload, ok := <-ray.InboundOutput(); ok {
|
||||
if payload, err := ray.InboundOutput().Read(); err == nil {
|
||||
payload.SliceBack(ivLen)
|
||||
rand.Read(payload.Value[:ivLen])
|
||||
|
||||
@@ -219,7 +219,8 @@ func (this *Shadowsocks) handleConnection(conn *hub.TCPConn) {
|
||||
payload.Release()
|
||||
|
||||
writer := crypto.NewCryptionWriter(stream, conn)
|
||||
v2io.ChanToRawWriter(writer, ray.InboundOutput())
|
||||
v2io.Pipe(ray.InboundOutput(), v2io.NewAdaptiveWriter(writer))
|
||||
ray.InboundOutput().Release()
|
||||
}
|
||||
writeFinish.Unlock()
|
||||
}()
|
||||
@@ -232,8 +233,8 @@ func (this *Shadowsocks) handleConnection(conn *hub.TCPConn) {
|
||||
payloadReader = v2io.NewAdaptiveReader(reader)
|
||||
}
|
||||
|
||||
v2io.ReaderToChan(ray.InboundInput(), payloadReader)
|
||||
close(ray.InboundInput())
|
||||
v2io.Pipe(payloadReader, ray.InboundInput())
|
||||
ray.InboundInput().Close()
|
||||
payloadReader.Release()
|
||||
|
||||
writeFinish.Lock()
|
||||
|
||||
@@ -276,14 +276,15 @@ func (this *SocksServer) transport(reader io.Reader, writer io.Writer, firstPack
|
||||
outputFinish.Lock()
|
||||
|
||||
go func() {
|
||||
v2io.RawReaderToChan(input, reader)
|
||||
v2io.Pipe(v2io.NewAdaptiveReader(reader), input)
|
||||
inputFinish.Unlock()
|
||||
close(input)
|
||||
input.Close()
|
||||
}()
|
||||
|
||||
go func() {
|
||||
v2io.ChanToRawWriter(writer, output)
|
||||
v2io.Pipe(output, v2io.NewAdaptiveWriter(writer))
|
||||
outputFinish.Unlock()
|
||||
output.Release()
|
||||
}()
|
||||
outputFinish.Lock()
|
||||
}
|
||||
|
||||
@@ -42,13 +42,14 @@ func (this *InboundConnectionHandler) Communicate(packet v2net.Packet) error {
|
||||
writeFinish.Lock()
|
||||
|
||||
go func() {
|
||||
v2io.RawReaderToChan(input, this.ConnInput)
|
||||
close(input)
|
||||
v2io.Pipe(v2io.NewAdaptiveReader(this.ConnInput), input)
|
||||
input.Close()
|
||||
readFinish.Unlock()
|
||||
}()
|
||||
|
||||
go func() {
|
||||
v2io.ChanToRawWriter(this.ConnOutput, output)
|
||||
v2io.Pipe(output, v2io.NewAdaptiveWriter(this.ConnOutput))
|
||||
output.Release()
|
||||
writeFinish.Unlock()
|
||||
}()
|
||||
|
||||
|
||||
@@ -33,15 +33,16 @@ func (this *OutboundConnectionHandler) Dispatch(packet v2net.Packet, ray ray.Out
|
||||
writeFinish.Lock()
|
||||
|
||||
go func() {
|
||||
v2io.ChanToRawWriter(this.ConnOutput, input)
|
||||
v2io.Pipe(input, v2io.NewAdaptiveWriter(this.ConnOutput))
|
||||
writeFinish.Unlock()
|
||||
input.Release()
|
||||
}()
|
||||
|
||||
writeFinish.Lock()
|
||||
}
|
||||
|
||||
v2io.RawReaderToChan(output, this.ConnInput)
|
||||
close(output)
|
||||
v2io.Pipe(v2io.NewAdaptiveReader(this.ConnInput), output)
|
||||
output.Close()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -145,7 +145,7 @@ func (this *VMessInboundHandler) HandleConnection(connection *hub.TCPConn) {
|
||||
connReader.SetTimeOut(userSettings.PayloadReadTimeout)
|
||||
reader.SetCached(false)
|
||||
go func() {
|
||||
defer close(input)
|
||||
defer input.Close()
|
||||
defer readFinish.Unlock()
|
||||
bodyReader := session.DecodeRequestBody(reader)
|
||||
var requestReader v2io.Reader
|
||||
@@ -154,7 +154,7 @@ func (this *VMessInboundHandler) HandleConnection(connection *hub.TCPConn) {
|
||||
} else {
|
||||
requestReader = v2io.NewAdaptiveReader(bodyReader)
|
||||
}
|
||||
v2io.ReaderToChan(input, requestReader)
|
||||
v2io.Pipe(requestReader, input)
|
||||
requestReader.Release()
|
||||
}()
|
||||
|
||||
@@ -170,7 +170,7 @@ func (this *VMessInboundHandler) HandleConnection(connection *hub.TCPConn) {
|
||||
bodyWriter := session.EncodeResponseBody(writer)
|
||||
|
||||
// Optimize for small response packet
|
||||
if data, open := <-output; open {
|
||||
if data, err := output.Read(); err == nil {
|
||||
if request.Option.IsChunkStream() {
|
||||
vmessio.Authenticate(data)
|
||||
}
|
||||
@@ -183,7 +183,8 @@ func (this *VMessInboundHandler) HandleConnection(connection *hub.TCPConn) {
|
||||
if request.Option.IsChunkStream() {
|
||||
writer = vmessio.NewAuthChunkWriter(writer)
|
||||
}
|
||||
v2io.ChanToWriter(writer, output)
|
||||
v2io.Pipe(output, writer)
|
||||
output.Release()
|
||||
writer.Release()
|
||||
finish.Unlock()
|
||||
}(&writeFinish)
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"sync"
|
||||
|
||||
"github.com/v2ray/v2ray-core/app"
|
||||
"github.com/v2ray/v2ray-core/common/alloc"
|
||||
v2io "github.com/v2ray/v2ray-core/common/io"
|
||||
"github.com/v2ray/v2ray-core/common/log"
|
||||
v2net "github.com/v2ray/v2ray-core/common/net"
|
||||
@@ -60,7 +59,7 @@ func (this *VMessOutboundHandler) startCommunicate(request *proto.RequestHeader,
|
||||
if err != nil {
|
||||
log.Error("Failed to open ", dest, ": ", err)
|
||||
if ray != nil {
|
||||
close(ray.OutboundOutput())
|
||||
ray.OutboundOutput().Close()
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -83,10 +82,12 @@ func (this *VMessOutboundHandler) startCommunicate(request *proto.RequestHeader,
|
||||
requestFinish.Lock()
|
||||
conn.CloseWrite()
|
||||
responseFinish.Lock()
|
||||
output.Close()
|
||||
input.Release()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *VMessOutboundHandler) handleRequest(session *raw.ClientSession, conn net.Conn, request *proto.RequestHeader, firstPacket v2net.Packet, input <-chan *alloc.Buffer, finish *sync.Mutex) {
|
||||
func (this *VMessOutboundHandler) handleRequest(session *raw.ClientSession, conn net.Conn, request *proto.RequestHeader, firstPacket v2net.Packet, input v2io.Reader, finish *sync.Mutex) {
|
||||
defer finish.Unlock()
|
||||
|
||||
writer := v2io.NewBufferedWriter(conn)
|
||||
@@ -97,15 +98,6 @@ func (this *VMessOutboundHandler) handleRequest(session *raw.ClientSession, conn
|
||||
firstChunk := firstPacket.Chunk()
|
||||
moreChunks := firstPacket.MoreChunks()
|
||||
|
||||
for firstChunk == nil && moreChunks {
|
||||
firstChunk, moreChunks = <-input
|
||||
}
|
||||
|
||||
if firstChunk == nil && !moreChunks {
|
||||
log.Warning("VMessOut: Nothing to send. Existing...")
|
||||
return
|
||||
}
|
||||
|
||||
if request.Option.IsChunkStream() {
|
||||
vmessio.Authenticate(firstChunk)
|
||||
}
|
||||
@@ -121,15 +113,14 @@ func (this *VMessOutboundHandler) handleRequest(session *raw.ClientSession, conn
|
||||
if request.Option.IsChunkStream() {
|
||||
streamWriter = vmessio.NewAuthChunkWriter(streamWriter)
|
||||
}
|
||||
v2io.ChanToWriter(streamWriter, input)
|
||||
v2io.Pipe(input, streamWriter)
|
||||
streamWriter.Release()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (this *VMessOutboundHandler) handleResponse(session *raw.ClientSession, conn net.Conn, request *proto.RequestHeader, dest v2net.Destination, output chan<- *alloc.Buffer, finish *sync.Mutex) {
|
||||
func (this *VMessOutboundHandler) handleResponse(session *raw.ClientSession, conn net.Conn, request *proto.RequestHeader, dest v2net.Destination, output v2io.Writer, finish *sync.Mutex) {
|
||||
defer finish.Unlock()
|
||||
defer close(output)
|
||||
|
||||
reader := v2io.NewBufferedReader(conn)
|
||||
defer reader.Release()
|
||||
@@ -151,7 +142,7 @@ func (this *VMessOutboundHandler) handleResponse(session *raw.ClientSession, con
|
||||
bodyReader = v2io.NewAdaptiveReader(decryptReader)
|
||||
}
|
||||
|
||||
v2io.ReaderToChan(output, bodyReader)
|
||||
v2io.Pipe(bodyReader, output)
|
||||
bodyReader.Release()
|
||||
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user