Kaynağa Gözat

move framemeta onto stack

Darien Raymond 7 yıl önce
ebeveyn
işleme
f9f8c21a07

+ 31 - 11
app/proxyman/mux/frame.go

@@ -1,6 +1,8 @@
 package mux
 
 import (
+	"io"
+
 	"v2ray.com/core/common"
 	"v2ray.com/core/common/bitmask"
 	"v2ray.com/core/common/buf"
@@ -86,18 +88,36 @@ func (f FrameMetadata) WriteTo(b *buf.Buffer) error {
 	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.
-func ReadFrameFrom(b *buf.Buffer) (*FrameMetadata, error) {
+func (f *FrameMetadata) ReadFromBuffer(b *buf.Buffer) error {
 	if b.Len() < 4 {
-		return nil, newError("insufficient buffer: ", b.Len())
+		return newError("insufficient buffer: ", b.Len())
 	}
 
-	f := &FrameMetadata{
-		SessionID:     serial.BytesToUint16(b.BytesTo(2)),
-		SessionStatus: SessionStatus(b.Byte(2)),
-		Option:        bitmask.Byte(b.Byte(3)),
-	}
+	f.SessionID = serial.BytesToUint16(b.BytesTo(2))
+	f.SessionStatus = SessionStatus(b.Byte(2))
+	f.Option = bitmask.Byte(b.Byte(3))
+	f.Target.Network = net.Network_Unknown
 
 	if f.SessionStatus == SessionStatusNew {
 		network := TargetNetwork(b.Byte(4))
@@ -105,7 +125,7 @@ func ReadFrameFrom(b *buf.Buffer) (*FrameMetadata, error) {
 
 		addr, port, err := addrParser.ReadAddressPort(nil, b)
 		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 {
@@ -114,9 +134,9 @@ func ReadFrameFrom(b *buf.Buffer) (*FrameMetadata, error) {
 		case TargetNetworkUDP:
 			f.Target = net.UDPDestination(addr, port)
 		default:
-			return nil, newError("unknown network type: ", network)
+			return newError("unknown network type: ", network)
 		}
 	}
 
-	return f, nil
+	return nil
 }

+ 16 - 12
app/proxyman/mux/mux.go

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

+ 10 - 10
app/proxyman/mux/mux_test.go

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

+ 0 - 19
app/proxyman/mux/reader.go

@@ -8,25 +8,6 @@ import (
 	"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.
 type PacketReader struct {
 	reader io.Reader