mirror of
https://github.com/v2fly/v2ray-core.git
synced 2024-12-22 01:57:12 -05:00
implement ReadMultiBuffer in quic conn
This commit is contained in:
parent
d649de172e
commit
61ad81c326
@ -142,6 +142,29 @@ func (c *interConn) Read(b []byte) (int, error) {
|
||||
return c.stream.Read(b)
|
||||
}
|
||||
|
||||
func (c *interConn) ReadMultiBuffer() (buf.MultiBuffer, error) {
|
||||
mb := make(buf.MultiBuffer, 0, 8)
|
||||
{
|
||||
b := buf.New()
|
||||
if _, err := b.ReadFrom(c.stream); err != nil {
|
||||
b.Release()
|
||||
return nil, err
|
||||
}
|
||||
mb = append(mb, b)
|
||||
}
|
||||
|
||||
for c.stream.HasMoreData() {
|
||||
b := buf.New()
|
||||
if _, err := b.ReadFrom(c.stream); err != nil {
|
||||
b.Release()
|
||||
break
|
||||
}
|
||||
mb = append(mb, b)
|
||||
}
|
||||
|
||||
return mb, nil
|
||||
}
|
||||
|
||||
func (c *interConn) WriteMultiBuffer(mb buf.MultiBuffer) error {
|
||||
if mb.IsEmpty() {
|
||||
return nil
|
||||
|
10
vendor/github.com/lucas-clemente/quic-go/internal/protocol/params.go
generated
vendored
10
vendor/github.com/lucas-clemente/quic-go/internal/protocol/params.go
generated
vendored
@ -8,13 +8,6 @@ const MaxPacketSizeIPv4 = 1252
|
||||
// MaxPacketSizeIPv6 is the maximum packet size that we use for sending IPv6 packets.
|
||||
const MaxPacketSizeIPv6 = 1232
|
||||
|
||||
// MinStatelessResetSize is the minimum size of a stateless reset packet
|
||||
const MinStatelessResetSize = 1 + 20 + 16
|
||||
|
||||
// NonForwardSecurePacketSizeReduction is the number of bytes a non forward-secure packet has to be smaller than a forward-secure packet
|
||||
// This makes sure that those packets can always be retransmitted without splitting the contained StreamFrames
|
||||
const NonForwardSecurePacketSizeReduction = 50
|
||||
|
||||
const defaultMaxCongestionWindowPackets = 1000
|
||||
|
||||
// DefaultMaxCongestionWindow is the default for the max congestion window
|
||||
@ -23,8 +16,7 @@ const DefaultMaxCongestionWindow ByteCount = defaultMaxCongestionWindowPackets *
|
||||
// InitialCongestionWindow is the initial congestion window in QUIC packets
|
||||
const InitialCongestionWindow ByteCount = 32 * DefaultTCPMSS
|
||||
|
||||
// MaxUndecryptablePackets limits the number of undecryptable packets that a
|
||||
// session queues for later until it sends a public reset.
|
||||
// MaxUndecryptablePackets limits the number of undecryptable packets that are queued in the session.
|
||||
const MaxUndecryptablePackets = 10
|
||||
|
||||
// ConnectionFlowControlMultiplier determines how much larger the connection flow control windows needs to be relative to any stream's flow control window
|
||||
|
3
vendor/github.com/lucas-clemente/quic-go/internal/protocol/protocol.go
generated
vendored
3
vendor/github.com/lucas-clemente/quic-go/internal/protocol/protocol.go
generated
vendored
@ -58,5 +58,8 @@ const DefaultTCPMSS ByteCount = 1460
|
||||
// MinInitialPacketSize is the minimum size an Initial packet is required to have.
|
||||
const MinInitialPacketSize = 1200
|
||||
|
||||
// MinStatelessResetSize is the minimum size of a stateless reset packet
|
||||
const MinStatelessResetSize = 1 /* first byte */ + 22 /* random bytes */ + 16 /* token */
|
||||
|
||||
// MinConnectionIDLenInitial is the minimum length of the destination connection ID on an Initial packet.
|
||||
const MinConnectionIDLenInitial = 8
|
||||
|
93
vendor/github.com/lucas-clemente/quic-go/packet_packer.go
generated
vendored
93
vendor/github.com/lucas-clemente/quic-go/packet_packer.go
generated
vendored
@ -96,7 +96,6 @@ type packetPacker struct {
|
||||
acks ackFrameSource
|
||||
|
||||
maxPacketSize protocol.ByteCount
|
||||
hasSentPacket bool // has the packetPacker already sent a packet
|
||||
numNonRetransmittableAcks int
|
||||
}
|
||||
|
||||
@ -168,14 +167,12 @@ func (p *packetPacker) MaybePackAckPacket() (*packedPacket, error) {
|
||||
// For packets sent after completion of the handshake, it might happen that 2 packets have to be sent.
|
||||
// This can happen e.g. when a longer packet number is used in the header.
|
||||
func (p *packetPacker) PackRetransmission(packet *ackhandler.Packet) ([]*packedPacket, error) {
|
||||
if packet.EncryptionLevel != protocol.Encryption1RTT {
|
||||
p, err := p.packHandshakeRetransmission(packet)
|
||||
return []*packedPacket{p}, err
|
||||
}
|
||||
|
||||
var controlFrames []wire.Frame
|
||||
var streamFrames []*wire.StreamFrame
|
||||
for _, f := range packet.Frames {
|
||||
// CRYPTO frames are treated as control frames here.
|
||||
// Since we're making sure that the header can never be larger for a retransmission,
|
||||
// we never have to split CRYPTO frames.
|
||||
if sf, ok := f.(*wire.StreamFrame); ok {
|
||||
sf.DataLenPresent = true
|
||||
streamFrames = append(streamFrames, sf)
|
||||
@ -244,27 +241,6 @@ func (p *packetPacker) PackRetransmission(packet *ackhandler.Packet) ([]*packedP
|
||||
return packets, nil
|
||||
}
|
||||
|
||||
// packHandshakeRetransmission retransmits a handshake packet
|
||||
func (p *packetPacker) packHandshakeRetransmission(packet *ackhandler.Packet) (*packedPacket, error) {
|
||||
sealer, err := p.cryptoSetup.GetSealerWithEncryptionLevel(packet.EncryptionLevel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// make sure that the retransmission for an Initial packet is sent as an Initial packet
|
||||
if packet.PacketType == protocol.PacketTypeInitial {
|
||||
p.hasSentPacket = false
|
||||
}
|
||||
header := p.getHeader(packet.EncryptionLevel)
|
||||
header.Type = packet.PacketType
|
||||
raw, err := p.writeAndSealPacket(header, packet.Frames, sealer)
|
||||
return &packedPacket{
|
||||
header: header,
|
||||
raw: raw,
|
||||
frames: packet.Frames,
|
||||
encryptionLevel: packet.EncryptionLevel,
|
||||
}, err
|
||||
}
|
||||
|
||||
// PackPacket packs a new packet
|
||||
// the other controlFrames are sent in the next packet, but might be queued and sent in the next packet if the packet would overflow MaxPacketSize otherwise
|
||||
func (p *packetPacker) PackPacket() (*packedPacket, error) {
|
||||
@ -275,10 +251,6 @@ func (p *packetPacker) PackPacket() (*packedPacket, error) {
|
||||
if packet != nil {
|
||||
return packet, nil
|
||||
}
|
||||
// if this is the first packet to be send, make sure it contains stream data
|
||||
if !p.hasSentPacket && packet == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
encLevel, sealer := p.cryptoSetup.GetSealer()
|
||||
header := p.getHeader(encLevel)
|
||||
@ -288,7 +260,7 @@ func (p *packetPacker) PackPacket() (*packedPacket, error) {
|
||||
}
|
||||
|
||||
maxSize := p.maxPacketSize - protocol.ByteCount(sealer.Overhead()) - headerLen
|
||||
frames, err := p.composeNextPacket(maxSize, p.canSendData(encLevel))
|
||||
frames, err := p.composeNextPacket(maxSize)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -360,10 +332,7 @@ func (p *packetPacker) maybePackCryptoPacket() (*packedPacket, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *packetPacker) composeNextPacket(
|
||||
maxFrameSize protocol.ByteCount,
|
||||
canSendStreamFrames bool,
|
||||
) ([]wire.Frame, error) {
|
||||
func (p *packetPacker) composeNextPacket(maxFrameSize protocol.ByteCount) ([]wire.Frame, error) {
|
||||
var length protocol.ByteCount
|
||||
var frames []wire.Frame
|
||||
|
||||
@ -377,10 +346,6 @@ func (p *packetPacker) composeNextPacket(
|
||||
frames, lengthAdded = p.framer.AppendControlFrames(frames, maxFrameSize-length)
|
||||
length += lengthAdded
|
||||
|
||||
if !canSendStreamFrames {
|
||||
return frames, nil
|
||||
}
|
||||
|
||||
// temporarily increase the maxFrameSize by the (minimum) length of the DataLen field
|
||||
// this leads to a properly sized packet in all cases, since we do all the packet length calculations with STREAM frames that have the DataLen set
|
||||
// however, for the last STREAM frame in the packet, we can omit the DataLen, thus yielding a packet of exactly the correct size
|
||||
@ -407,6 +372,10 @@ func (p *packetPacker) getHeader(encLevel protocol.EncryptionLevel) *wire.Extend
|
||||
|
||||
if encLevel != protocol.Encryption1RTT {
|
||||
header.IsLongHeader = true
|
||||
// Always send Initial and Handshake packets with the maximum packet number length.
|
||||
// This simplifies retransmissions: Since the header can't get any larger,
|
||||
// we don't need to split CRYPTO frames.
|
||||
header.PacketNumberLen = protocol.PacketNumberLen4
|
||||
header.SrcConnectionID = p.srcConnID
|
||||
// Set the length to the maximum packet size.
|
||||
// Since it is encoded as a varint, this guarantees us that the header will end up at most as big as GetLength() returns.
|
||||
@ -423,23 +392,24 @@ func (p *packetPacker) getHeader(encLevel protocol.EncryptionLevel) *wire.Extend
|
||||
}
|
||||
|
||||
func (p *packetPacker) writeAndSealPacket(
|
||||
header *wire.ExtendedHeader, frames []wire.Frame,
|
||||
header *wire.ExtendedHeader,
|
||||
frames []wire.Frame,
|
||||
sealer handshake.Sealer,
|
||||
) ([]byte, error) {
|
||||
raw := *getPacketBuffer()
|
||||
buffer := bytes.NewBuffer(raw[:0])
|
||||
|
||||
addPadding := p.perspective == protocol.PerspectiveClient && header.Type == protocol.PacketTypeInitial && !p.hasSentPacket
|
||||
addPaddingForInitial := p.perspective == protocol.PerspectiveClient && header.Type == protocol.PacketTypeInitial
|
||||
|
||||
// the length is only needed for Long Headers
|
||||
if header.IsLongHeader {
|
||||
if p.perspective == protocol.PerspectiveClient && header.Type == protocol.PacketTypeInitial {
|
||||
header.Token = p.token
|
||||
}
|
||||
if addPadding {
|
||||
if addPaddingForInitial {
|
||||
headerLen := header.GetLength(p.version)
|
||||
header.Length = protocol.ByteCount(header.PacketNumberLen) + protocol.MinInitialPacketSize - headerLen
|
||||
} else {
|
||||
// long header packets always use 4 byte packet number, so we never need to pad short payloads
|
||||
length := protocol.ByteCount(sealer.Overhead()) + protocol.ByteCount(header.PacketNumberLen)
|
||||
for _, frame := range frames {
|
||||
length += frame.Length(p.version)
|
||||
@ -453,19 +423,31 @@ func (p *packetPacker) writeAndSealPacket(
|
||||
}
|
||||
payloadStartIndex := buffer.Len()
|
||||
|
||||
// the Initial packet needs to be padded, so the last STREAM frame must have the data length present
|
||||
if p.perspective == protocol.PerspectiveClient && header.Type == protocol.PacketTypeInitial {
|
||||
lastFrame := frames[len(frames)-1]
|
||||
if sf, ok := lastFrame.(*wire.StreamFrame); ok {
|
||||
sf.DataLenPresent = true
|
||||
}
|
||||
}
|
||||
for _, frame := range frames {
|
||||
// write all frames but the last one
|
||||
for _, frame := range frames[:len(frames)-1] {
|
||||
if err := frame.Write(buffer, p.version); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if addPadding {
|
||||
lastFrame := frames[len(frames)-1]
|
||||
if addPaddingForInitial {
|
||||
// when appending padding, we need to make sure that the last STREAM frames has the data length set
|
||||
if sf, ok := lastFrame.(*wire.StreamFrame); ok {
|
||||
sf.DataLenPresent = true
|
||||
}
|
||||
} else {
|
||||
payloadLen := buffer.Len() - payloadStartIndex + int(lastFrame.Length(p.version))
|
||||
if paddingLen := 4 - int(header.PacketNumberLen) - payloadLen; paddingLen > 0 {
|
||||
// Pad the packet such that packet number length + payload length is 4 bytes.
|
||||
// This is needed to enable the peer to get a 16 byte sample for header protection.
|
||||
buffer.Write(bytes.Repeat([]byte{0}, paddingLen))
|
||||
}
|
||||
}
|
||||
if err := lastFrame.Write(buffer, p.version); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if addPaddingForInitial {
|
||||
paddingLen := protocol.MinInitialPacketSize - sealer.Overhead() - buffer.Len()
|
||||
if paddingLen > 0 {
|
||||
buffer.Write(bytes.Repeat([]byte{0}, paddingLen))
|
||||
@ -484,14 +466,9 @@ func (p *packetPacker) writeAndSealPacket(
|
||||
if num != header.PacketNumber {
|
||||
return nil, errors.New("packetPacker BUG: Peeked and Popped packet numbers do not match")
|
||||
}
|
||||
p.hasSentPacket = true
|
||||
return raw, nil
|
||||
}
|
||||
|
||||
func (p *packetPacker) canSendData(encLevel protocol.EncryptionLevel) bool {
|
||||
return encLevel == protocol.Encryption1RTT
|
||||
}
|
||||
|
||||
func (p *packetPacker) ChangeDestConnectionID(connID protocol.ConnectionID) {
|
||||
p.destConnID = connID
|
||||
}
|
||||
|
1
vendor/github.com/lucas-clemente/quic-go/packet_unpacker.go
generated
vendored
1
vendor/github.com/lucas-clemente/quic-go/packet_unpacker.go
generated
vendored
@ -58,7 +58,6 @@ func (u *packetUnpacker) Unpack(headerBinary []byte, hdr *wire.ExtendedHeader, d
|
||||
encryptionLevel = protocol.Encryption1RTT
|
||||
}
|
||||
if err != nil {
|
||||
// Wrap err in quicError so that public reset is sent by session
|
||||
return nil, qerr.Error(qerr.DecryptionFailure, err.Error())
|
||||
}
|
||||
|
||||
|
4
vendor/github.com/lucas-clemente/quic-go/server.go
generated
vendored
4
vendor/github.com/lucas-clemente/quic-go/server.go
generated
vendored
@ -128,6 +128,10 @@ func Listen(conn net.PacketConn, tlsConf *tls.Config, config *Config) (Listener,
|
||||
}
|
||||
|
||||
func listen(conn net.PacketConn, tlsConf *tls.Config, config *Config) (*server, error) {
|
||||
// TODO(#1655): only require that tls.Config.Certificates or tls.Config.GetCertificate is set
|
||||
if tlsConf == nil || len(tlsConf.Certificates) == 0 {
|
||||
return nil, errors.New("quic: Certificates not set in tls.Config")
|
||||
}
|
||||
config = populateServerConfig(config)
|
||||
for _, v := range config.Versions {
|
||||
if !protocol.IsValidVersion(v) {
|
||||
|
11
vendor/github.com/lucas-clemente/quic-go/session.go
generated
vendored
11
vendor/github.com/lucas-clemente/quic-go/session.go
generated
vendored
@ -114,9 +114,7 @@ type session struct {
|
||||
|
||||
receivedFirstPacket bool // since packet numbers start at 0, we can't use largestRcvdPacketNumber != 0 for this
|
||||
receivedFirstForwardSecurePacket bool
|
||||
// Used to calculate the next packet number from the truncated wire
|
||||
// representation, and sent back in public reset packets
|
||||
largestRcvdPacketNumber protocol.PacketNumber
|
||||
largestRcvdPacketNumber protocol.PacketNumber // used to calculate the next packet number
|
||||
|
||||
sessionCreationTime time.Time
|
||||
lastNetworkActivityTime time.Time
|
||||
@ -905,12 +903,7 @@ func (s *session) maybeSendRetransmission() (bool, error) {
|
||||
break
|
||||
}
|
||||
|
||||
if retransmitPacket.EncryptionLevel != protocol.Encryption1RTT {
|
||||
s.logger.Debugf("Dequeueing handshake retransmission for packet 0x%x", retransmitPacket.PacketNumber)
|
||||
} else {
|
||||
s.logger.Debugf("Dequeueing retransmission for packet 0x%x", retransmitPacket.PacketNumber)
|
||||
}
|
||||
|
||||
s.logger.Debugf("Dequeueing retransmission for packet 0x%x", retransmitPacket.PacketNumber)
|
||||
packets, err := s.packer.PackRetransmission(retransmitPacket)
|
||||
if err != nil {
|
||||
return false, err
|
||||
|
12
vendor/github.com/lucas-clemente/sync-files.sh
generated
vendored
Executable file
12
vendor/github.com/lucas-clemente/sync-files.sh
generated
vendored
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
|
||||
rsync -rv "$GOPATH/src/github.com/lucas-clemente/quic-go/" "$GOPATH/src/v2ray.com/core/vendor/github.com/lucas-clemente/quic-go/"
|
||||
find . -name "*_test.go" -delete
|
||||
rm -rf ./quic-go/\.*
|
||||
rm -rf ./quic-go/benchmark
|
||||
rm -rf ./quic-go/docs
|
||||
rm -rf ./quic-go/example
|
||||
rm -rf ./quic-go/h2quic
|
||||
rm -rf ./quic-go/integrationtests
|
||||
rm -rf ./quic-go/vendor/golang\.org/
|
||||
rm ./quic-go/vendor/vendor.json
|
Loading…
Reference in New Issue
Block a user