Browse Source

move framemeta onto stack

pull/1289/head
Darien Raymond 6 years ago
parent
commit
f9f8c21a07
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169
  1. 42
      app/proxyman/mux/frame.go
  2. 28
      app/proxyman/mux/mux.go
  3. 20
      app/proxyman/mux/mux_test.go
  4. 19
      app/proxyman/mux/reader.go

42
app/proxyman/mux/frame.go

@ -1,6 +1,8 @@
package mux package mux
import ( import (
"io"
"v2ray.com/core/common" "v2ray.com/core/common"
"v2ray.com/core/common/bitmask" "v2ray.com/core/common/bitmask"
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
@ -86,18 +88,36 @@ func (f FrameMetadata) WriteTo(b *buf.Buffer) error {
return nil return nil
} }
// ReadFrameFrom reads a FrameMetadata from the given buffer. // ReadFrom reads FrameMetadata from the given reader.
func (f *FrameMetadata) ReadFrom(reader io.Reader) error {
metaLen, err := serial.ReadUint16(reader)
if err != nil {
return err
}
if metaLen > 512 {
return newError("invalid metalen ", metaLen).AtError()
}
b := buf.New()
defer b.Release()
if err := b.Reset(buf.ReadFullFrom(reader, int32(metaLen))); err != nil {
return err
}
return f.ReadFromBuffer(b)
}
// ReadFromBuffer reads a FrameMetadata from the given buffer.
// Visible for testing only. // Visible for testing only.
func ReadFrameFrom(b *buf.Buffer) (*FrameMetadata, error) { func (f *FrameMetadata) ReadFromBuffer(b *buf.Buffer) error {
if b.Len() < 4 { if b.Len() < 4 {
return nil, newError("insufficient buffer: ", b.Len()) return newError("insufficient buffer: ", b.Len())
} }
f := &FrameMetadata{ f.SessionID = serial.BytesToUint16(b.BytesTo(2))
SessionID: serial.BytesToUint16(b.BytesTo(2)), f.SessionStatus = SessionStatus(b.Byte(2))
SessionStatus: SessionStatus(b.Byte(2)), f.Option = bitmask.Byte(b.Byte(3))
Option: bitmask.Byte(b.Byte(3)), f.Target.Network = net.Network_Unknown
}
if f.SessionStatus == SessionStatusNew { if f.SessionStatus == SessionStatusNew {
network := TargetNetwork(b.Byte(4)) network := TargetNetwork(b.Byte(4))
@ -105,7 +125,7 @@ func ReadFrameFrom(b *buf.Buffer) (*FrameMetadata, error) {
addr, port, err := addrParser.ReadAddressPort(nil, b) addr, port, err := addrParser.ReadAddressPort(nil, b)
if err != nil { if err != nil {
return nil, newError("failed to parse address and port").Base(err) return newError("failed to parse address and port").Base(err)
} }
switch network { switch network {
@ -114,9 +134,9 @@ func ReadFrameFrom(b *buf.Buffer) (*FrameMetadata, error) {
case TargetNetworkUDP: case TargetNetworkUDP:
f.Target = net.UDPDestination(addr, port) f.Target = net.UDPDestination(addr, port)
default: default:
return nil, newError("unknown network type: ", network) return newError("unknown network type: ", network)
} }
} }
return f, nil return nil
} }

28
app/proxyman/mux/mux.go

@ -264,8 +264,9 @@ func (m *Client) fetchOutput() {
reader := &buf.BufferedReader{Reader: m.link.Reader} reader := &buf.BufferedReader{Reader: m.link.Reader}
var meta FrameMetadata
for { for {
meta, err := ReadMetadata(reader) err := meta.ReadFrom(reader)
if err != nil { if err != nil {
if errors.Cause(err) != io.EOF { if errors.Cause(err) != io.EOF {
newError("failed to read metadata").Base(err).WriteToLog() newError("failed to read metadata").Base(err).WriteToLog()
@ -275,15 +276,16 @@ func (m *Client) fetchOutput() {
switch meta.SessionStatus { switch meta.SessionStatus {
case SessionStatusKeepAlive: case SessionStatusKeepAlive:
err = m.handleStatueKeepAlive(meta, reader) err = m.handleStatueKeepAlive(&meta, reader)
case SessionStatusEnd: case SessionStatusEnd:
err = m.handleStatusEnd(meta, reader) err = m.handleStatusEnd(&meta, reader)
case SessionStatusNew: case SessionStatusNew:
err = m.handleStatusNew(meta, reader) err = m.handleStatusNew(&meta, reader)
case SessionStatusKeep: case SessionStatusKeep:
err = m.handleStatusKeep(meta, reader) err = m.handleStatusKeep(&meta, reader)
default: default:
newError("unknown status: ", meta.SessionStatus).AtError().WriteToLog() status := meta.SessionStatus
newError("unknown status: ", status).AtError().WriteToLog()
return return
} }
@ -437,22 +439,24 @@ func (w *ServerWorker) handleStatusEnd(meta *FrameMetadata, reader *buf.Buffered
} }
func (w *ServerWorker) handleFrame(ctx context.Context, reader *buf.BufferedReader) error { func (w *ServerWorker) handleFrame(ctx context.Context, reader *buf.BufferedReader) error {
meta, err := ReadMetadata(reader) var meta FrameMetadata
err := meta.ReadFrom(reader)
if err != nil { if err != nil {
return newError("failed to read metadata").Base(err) return newError("failed to read metadata").Base(err)
} }
switch meta.SessionStatus { switch meta.SessionStatus {
case SessionStatusKeepAlive: case SessionStatusKeepAlive:
err = w.handleStatusKeepAlive(meta, reader) err = w.handleStatusKeepAlive(&meta, reader)
case SessionStatusEnd: case SessionStatusEnd:
err = w.handleStatusEnd(meta, reader) err = w.handleStatusEnd(&meta, reader)
case SessionStatusNew: case SessionStatusNew:
err = w.handleStatusNew(ctx, meta, reader) err = w.handleStatusNew(ctx, &meta, reader)
case SessionStatusKeep: case SessionStatusKeep:
err = w.handleStatusKeep(meta, reader) err = w.handleStatusKeep(&meta, reader)
default: default:
return newError("unknown status: ", meta.SessionStatus).AtError() status := meta.SessionStatus
return newError("unknown status: ", status).AtError()
} }
if err != nil { if err != nil {

20
app/proxyman/mux/mux_test.go

@ -61,7 +61,8 @@ func TestReaderWriter(t *testing.T) {
bytesReader := &buf.BufferedReader{Reader: pReader} bytesReader := &buf.BufferedReader{Reader: pReader}
meta, err := ReadMetadata(bytesReader) var meta FrameMetadata
err := meta.ReadFrom(bytesReader)
assert(err, IsNil) assert(err, IsNil)
assert(meta.SessionID, Equals, uint16(1)) assert(meta.SessionID, Equals, uint16(1))
assert(byte(meta.SessionStatus), Equals, byte(SessionStatusNew)) assert(byte(meta.SessionStatus), Equals, byte(SessionStatusNew))
@ -73,14 +74,14 @@ func TestReaderWriter(t *testing.T) {
assert(len(data), Equals, 1) assert(len(data), Equals, 1)
assert(data[0].String(), Equals, "abcd") assert(data[0].String(), Equals, "abcd")
meta, err = ReadMetadata(bytesReader) err = meta.ReadFrom(bytesReader)
assert(err, IsNil) assert(err, IsNil)
assert(byte(meta.SessionStatus), Equals, byte(SessionStatusNew)) assert(byte(meta.SessionStatus), Equals, byte(SessionStatusNew))
assert(meta.SessionID, Equals, uint16(2)) assert(meta.SessionID, Equals, uint16(2))
assert(byte(meta.Option), Equals, byte(0)) assert(byte(meta.Option), Equals, byte(0))
assert(meta.Target, Equals, dest2) assert(meta.Target, Equals, dest2)
meta, err = ReadMetadata(bytesReader) err = meta.ReadFrom(bytesReader)
assert(err, IsNil) assert(err, IsNil)
assert(byte(meta.SessionStatus), Equals, byte(SessionStatusKeep)) assert(byte(meta.SessionStatus), Equals, byte(SessionStatusKeep))
assert(meta.SessionID, Equals, uint16(1)) assert(meta.SessionID, Equals, uint16(1))
@ -91,7 +92,7 @@ func TestReaderWriter(t *testing.T) {
assert(len(data), Equals, 1) assert(len(data), Equals, 1)
assert(data[0].String(), Equals, "efgh") assert(data[0].String(), Equals, "efgh")
meta, err = ReadMetadata(bytesReader) err = meta.ReadFrom(bytesReader)
assert(err, IsNil) assert(err, IsNil)
assert(byte(meta.SessionStatus), Equals, byte(SessionStatusNew)) assert(byte(meta.SessionStatus), Equals, byte(SessionStatusNew))
assert(meta.SessionID, Equals, uint16(3)) assert(meta.SessionID, Equals, uint16(3))
@ -103,19 +104,19 @@ func TestReaderWriter(t *testing.T) {
assert(len(data), Equals, 1) assert(len(data), Equals, 1)
assert(data[0].String(), Equals, "x") assert(data[0].String(), Equals, "x")
meta, err = ReadMetadata(bytesReader) err = meta.ReadFrom(bytesReader)
assert(err, IsNil) assert(err, IsNil)
assert(byte(meta.SessionStatus), Equals, byte(SessionStatusEnd)) assert(byte(meta.SessionStatus), Equals, byte(SessionStatusEnd))
assert(meta.SessionID, Equals, uint16(1)) assert(meta.SessionID, Equals, uint16(1))
assert(byte(meta.Option), Equals, byte(0)) assert(byte(meta.Option), Equals, byte(0))
meta, err = ReadMetadata(bytesReader) err = meta.ReadFrom(bytesReader)
assert(err, IsNil) assert(err, IsNil)
assert(byte(meta.SessionStatus), Equals, byte(SessionStatusEnd)) assert(byte(meta.SessionStatus), Equals, byte(SessionStatusEnd))
assert(meta.SessionID, Equals, uint16(3)) assert(meta.SessionID, Equals, uint16(3))
assert(byte(meta.Option), Equals, byte(0)) assert(byte(meta.Option), Equals, byte(0))
meta, err = ReadMetadata(bytesReader) err = meta.ReadFrom(bytesReader)
assert(err, IsNil) assert(err, IsNil)
assert(byte(meta.SessionStatus), Equals, byte(SessionStatusKeep)) assert(byte(meta.SessionStatus), Equals, byte(SessionStatusKeep))
assert(meta.SessionID, Equals, uint16(2)) assert(meta.SessionID, Equals, uint16(2))
@ -126,7 +127,7 @@ func TestReaderWriter(t *testing.T) {
assert(len(data), Equals, 1) assert(len(data), Equals, 1)
assert(data[0].String(), Equals, "y") assert(data[0].String(), Equals, "y")
meta, err = ReadMetadata(bytesReader) err = meta.ReadFrom(bytesReader)
assert(err, IsNil) assert(err, IsNil)
assert(byte(meta.SessionStatus), Equals, byte(SessionStatusEnd)) assert(byte(meta.SessionStatus), Equals, byte(SessionStatusEnd))
assert(meta.SessionID, Equals, uint16(2)) assert(meta.SessionID, Equals, uint16(2))
@ -134,7 +135,6 @@ func TestReaderWriter(t *testing.T) {
pWriter.Close() pWriter.Close()
meta, err = ReadMetadata(bytesReader) err = meta.ReadFrom(bytesReader)
assert(err, IsNotNil) assert(err, IsNotNil)
assert(meta, IsNil)
} }

19
app/proxyman/mux/reader.go

@ -8,25 +8,6 @@ import (
"v2ray.com/core/common/serial" "v2ray.com/core/common/serial"
) )
// ReadMetadata reads FrameMetadata from the given reader.
func ReadMetadata(reader io.Reader) (*FrameMetadata, error) {
metaLen, err := serial.ReadUint16(reader)
if err != nil {
return nil, err
}
if metaLen > 512 {
return nil, newError("invalid metalen ", metaLen).AtError()
}
b := buf.New()
defer b.Release()
if err := b.Reset(buf.ReadFullFrom(reader, int32(metaLen))); err != nil {
return nil, err
}
return ReadFrameFrom(b)
}
// PacketReader is an io.Reader that reads whole chunk of Mux frames every time. // PacketReader is an io.Reader that reads whole chunk of Mux frames every time.
type PacketReader struct { type PacketReader struct {
reader io.Reader reader io.Reader

Loading…
Cancel
Save