1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-06-27 01:45:23 +00:00

move framemeta onto stack

This commit is contained in:
Darien Raymond 2018-09-26 13:01:12 +02:00
parent fce64b1665
commit f9f8c21a07
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169
4 changed files with 58 additions and 53 deletions

View File

@ -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.
// Visible for testing only.
func ReadFrameFrom(b *buf.Buffer) (*FrameMetadata, error) {
if b.Len() < 4 {
return nil, newError("insufficient buffer: ", b.Len())
// 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()
}
f := &FrameMetadata{
SessionID: serial.BytesToUint16(b.BytesTo(2)),
SessionStatus: SessionStatus(b.Byte(2)),
Option: bitmask.Byte(b.Byte(3)),
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 (f *FrameMetadata) ReadFromBuffer(b *buf.Buffer) error {
if b.Len() < 4 {
return newError("insufficient buffer: ", b.Len())
}
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
}

View File

@ -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 {

View File

@ -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)
}

View File

@ -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