mirror of
https://github.com/SagerNet/sing-box.git
synced 2024-11-16 16:12:22 +08:00
Fix quic sniff irl
This commit is contained in:
parent
730144cc26
commit
4432cc2253
|
@ -12,6 +12,7 @@ import (
|
||||||
"github.com/sagernet/sing-box/adapter"
|
"github.com/sagernet/sing-box/adapter"
|
||||||
"github.com/sagernet/sing-box/common/sniff/internal/qtls"
|
"github.com/sagernet/sing-box/common/sniff/internal/qtls"
|
||||||
C "github.com/sagernet/sing-box/constant"
|
C "github.com/sagernet/sing-box/constant"
|
||||||
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
|
|
||||||
"golang.org/x/crypto/hkdf"
|
"golang.org/x/crypto/hkdf"
|
||||||
)
|
)
|
||||||
|
@ -25,7 +26,7 @@ func QUICClientHello(ctx context.Context, packet []byte) (*adapter.InboundContex
|
||||||
}
|
}
|
||||||
|
|
||||||
if typeByte&0x80 == 0 || typeByte&0x40 == 0 {
|
if typeByte&0x80 == 0 || typeByte&0x40 == 0 {
|
||||||
return nil, os.ErrInvalid
|
return nil, E.New("bad type byte")
|
||||||
}
|
}
|
||||||
var versionNumber uint32
|
var versionNumber uint32
|
||||||
err = binary.Read(reader, binary.BigEndian, &versionNumber)
|
err = binary.Read(reader, binary.BigEndian, &versionNumber)
|
||||||
|
@ -33,13 +34,22 @@ func QUICClientHello(ctx context.Context, packet []byte) (*adapter.InboundContex
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if versionNumber != qtls.VersionDraft29 && versionNumber != qtls.Version1 && versionNumber != qtls.Version2 {
|
if versionNumber != qtls.VersionDraft29 && versionNumber != qtls.Version1 && versionNumber != qtls.Version2 {
|
||||||
return nil, os.ErrInvalid
|
return nil, E.New("bad version")
|
||||||
}
|
}
|
||||||
if (typeByte&0x30)>>4 == 0x0 {
|
if versionNumber == qtls.Version2 {
|
||||||
} else if (typeByte&0x30)>>4 != 0x01 {
|
if (typeByte&0x30)>>4 == 0b01 {
|
||||||
// 0-rtt
|
} else if (typeByte&0x30)>>4 != 0b10 {
|
||||||
|
// 0-rtt
|
||||||
|
} else {
|
||||||
|
return nil, E.New("bad packet type")
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return nil, os.ErrInvalid
|
if (typeByte&0x30)>>4 == 0x0 {
|
||||||
|
} else if (typeByte&0x30)>>4 != 0x01 {
|
||||||
|
// 0-rtt
|
||||||
|
} else {
|
||||||
|
return nil, E.New("bad packet type")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
destConnIDLen, err := reader.ReadByte()
|
destConnIDLen, err := reader.ReadByte()
|
||||||
|
@ -47,6 +57,10 @@ func QUICClientHello(ctx context.Context, packet []byte) (*adapter.InboundContex
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if destConnIDLen == 0 || destConnIDLen > 20 {
|
||||||
|
return nil, E.New("bad destination connection id length")
|
||||||
|
}
|
||||||
|
|
||||||
destConnID := make([]byte, destConnIDLen)
|
destConnID := make([]byte, destConnIDLen)
|
||||||
_, err = io.ReadFull(reader, destConnID)
|
_, err = io.ReadFull(reader, destConnID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -79,7 +93,7 @@ func QUICClientHello(ctx context.Context, packet []byte) (*adapter.InboundContex
|
||||||
}
|
}
|
||||||
|
|
||||||
hdrLen := int(reader.Size()) - reader.Len()
|
hdrLen := int(reader.Size()) - reader.Len()
|
||||||
if hdrLen != len(packet)-int(packetLen) {
|
if hdrLen+int(packetLen) > len(packet) {
|
||||||
return nil, os.ErrInvalid
|
return nil, os.ErrInvalid
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,17 +140,25 @@ func QUICClientHello(ctx context.Context, packet []byte) (*adapter.InboundContex
|
||||||
newPacket[hdrLen+i] ^= mask[i+1]
|
newPacket[hdrLen+i] ^= mask[i+1]
|
||||||
}
|
}
|
||||||
packetNumberLength := newPacket[0]&0x3 + 1
|
packetNumberLength := newPacket[0]&0x3 + 1
|
||||||
if packetNumberLength != 1 {
|
if hdrLen+int(packetNumberLength) > int(packetLen)+hdrLen {
|
||||||
return nil, os.ErrInvalid
|
return nil, os.ErrInvalid
|
||||||
}
|
}
|
||||||
packetNumber := newPacket[hdrLen]
|
var packetNumber uint32
|
||||||
if err != nil {
|
switch packetNumberLength {
|
||||||
return nil, err
|
case 1:
|
||||||
|
packetNumber = uint32(newPacket[hdrLen])
|
||||||
|
case 2:
|
||||||
|
packetNumber = uint32(binary.BigEndian.Uint16(newPacket[hdrLen:]))
|
||||||
|
case 3:
|
||||||
|
packetNumber = uint32(newPacket[hdrLen+2]) | uint32(newPacket[hdrLen+1])<<8 | uint32(newPacket[hdrLen])<<16
|
||||||
|
case 4:
|
||||||
|
packetNumber = binary.BigEndian.Uint32(newPacket[hdrLen:])
|
||||||
|
default:
|
||||||
|
return nil, E.New("bad packet number length")
|
||||||
}
|
}
|
||||||
if packetNumber != 0 {
|
if packetNumber != 0 {
|
||||||
return nil, os.ErrInvalid
|
return nil, E.New("bad packet number: ", packetNumber)
|
||||||
}
|
}
|
||||||
|
|
||||||
extHdrLen := hdrLen + int(packetNumberLength)
|
extHdrLen := hdrLen + int(packetNumberLength)
|
||||||
copy(newPacket[extHdrLen:hdrLen+4], packet[extHdrLen:])
|
copy(newPacket[extHdrLen:hdrLen+4], packet[extHdrLen:])
|
||||||
data := newPacket[extHdrLen : int(packetLen)+hdrLen]
|
data := newPacket[extHdrLen : int(packetLen)+hdrLen]
|
||||||
|
@ -166,6 +188,13 @@ func QUICClientHello(ctx context.Context, packet []byte) (*adapter.InboundContex
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
for frameType == 0x0 {
|
||||||
|
// skip padding
|
||||||
|
frameType, err = decryptedReader.ReadByte()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
if frameType != 0x6 {
|
if frameType != 0x6 {
|
||||||
// not crypto frame
|
// not crypto frame
|
||||||
return &adapter.InboundContext{Protocol: C.ProtocolQUIC}, nil
|
return &adapter.InboundContext{Protocol: C.ProtocolQUIC}, nil
|
||||||
|
|
|
@ -28,6 +28,7 @@ func PeekPacket(ctx context.Context, packet []byte, sniffers ...PacketSniffer) (
|
||||||
for _, sniffer := range sniffers {
|
for _, sniffer := range sniffers {
|
||||||
sniffMetadata, err := sniffer(ctx, packet)
|
sniffMetadata, err := sniffer(ctx, packet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
println(err.Error())
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return sniffMetadata, nil
|
return sniffMetadata, nil
|
||||||
|
|
Loading…
Reference in New Issue
Block a user