From d8c610263856a91df90973aa3221731bfdb4579e Mon Sep 17 00:00:00 2001 From: Darien Raymond Date: Thu, 21 Jan 2016 16:22:56 +0000 Subject: [PATCH] test case for on demand detour --- proxy/vmess/command/accounts.go | 4 +++- proxy/vmess/inbound/command.go | 1 + proxy/vmess/inbound/inbound.go | 2 +- proxy/vmess/outbound/command.go | 5 ++++- proxy/vmess/outbound/outbound.go | 6 +++--- proxy/vmess/outbound/receiver.go | 11 ++++++----- shell/point/point.go | 8 ++++++-- testing/scenarios/data/test_1_server.json | 8 +++++++- testing/scenarios/socks_end_test.go | 2 +- 9 files changed, 32 insertions(+), 15 deletions(-) diff --git a/proxy/vmess/command/accounts.go b/proxy/vmess/command/accounts.go index 86560b54f..60e06f27c 100644 --- a/proxy/vmess/command/accounts.go +++ b/proxy/vmess/command/accounts.go @@ -58,7 +58,9 @@ func (this *SwitchAccount) Unmarshal(data []byte) error { if len(data) < lenHost+1 { return transport.CorruptedPacket } - this.Host = v2net.ParseAddress(string(data[1 : 1+lenHost])) + if lenHost > 0 { + this.Host = v2net.ParseAddress(string(data[1 : 1+lenHost])) + } portStart := 1 + lenHost if len(data) < portStart+2 { return transport.CorruptedPacket diff --git a/proxy/vmess/inbound/command.go b/proxy/vmess/inbound/command.go index 7a6970fc1..8e5241872 100644 --- a/proxy/vmess/inbound/command.go +++ b/proxy/vmess/inbound/command.go @@ -12,6 +12,7 @@ func (this *VMessInboundHandler) generateCommand(buffer *alloc.Buffer) { defer commandBytes.Release() if this.features != nil && this.features.Detour != nil { + cmd = byte(1) tag := this.features.Detour.ToTag if this.space.HasInboundHandlerManager() { handlerManager := this.space.InboundHandlerManager() diff --git a/proxy/vmess/inbound/inbound.go b/proxy/vmess/inbound/inbound.go index d185c6694..7a12cfc09 100644 --- a/proxy/vmess/inbound/inbound.go +++ b/proxy/vmess/inbound/inbound.go @@ -139,7 +139,7 @@ func (this *VMessInboundHandler) HandleConnection(connection *net.TCPConn) error buffer := alloc.NewLargeBuffer().Clear() defer buffer.Release() buffer.AppendBytes(request.ResponseHeader, byte(0)) - buffer.AppendBytes(byte(0), byte(0)) + this.generateCommand(buffer) if data, open := <-output; open { buffer.Append(data.Value) diff --git a/proxy/vmess/outbound/command.go b/proxy/vmess/outbound/command.go index f3848c7ca..868f61a74 100644 --- a/proxy/vmess/outbound/command.go +++ b/proxy/vmess/outbound/command.go @@ -13,7 +13,7 @@ func (this *VMessOutboundHandler) handleSwitchAccount(cmd *command.SwitchAccount this.receiverManager.AddDetour(NewReceiver(dest, user), cmd.ValidMin) } -func (this *VMessOutboundHandler) handleCommand(cmdId byte, data []byte) { +func (this *VMessOutboundHandler) handleCommand(dest v2net.Destination, cmdId byte, data []byte) { cmd, err := command.CreateResponseCommand(cmdId) if err != nil { log.Warning("VMessOut: Unknown response command (", cmdId, "): ", err) @@ -25,6 +25,9 @@ func (this *VMessOutboundHandler) handleCommand(cmdId byte, data []byte) { } switch typedCommand := cmd.(type) { case *command.SwitchAccount: + if typedCommand.Host == nil { + typedCommand.Host = dest.Address() + } this.handleSwitchAccount(typedCommand) default: } diff --git a/proxy/vmess/outbound/outbound.go b/proxy/vmess/outbound/outbound.go index 97b9e7c96..d808b75f6 100644 --- a/proxy/vmess/outbound/outbound.go +++ b/proxy/vmess/outbound/outbound.go @@ -82,7 +82,7 @@ func (this *VMessOutboundHandler) startCommunicate(request *protocol.VMessReques responseFinish.Lock() go this.handleRequest(conn, request, firstPacket, input, &requestFinish) - go this.handleResponse(conn, request, output, &responseFinish, (request.Command == protocol.CmdUDP)) + go this.handleResponse(conn, request, dest, output, &responseFinish, (request.Command == protocol.CmdUDP)) requestFinish.Lock() conn.CloseWrite() @@ -140,7 +140,7 @@ func headerMatch(request *protocol.VMessRequest, responseHeader byte) bool { return request.ResponseHeader == responseHeader } -func (this *VMessOutboundHandler) handleResponse(conn net.Conn, request *protocol.VMessRequest, output chan<- *alloc.Buffer, finish *sync.Mutex, isUDP bool) { +func (this *VMessOutboundHandler) handleResponse(conn net.Conn, request *protocol.VMessRequest, dest v2net.Destination, output chan<- *alloc.Buffer, finish *sync.Mutex, isUDP bool) { defer finish.Unlock() defer close(output) responseKey := md5.Sum(request.RequestKey[:]) @@ -175,7 +175,7 @@ func (this *VMessOutboundHandler) handleResponse(conn net.Conn, request *protoco } command := buffer.Value[2] data := buffer.Value[4 : 4+dataLen] - go this.handleCommand(command, data) + go this.handleCommand(dest, command, data) responseBegin = 4 + dataLen } diff --git a/proxy/vmess/outbound/receiver.go b/proxy/vmess/outbound/receiver.go index 070789a15..31e20d644 100644 --- a/proxy/vmess/outbound/receiver.go +++ b/proxy/vmess/outbound/receiver.go @@ -58,7 +58,7 @@ type ExpiringReceiver struct { } func (this *ExpiringReceiver) Expired() bool { - return this.until.After(time.Now()) + return this.until.Before(time.Now()) } type ReceiverManager struct { @@ -87,15 +87,16 @@ func (this *ReceiverManager) AddDetour(rec *Receiver, availableMin byte) { for _, u := range rec.Accounts { r.AddUser(u) } + break } } this.detourAccess.RUnlock() - expRec := &ExpiringReceiver{ - Receiver: rec, - until: time.Now().Add(time.Duration(availableMin-1) * time.Minute), - } if !destExists { + expRec := &ExpiringReceiver{ + Receiver: rec, + until: time.Now().Add(time.Duration(availableMin-1) * time.Minute), + } this.detourAccess.Lock() this.detours = append(this.detours, expRec) this.detourAccess.Unlock() diff --git a/shell/point/point.go b/shell/point/point.go index a8452b76e..97efecdf5 100644 --- a/shell/point/point.go +++ b/shell/point/point.go @@ -205,6 +205,10 @@ func (this *Point) FilterPacketAndDispatch(packet v2net.Packet, link ray.Outboun dispatcher.Dispatch(packet, link) } -func (this *Point) GetHandler(tag string) (proxy.InboundConnectionHandler, int) { - return nil, 0 +func (this *Point) GetHandler(context app.Context, tag string) (proxy.InboundConnectionHandler, int) { + handler, found := this.taggedIdh[tag] + if !found { + return nil, 0 + } + return handler.GetConnectionHandler() } diff --git a/testing/scenarios/data/test_1_server.json b/testing/scenarios/data/test_1_server.json index e4b2efd94..92edb66f7 100644 --- a/testing/scenarios/data/test_1_server.json +++ b/testing/scenarios/data/test_1_server.json @@ -14,7 +14,12 @@ "level": 1, "alterId": 10 } - ] + ], + "features": { + "detour": { + "to": "detour" + } + } } }, "outbound": { @@ -25,6 +30,7 @@ { "protocol": "vmess", "port": "50005-50009", + "tag": "detour", "settings": { "clients": [ { diff --git a/testing/scenarios/socks_end_test.go b/testing/scenarios/socks_end_test.go index e5b69c764..0e60fcc7c 100644 --- a/testing/scenarios/socks_end_test.go +++ b/testing/scenarios/socks_end_test.go @@ -33,7 +33,7 @@ func TestTCPConnection(t *testing.T) { socksPort := v2net.Port(50000) - for i := 0; i < 10; i++ { + for i := 0; i < 100; i++ { conn, err := net.DialTCP("tcp", nil, &net.TCPAddr{ IP: []byte{127, 0, 0, 1}, Port: int(socksPort),