mirror of
https://github.com/XTLS/Xray-core.git
synced 2024-11-10 19:13:11 +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 {
|
||||
return err
|
||||
}
|
||||
if b.UDP != nil {
|
||||
b.Write(f.GlobalID[:])
|
||||
if b.UDP != nil { // make sure it's user's proxy request
|
||||
b.Write(f.GlobalID[:]) // no need to check whether it's empty
|
||||
}
|
||||
} else if b.UDP != nil {
|
||||
b.WriteByte(byte(TargetNetworkUDP))
|
||||
|
@ -126,7 +126,8 @@ func (f *FrameMetadata) UnmarshalFromBuffer(b *buf.Buffer) error {
|
|||
f.Option = bitmask.Byte(b.Byte(3))
|
||||
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 {
|
||||
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) &&
|
||||
f.Target.Network == net.Network_UDP && b.Len() >= 8 {
|
||||
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()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -86,21 +86,21 @@ func (w *PacketWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
|
|||
}
|
||||
|
||||
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 {
|
||||
eb.WriteByte(1) // New
|
||||
eb.WriteByte(1) // Opt
|
||||
eb.WriteByte(2) // UDP
|
||||
AddrParser.WriteAddressPort(eb, w.Dest.Address, w.Dest.Port)
|
||||
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
|
||||
} else {
|
||||
eb.WriteByte(2) // Keep
|
||||
eb.WriteByte(1)
|
||||
eb.WriteByte(1) // Opt
|
||||
if b.UDP != nil {
|
||||
eb.WriteByte(2)
|
||||
eb.WriteByte(2) // UDP
|
||||
AddrParser.WriteAddressPort(eb, b.UDP.Address, b.UDP.Port)
|
||||
}
|
||||
}
|
||||
|
@ -148,9 +148,10 @@ func (r *PacketReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
|
|||
discard := false
|
||||
switch b.Byte(2) {
|
||||
case 2:
|
||||
if l != 4 {
|
||||
if l > 4 && b.Byte(4) == 2 { // MUST check the flag first
|
||||
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 {
|
||||
b.Release()
|
||||
return nil, err
|
||||
|
@ -167,6 +168,7 @@ func (r *PacketReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
|
|||
b.Release()
|
||||
return nil, io.EOF
|
||||
}
|
||||
b.Clear() // in case there is padding (empty bytes) attached
|
||||
if b.Byte(3) == 1 {
|
||||
if _, err := io.ReadFull(r.Reader, r.cache); err != nil {
|
||||
b.Release()
|
||||
|
@ -174,7 +176,6 @@ func (r *PacketReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
|
|||
}
|
||||
length := int32(r.cache[0])<<8 | int32(r.cache[1])
|
||||
if length > 0 {
|
||||
b.Clear()
|
||||
if _, err := b.ReadFullFrom(r.Reader, length); err != nil {
|
||||
b.Release()
|
||||
return nil, err
|
||||
|
|
Loading…
Reference in a new issue