mirror of
https://github.com/XTLS/Xray-core.git
synced 2024-11-13 04:03:19 +00:00
XUDP practice: MUST check the flag first & Add more comments
This commit is contained in:
parent
9f8e9e8e64
commit
b4c1a56026
|
@ -82,8 +82,8 @@ func (f FrameMetadata) WriteTo(b *buf.Buffer) error {
|
||||||
if err := addrParser.WriteAddressPort(b, f.Target.Address, f.Target.Port); err != nil {
|
if err := addrParser.WriteAddressPort(b, f.Target.Address, f.Target.Port); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if b.UDP != nil {
|
if b.UDP != nil { // make sure it's user's proxy request
|
||||||
b.Write(f.GlobalID[:])
|
b.Write(f.GlobalID[:]) // no need to check whether it's empty
|
||||||
}
|
}
|
||||||
} else if b.UDP != nil {
|
} else if b.UDP != nil {
|
||||||
b.WriteByte(byte(TargetNetworkUDP))
|
b.WriteByte(byte(TargetNetworkUDP))
|
||||||
|
@ -126,7 +126,8 @@ func (f *FrameMetadata) UnmarshalFromBuffer(b *buf.Buffer) error {
|
||||||
f.Option = bitmask.Byte(b.Byte(3))
|
f.Option = bitmask.Byte(b.Byte(3))
|
||||||
f.Target.Network = net.Network_Unknown
|
f.Target.Network = net.Network_Unknown
|
||||||
|
|
||||||
if f.SessionStatus == SessionStatusNew || (f.SessionStatus == SessionStatusKeep && b.Len() != 4) {
|
if f.SessionStatus == SessionStatusNew || (f.SessionStatus == SessionStatusKeep && b.Len() > 4 &&
|
||||||
|
TargetNetwork(b.Byte(4)) == TargetNetworkUDP) { // MUST check the flag first
|
||||||
if b.Len() < 8 {
|
if b.Len() < 8 {
|
||||||
return newError("insufficient buffer: ", b.Len())
|
return newError("insufficient buffer: ", b.Len())
|
||||||
}
|
}
|
||||||
|
@ -148,6 +149,7 @@ func (f *FrameMetadata) UnmarshalFromBuffer(b *buf.Buffer) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Application data is essential, to test whether the pipe is closed.
|
||||||
if f.SessionStatus == SessionStatusNew && f.Option.Has(OptionData) &&
|
if f.SessionStatus == SessionStatusNew && f.Option.Has(OptionData) &&
|
||||||
f.Target.Network == net.Network_UDP && b.Len() >= 8 {
|
f.Target.Network == net.Network_UDP && b.Len() >= 8 {
|
||||||
copy(f.GlobalID[:], b.Bytes())
|
copy(f.GlobalID[:], b.Bytes())
|
||||||
|
|
|
@ -138,7 +138,7 @@ func (w *ServerWorker) handleStatusNew(ctx context.Context, meta *FrameMetadata,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if meta.GlobalID != [8]byte{} {
|
if meta.GlobalID != [8]byte{} { // MUST ignore empty Global ID
|
||||||
mb, err := NewPacketReader(reader, &meta.Target).ReadMultiBuffer()
|
mb, err := NewPacketReader(reader, &meta.Target).ReadMultiBuffer()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -86,21 +86,21 @@ func (w *PacketWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
eb := buf.New()
|
eb := buf.New()
|
||||||
eb.Write([]byte{0, 0, 0, 0})
|
eb.Write([]byte{0, 0, 0, 0}) // Meta data length; Mux Session ID
|
||||||
if w.Dest.Network == net.Network_UDP {
|
if w.Dest.Network == net.Network_UDP {
|
||||||
eb.WriteByte(1) // New
|
eb.WriteByte(1) // New
|
||||||
eb.WriteByte(1) // Opt
|
eb.WriteByte(1) // Opt
|
||||||
eb.WriteByte(2) // UDP
|
eb.WriteByte(2) // UDP
|
||||||
AddrParser.WriteAddressPort(eb, w.Dest.Address, w.Dest.Port)
|
AddrParser.WriteAddressPort(eb, w.Dest.Address, w.Dest.Port)
|
||||||
if b.UDP != nil { // make sure it's user's proxy request
|
if b.UDP != nil { // make sure it's user's proxy request
|
||||||
eb.Write(w.GlobalID[:])
|
eb.Write(w.GlobalID[:]) // no need to check whether it's empty
|
||||||
}
|
}
|
||||||
w.Dest.Network = net.Network_Unknown
|
w.Dest.Network = net.Network_Unknown
|
||||||
} else {
|
} else {
|
||||||
eb.WriteByte(2) // Keep
|
eb.WriteByte(2) // Keep
|
||||||
eb.WriteByte(1)
|
eb.WriteByte(1) // Opt
|
||||||
if b.UDP != nil {
|
if b.UDP != nil {
|
||||||
eb.WriteByte(2)
|
eb.WriteByte(2) // UDP
|
||||||
AddrParser.WriteAddressPort(eb, b.UDP.Address, b.UDP.Port)
|
AddrParser.WriteAddressPort(eb, b.UDP.Address, b.UDP.Port)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -148,9 +148,10 @@ func (r *PacketReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
|
||||||
discard := false
|
discard := false
|
||||||
switch b.Byte(2) {
|
switch b.Byte(2) {
|
||||||
case 2:
|
case 2:
|
||||||
if l != 4 {
|
if l > 4 && b.Byte(4) == 2 { // MUST check the flag first
|
||||||
b.Advance(5)
|
b.Advance(5)
|
||||||
addr, port, err := AddrParser.ReadAddressPort(nil, b) // read addr will read all content and clear b
|
// b.Clear() will be called automatically if all data had been read.
|
||||||
|
addr, port, err := AddrParser.ReadAddressPort(nil, b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Release()
|
b.Release()
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -167,6 +168,7 @@ func (r *PacketReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
|
||||||
b.Release()
|
b.Release()
|
||||||
return nil, io.EOF
|
return nil, io.EOF
|
||||||
}
|
}
|
||||||
|
b.Clear() // in case there is padding (empty bytes) attached
|
||||||
if b.Byte(3) == 1 {
|
if b.Byte(3) == 1 {
|
||||||
if _, err := io.ReadFull(r.Reader, r.cache); err != nil {
|
if _, err := io.ReadFull(r.Reader, r.cache); err != nil {
|
||||||
b.Release()
|
b.Release()
|
||||||
|
@ -174,7 +176,6 @@ func (r *PacketReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
|
||||||
}
|
}
|
||||||
length := int32(r.cache[0])<<8 | int32(r.cache[1])
|
length := int32(r.cache[0])<<8 | int32(r.cache[1])
|
||||||
if length > 0 {
|
if length > 0 {
|
||||||
b.Clear()
|
|
||||||
if _, err := b.ReadFullFrom(r.Reader, length); err != nil {
|
if _, err := b.ReadFullFrom(r.Reader, length); err != nil {
|
||||||
b.Release()
|
b.Release()
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
Loading…
Reference in a new issue