| Index: net/quic/quic_framer.cc
|
| ===================================================================
|
| --- net/quic/quic_framer.cc (revision 248755)
|
| +++ net/quic/quic_framer.cc (working copy)
|
| @@ -5,10 +5,13 @@
|
| #include "net/quic/quic_framer.h"
|
|
|
| #include "base/containers/hash_tables.h"
|
| +#include "net/quic/crypto/crypto_framer.h"
|
| +#include "net/quic/crypto/crypto_handshake_message.h"
|
| #include "net/quic/crypto/quic_decrypter.h"
|
| #include "net/quic/crypto/quic_encrypter.h"
|
| #include "net/quic/quic_data_reader.h"
|
| #include "net/quic/quic_data_writer.h"
|
| +#include "net/quic/quic_socket_address_coder.h"
|
|
|
| using base::StringPiece;
|
| using std::make_pair;
|
| @@ -429,12 +432,27 @@
|
| QuicEncryptedPacket* QuicFramer::BuildPublicResetPacket(
|
| const QuicPublicResetPacket& packet) {
|
| DCHECK(packet.public_header.reset_flag);
|
| - size_t len = GetPublicResetPacketSize();
|
| +
|
| + CryptoHandshakeMessage reset;
|
| + reset.set_tag(kPRST);
|
| + reset.SetValue(kRNON, packet.nonce_proof);
|
| + reset.SetValue(kRSEQ, packet.rejected_sequence_number);
|
| + if (!packet.client_address.address().empty()) {
|
| + // packet.client_address is non-empty.
|
| + QuicSocketAddressCoder address_coder(packet.client_address);
|
| + string serialized_address = address_coder.Encode();
|
| + if (serialized_address.empty()) {
|
| + return NULL;
|
| + }
|
| + reset.SetStringPiece(kCADR, serialized_address);
|
| + }
|
| + const QuicData& reset_serialized = reset.GetSerialized();
|
| +
|
| + size_t len = kPublicFlagsSize + PACKET_8BYTE_GUID + reset_serialized.length();
|
| QuicDataWriter writer(len);
|
|
|
| uint8 flags = static_cast<uint8>(PACKET_PUBLIC_FLAGS_RST |
|
| - PACKET_PUBLIC_FLAGS_8BYTE_GUID |
|
| - PACKET_PUBLIC_FLAGS_6BYTE_SEQUENCE);
|
| + PACKET_PUBLIC_FLAGS_8BYTE_GUID);
|
| if (!writer.WriteUInt8(flags)) {
|
| return NULL;
|
| }
|
| @@ -443,16 +461,10 @@
|
| return NULL;
|
| }
|
|
|
| - if (!writer.WriteUInt64(packet.nonce_proof)) {
|
| + if (!writer.WriteBytes(reset_serialized.data(), reset_serialized.length())) {
|
| return NULL;
|
| }
|
|
|
| - if (!AppendPacketSequenceNumber(PACKET_6BYTE_SEQUENCE_NUMBER,
|
| - packet.rejected_sequence_number,
|
| - &writer)) {
|
| - return NULL;
|
| - }
|
| -
|
| return new QuicEncryptedPacket(writer.take(), len, true);
|
| }
|
|
|
| @@ -464,8 +476,7 @@
|
| QuicDataWriter writer(len);
|
|
|
| uint8 flags = static_cast<uint8>(PACKET_PUBLIC_FLAGS_VERSION |
|
| - PACKET_PUBLIC_FLAGS_8BYTE_GUID |
|
| - PACKET_PUBLIC_FLAGS_6BYTE_SEQUENCE);
|
| + PACKET_PUBLIC_FLAGS_8BYTE_GUID);
|
| if (!writer.WriteUInt8(flags)) {
|
| return NULL;
|
| }
|
| @@ -585,16 +596,57 @@
|
| bool QuicFramer::ProcessPublicResetPacket(
|
| const QuicPacketPublicHeader& public_header) {
|
| QuicPublicResetPacket packet(public_header);
|
| - if (!reader_->ReadUInt64(&packet.nonce_proof)) {
|
| +
|
| + if (reader_->BytesRemaining() <=
|
| + kPublicResetNonceSize + PACKET_6BYTE_SEQUENCE_NUMBER) {
|
| + // An old-style public reset packet.
|
| + // TODO(wtc): remove this when we drop support for QUIC_VERSION_13.
|
| + if (!reader_->ReadUInt64(&packet.nonce_proof)) {
|
| + set_detailed_error("Unable to read nonce proof.");
|
| + return RaiseError(QUIC_INVALID_PUBLIC_RST_PACKET);
|
| + }
|
| +
|
| + if (!reader_->ReadUInt48(&packet.rejected_sequence_number)) {
|
| + set_detailed_error("Unable to read rejected sequence number.");
|
| + return RaiseError(QUIC_INVALID_PUBLIC_RST_PACKET);
|
| + }
|
| +
|
| + visitor_->OnPublicResetPacket(packet);
|
| + return true;
|
| + }
|
| +
|
| + scoped_ptr<CryptoHandshakeMessage> reset(
|
| + CryptoFramer::ParseMessage(reader_->ReadRemainingPayload()));
|
| + if (!reset.get()) {
|
| + set_detailed_error("Unable to read reset message.");
|
| + return RaiseError(QUIC_INVALID_PUBLIC_RST_PACKET);
|
| + }
|
| + if (reset->tag() != kPRST) {
|
| + set_detailed_error("Incorrect message tag.");
|
| + return RaiseError(QUIC_INVALID_PUBLIC_RST_PACKET);
|
| + }
|
| +
|
| + if (reset->GetUint64(kRNON, &packet.nonce_proof) != QUIC_NO_ERROR) {
|
| set_detailed_error("Unable to read nonce proof.");
|
| return RaiseError(QUIC_INVALID_PUBLIC_RST_PACKET);
|
| }
|
| // TODO(satyamshekhar): validate nonce to protect against DoS.
|
|
|
| - if (!reader_->ReadUInt48(&packet.rejected_sequence_number)) {
|
| + if (reset->GetUint64(kRSEQ, &packet.rejected_sequence_number) !=
|
| + QUIC_NO_ERROR) {
|
| set_detailed_error("Unable to read rejected sequence number.");
|
| return RaiseError(QUIC_INVALID_PUBLIC_RST_PACKET);
|
| }
|
| +
|
| + StringPiece address;
|
| + if (reset->GetStringPiece(kCADR, &address)) {
|
| + QuicSocketAddressCoder address_coder;
|
| + if (address_coder.Decode(address.data(), address.length())) {
|
| + packet.client_address = IPEndPoint(address_coder.ip(),
|
| + address_coder.port());
|
| + }
|
| + }
|
| +
|
| visitor_->OnPublicResetPacket(packet);
|
| return true;
|
| }
|
|
|