mirror of https://github.com/v2ray/v2ray-core
move framemeta onto stack
parent
fce64b1665
commit
f9f8c21a07
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue