1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-09-07 04:24:23 -04:00
v2fly/external/github.com/lucas-clemente/quic-go/packet_unpacker.go

103 lines
3.0 KiB
Go
Raw Normal View History

2018-11-20 17:51:25 -05:00
package quic
import (
"bytes"
2018-11-23 11:04:53 -05:00
"fmt"
2018-11-20 17:51:25 -05:00
2019-01-17 09:33:18 -05:00
"v2ray.com/core/external/github.com/lucas-clemente/quic-go/internal/handshake"
"v2ray.com/core/external/github.com/lucas-clemente/quic-go/internal/protocol"
"v2ray.com/core/external/github.com/lucas-clemente/quic-go/internal/utils"
"v2ray.com/core/external/github.com/lucas-clemente/quic-go/internal/wire"
2018-11-20 17:51:25 -05:00
)
type unpackedPacket struct {
2019-01-02 07:01:06 -05:00
packetNumber protocol.PacketNumber // the decoded packet number
hdr *wire.ExtendedHeader
2018-11-20 17:51:25 -05:00
encryptionLevel protocol.EncryptionLevel
2019-01-14 14:52:10 -05:00
data []byte
2018-11-20 17:51:25 -05:00
}
2018-11-23 11:04:53 -05:00
// The packetUnpacker unpacks QUIC packets.
2018-11-20 17:51:25 -05:00
type packetUnpacker struct {
2019-01-02 07:01:06 -05:00
cs handshake.CryptoSetup
largestRcvdPacketNumber protocol.PacketNumber
2018-11-23 11:04:53 -05:00
version protocol.VersionNumber
2018-11-20 17:51:25 -05:00
}
var _ unpacker = &packetUnpacker{}
2019-01-02 07:01:06 -05:00
func newPacketUnpacker(cs handshake.CryptoSetup, version protocol.VersionNumber) unpacker {
2018-11-20 17:51:25 -05:00
return &packetUnpacker{
2019-01-02 07:01:06 -05:00
cs: cs,
2018-11-23 11:04:53 -05:00
version: version,
2018-11-20 17:51:25 -05:00
}
}
2019-01-02 07:01:06 -05:00
func (u *packetUnpacker) Unpack(hdr *wire.Header, data []byte) (*unpackedPacket, error) {
r := bytes.NewReader(data)
2018-11-20 17:51:25 -05:00
2019-01-02 07:01:06 -05:00
var encLevel protocol.EncryptionLevel
2018-11-23 11:04:53 -05:00
switch hdr.Type {
case protocol.PacketTypeInitial:
2019-01-02 07:01:06 -05:00
encLevel = protocol.EncryptionInitial
2018-11-23 11:04:53 -05:00
case protocol.PacketTypeHandshake:
2019-01-02 07:01:06 -05:00
encLevel = protocol.EncryptionHandshake
2018-11-23 11:04:53 -05:00
default:
if hdr.IsLongHeader {
return nil, fmt.Errorf("unknown packet type: %s", hdr.Type)
}
2019-01-02 07:01:06 -05:00
encLevel = protocol.Encryption1RTT
2018-11-20 17:51:25 -05:00
}
2019-01-02 07:01:06 -05:00
opener, err := u.cs.GetOpener(encLevel)
if err != nil {
return nil, err
}
hdrLen := int(hdr.ParsedLen())
2019-01-14 14:52:10 -05:00
if len(data) < hdrLen+4+16 {
return nil, fmt.Errorf("Packet too small. Expected at least 20 bytes after the header, got %d", len(data)-hdrLen)
}
2019-01-02 07:01:06 -05:00
// The packet number can be up to 4 bytes long, but we won't know the length until we decrypt it.
// 1. save a copy of the 4 bytes
origPNBytes := make([]byte, 4)
copy(origPNBytes, data[hdrLen:hdrLen+4])
// 2. decrypt the header, assuming a 4 byte packet number
opener.DecryptHeader(
data[hdrLen+4:hdrLen+4+16],
&data[0],
data[hdrLen:hdrLen+4],
)
// 3. parse the header (and learn the actual length of the packet number)
extHdr, err := hdr.ParseExtended(r, u.version)
2018-11-20 17:51:25 -05:00
if err != nil {
2019-01-02 07:01:06 -05:00
return nil, fmt.Errorf("error parsing extended header: %s", err)
2018-11-20 17:51:25 -05:00
}
2019-01-14 14:52:10 -05:00
extHdrLen := hdrLen + int(extHdr.PacketNumberLen)
2019-01-02 07:01:06 -05:00
// 4. if the packet number is shorter than 4 bytes, replace the remaining bytes with the copy we saved earlier
if extHdr.PacketNumberLen != protocol.PacketNumberLen4 {
2019-01-14 14:52:10 -05:00
copy(data[extHdrLen:hdrLen+4], origPNBytes[int(extHdr.PacketNumberLen):])
2019-01-02 07:01:06 -05:00
}
pn := protocol.DecodePacketNumber(
extHdr.PacketNumberLen,
u.largestRcvdPacketNumber,
extHdr.PacketNumber,
)
2019-01-14 14:52:10 -05:00
decrypted, err := opener.Open(data[extHdrLen:extHdrLen], data[extHdrLen:], pn, data[:extHdrLen])
2019-01-02 07:01:06 -05:00
if err != nil {
return nil, err
}
// Only do this after decrypting, so we are sure the packet is not attacker-controlled
u.largestRcvdPacketNumber = utils.MaxPacketNumber(u.largestRcvdPacketNumber, pn)
2018-11-20 17:51:25 -05:00
return &unpackedPacket{
2019-01-02 07:01:06 -05:00
hdr: extHdr,
packetNumber: pn,
encryptionLevel: encLevel,
2019-01-14 14:52:10 -05:00
data: decrypted,
2018-11-20 17:51:25 -05:00
}, nil
}