| Index: net/quic/quic_framer.cc
|
| diff --git a/net/quic/quic_framer.cc b/net/quic/quic_framer.cc
|
| index 1dd0064570b6edccdbd930e8ddf5a997dee0a311..852114a0c245104ab511b6e8578eafd540b6119a 100644
|
| --- a/net/quic/quic_framer.cc
|
| +++ b/net/quic/quic_framer.cc
|
| @@ -39,9 +39,6 @@ const QuicPacketNumber k4ByteSequenceNumberMask = UINT64_C(0x00000000FFFFFFFF);
|
| const QuicPacketNumber k2ByteSequenceNumberMask = UINT64_C(0x000000000000FFFF);
|
| const QuicPacketNumber k1ByteSequenceNumberMask = UINT64_C(0x00000000000000FF);
|
|
|
| -const QuicConnectionId k1ByteConnectionIdMask = UINT64_C(0x00000000000000FF);
|
| -const QuicConnectionId k4ByteConnectionIdMask = UINT64_C(0x00000000FFFFFFFF);
|
| -
|
| // Number of bits the packet number length bits are shifted from the right
|
| // edge of the public header.
|
| const uint8_t kPublicHeaderSequenceNumberShift = 4;
|
| @@ -653,6 +650,11 @@ bool QuicFramer::AppendPacketHeader(const QuicPacketHeader& header,
|
| GetSequenceNumberFlags(header.public_header.packet_number_length)
|
| << kPublicHeaderSequenceNumberShift;
|
|
|
| + if (header.public_header.nonce != nullptr) {
|
| + DCHECK_EQ(Perspective::IS_SERVER, perspective_);
|
| + public_flags |= PACKET_PUBLIC_FLAGS_NONCE;
|
| + }
|
| +
|
| switch (header.public_header.connection_id_length) {
|
| case PACKET_0BYTE_CONNECTION_ID:
|
| if (!writer->WriteUInt8(public_flags |
|
| @@ -660,32 +662,14 @@ bool QuicFramer::AppendPacketHeader(const QuicPacketHeader& header,
|
| return false;
|
| }
|
| break;
|
| - case PACKET_1BYTE_CONNECTION_ID:
|
| - if (!writer->WriteUInt8(public_flags |
|
| - PACKET_PUBLIC_FLAGS_1BYTE_CONNECTION_ID)) {
|
| - return false;
|
| - }
|
| - if (!writer->WriteUInt8(header.public_header.connection_id &
|
| - k1ByteConnectionIdMask)) {
|
| - return false;
|
| - }
|
| - break;
|
| - case PACKET_4BYTE_CONNECTION_ID:
|
| - if (!writer->WriteUInt8(public_flags |
|
| - PACKET_PUBLIC_FLAGS_4BYTE_CONNECTION_ID)) {
|
| - return false;
|
| - }
|
| - if (!writer->WriteUInt32(header.public_header.connection_id &
|
| - k4ByteConnectionIdMask)) {
|
| - return false;
|
| - }
|
| - break;
|
| case PACKET_8BYTE_CONNECTION_ID:
|
| - if (!writer->WriteUInt8(public_flags |
|
| - PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID)) {
|
| - return false;
|
| + if (quic_version_ > QUIC_VERSION_32) {
|
| + public_flags |= PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID;
|
| + } else {
|
| + public_flags |= PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID_OLD;
|
| }
|
| - if (!writer->WriteUInt64(header.public_header.connection_id)) {
|
| + if (!writer->WriteUInt8(public_flags) ||
|
| + !writer->WriteUInt64(header.public_header.connection_id)) {
|
| return false;
|
| }
|
| break;
|
| @@ -705,6 +689,12 @@ bool QuicFramer::AppendPacketHeader(const QuicPacketHeader& header,
|
| return false;
|
| }
|
|
|
| + if (header.public_header.nonce != nullptr &&
|
| + !writer->WriteBytes(header.public_header.nonce,
|
| + kDiversificationNonceSize)) {
|
| + return false;
|
| + }
|
| +
|
| if (!AppendPacketSequenceNumber(header.public_header.packet_number_length,
|
| header.packet_number, writer)) {
|
| return false;
|
| @@ -827,42 +817,6 @@ bool QuicFramer::ProcessPublicHeader(QuicDataReader* reader,
|
| }
|
| public_header->connection_id_length = PACKET_8BYTE_CONNECTION_ID;
|
| break;
|
| - case PACKET_PUBLIC_FLAGS_4BYTE_CONNECTION_ID:
|
| - // If the connection_id is truncated, expect to read the last serialized
|
| - // connection_id.
|
| - if (!reader->ReadBytes(&public_header->connection_id,
|
| - PACKET_4BYTE_CONNECTION_ID)) {
|
| - set_detailed_error("Unable to read ConnectionId.");
|
| - return false;
|
| - }
|
| - if (last_serialized_connection_id_ &&
|
| - (public_header->connection_id & k4ByteConnectionIdMask) !=
|
| - (last_serialized_connection_id_ & k4ByteConnectionIdMask)) {
|
| - set_detailed_error(
|
| - "Truncated 4 byte ConnectionId does not match "
|
| - "previous connection_id.");
|
| - return false;
|
| - }
|
| - public_header->connection_id_length = PACKET_4BYTE_CONNECTION_ID;
|
| - public_header->connection_id = last_serialized_connection_id_;
|
| - break;
|
| - case PACKET_PUBLIC_FLAGS_1BYTE_CONNECTION_ID:
|
| - if (!reader->ReadBytes(&public_header->connection_id,
|
| - PACKET_1BYTE_CONNECTION_ID)) {
|
| - set_detailed_error("Unable to read ConnectionId.");
|
| - return false;
|
| - }
|
| - if (last_serialized_connection_id_ &&
|
| - (public_header->connection_id & k1ByteConnectionIdMask) !=
|
| - (last_serialized_connection_id_ & k1ByteConnectionIdMask)) {
|
| - set_detailed_error(
|
| - "Truncated 1 byte ConnectionId does not match "
|
| - "previous connection_id.");
|
| - return false;
|
| - }
|
| - public_header->connection_id_length = PACKET_1BYTE_CONNECTION_ID;
|
| - public_header->connection_id = last_serialized_connection_id_;
|
| - break;
|
| case PACKET_PUBLIC_FLAGS_0BYTE_CONNECTION_ID:
|
| public_header->connection_id_length = PACKET_0BYTE_CONNECTION_ID;
|
| public_header->connection_id = last_serialized_connection_id_;
|
| @@ -892,6 +846,26 @@ bool QuicFramer::ProcessPublicHeader(QuicDataReader* reader,
|
| }
|
| public_header->versions.push_back(version);
|
| }
|
| +
|
| + // A nonce should only be present in packets from the server to the client,
|
| + // and only for versions after QUIC_VERSION_32. Earlier versions will
|
| + // set this bit when indicating an 8-byte connection ID, which should
|
| + // not be interpreted as indicating a nonce is present.
|
| + if (quic_version_ > QUIC_VERSION_32 &&
|
| + public_flags & PACKET_PUBLIC_FLAGS_NONCE &&
|
| + // The nonce flag from a client is ignored and is assumed to be an older
|
| + // client indicating an eight-byte connection ID.
|
| + perspective_ == Perspective::IS_CLIENT) {
|
| + if (!reader->ReadBytes(reinterpret_cast<uint8_t*>(last_nonce_),
|
| + sizeof(last_nonce_))) {
|
| + set_detailed_error("Unable to read nonce.");
|
| + return false;
|
| + }
|
| + public_header->nonce = &last_nonce_;
|
| + } else {
|
| + public_header->nonce = nullptr;
|
| + }
|
| +
|
| return true;
|
| }
|
|
|
| @@ -1615,12 +1589,14 @@ StringPiece QuicFramer::GetAssociatedDataFromEncryptedPacket(
|
| QuicConnectionIdLength connection_id_length,
|
| bool includes_version,
|
| bool includes_path_id,
|
| + bool includes_diversification_nonce,
|
| QuicPacketNumberLength packet_number_length) {
|
| // TODO(ianswett): This is identical to QuicData::AssociatedData.
|
| return StringPiece(
|
| encrypted.data(),
|
| GetStartOfEncryptedData(connection_id_length, includes_version,
|
| - includes_path_id, packet_number_length));
|
| + includes_path_id, includes_diversification_nonce,
|
| + packet_number_length));
|
| }
|
|
|
| void QuicFramer::SetDecrypter(EncryptionLevel level, QuicDecrypter* decrypter) {
|
| @@ -1726,13 +1702,29 @@ bool QuicFramer::DecryptPayload(QuicDataReader* encrypted_reader,
|
| StringPiece associated_data = GetAssociatedDataFromEncryptedPacket(
|
| packet, header.public_header.connection_id_length,
|
| header.public_header.version_flag, header.public_header.multipath_flag,
|
| + header.public_header.nonce != nullptr,
|
| header.public_header.packet_number_length);
|
| +
|
| bool success = decrypter_->DecryptPacket(
|
| header.path_id, header.packet_number, associated_data, encrypted,
|
| decrypted_buffer, decrypted_length, buffer_length);
|
| if (success) {
|
| visitor_->OnDecryptedPacket(decrypter_level_);
|
| } else if (alternative_decrypter_.get() != nullptr) {
|
| + if (header.public_header.nonce != nullptr) {
|
| + DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
|
| + alternative_decrypter_->SetDiversificationNonce(
|
| + *header.public_header.nonce);
|
| + }
|
| + if (alternative_decrypter_level_ == ENCRYPTION_INITIAL) {
|
| + if (perspective_ == Perspective::IS_CLIENT &&
|
| + quic_version_ > QUIC_VERSION_32) {
|
| + DCHECK(header.public_header.nonce != nullptr);
|
| + } else {
|
| + DCHECK(header.public_header.nonce == nullptr);
|
| + }
|
| + }
|
| +
|
| success = alternative_decrypter_->DecryptPacket(
|
| header.path_id, header.packet_number, associated_data, encrypted,
|
| decrypted_buffer, decrypted_length, buffer_length);
|
|
|