Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(325)

Unified Diff: net/quic/quic_framer.cc

Issue 12806002: Land Recent QUIC Changes (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: minor comment fix Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/quic/quic_framer.h ('k') | net/quic/quic_framer_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/quic/quic_framer.cc
diff --git a/net/quic/quic_framer.cc b/net/quic/quic_framer.cc
index 2329605dcc181e8c47f73b302f9c9a32f9665e44..462172cbac4f36df3896e9ead530530e75b330a3 100644
--- a/net/quic/quic_framer.cc
+++ b/net/quic/quic_framer.cc
@@ -45,15 +45,17 @@ QuicPacketSequenceNumber ClosestTo(QuicPacketSequenceNumber target,
QuicFramer::QuicFramer(QuicVersionTag version,
QuicDecrypter* decrypter,
- QuicEncrypter* encrypter)
+ QuicEncrypter* encrypter,
+ bool is_server)
: visitor_(NULL),
fec_builder_(NULL),
error_(QUIC_NO_ERROR),
last_sequence_number_(0),
quic_version_(version),
decrypter_(decrypter),
- encrypter_(encrypter) {
- DCHECK_EQ(kQuicVersion1, version);
+ encrypter_(encrypter),
+ is_server_(is_server) {
+ DCHECK(IsSupportedVersion(version));
}
QuicFramer::~QuicFramer() {}
@@ -96,6 +98,15 @@ size_t QuicFramer::GetMinGoAwayFrameSize() {
kQuicStreamIdSize;
}
+bool QuicFramer::IsSupportedVersion(QuicVersionTag version) {
+ return version == kQuicVersion1;
+}
+
+size_t QuicFramer::GetVersionNegotiationPacketSize(size_t number_versions) {
+ return kQuicGuidSize + kPublicFlagsSize +
+ number_versions * kQuicVersionSize;
+}
+
size_t QuicFramer::GetSerializedFrameLength(
const QuicFrame& frame, size_t free_bytes, bool first_frame) {
if (frame.type == PADDING_FRAME) {
@@ -245,7 +256,6 @@ SerializedPacket QuicFramer::ConstructFecPacket(const QuicPacketHeader& header,
QuicEncryptedPacket* QuicFramer::ConstructPublicResetPacket(
const QuicPublicResetPacket& packet) {
DCHECK(packet.public_header.reset_flag);
- DCHECK(!packet.public_header.version_flag);
size_t len = GetPublicResetPacketSize();
QuicDataWriter writer(len);
@@ -270,23 +280,56 @@ QuicEncryptedPacket* QuicFramer::ConstructPublicResetPacket(
return new QuicEncryptedPacket(writer.take(), len, true);
}
+QuicEncryptedPacket* QuicFramer::ConstructVersionNegotiationPacket(
+ const QuicPacketPublicHeader& header,
+ const QuicVersionTagList& supported_versions) {
+ DCHECK(header.version_flag);
+ size_t len = GetVersionNegotiationPacketSize(supported_versions.size());
+ QuicDataWriter writer(len);
+
+ if (!writer.WriteUInt64(header.guid)) {
+ return NULL;
+ }
+
+ uint8 flags = static_cast<uint8>(PACKET_PUBLIC_FLAGS_VERSION);
+ if (!writer.WriteUInt8(flags)) {
+ return NULL;
+ }
+
+ for (size_t i = 0; i < supported_versions.size(); ++i) {
+ if (!writer.WriteUInt32(supported_versions[i])) {
+ return NULL;
+ }
+ }
+
+ return new QuicEncryptedPacket(writer.take(), len, true);
+}
+
bool QuicFramer::ProcessPacket(const QuicEncryptedPacket& packet) {
DCHECK(!reader_.get());
reader_.reset(new QuicDataReader(packet.data(), packet.length()));
+ visitor_->OnPacket();
+
// First parse the public header.
QuicPacketPublicHeader public_header;
if (!ProcessPublicHeader(&public_header)) {
DLOG(WARNING) << "Unable to process public header.";
return RaiseError(QUIC_INVALID_PACKET_HEADER);
}
- // TODO(satyamshekhar): Handle version negotiation.
- if (public_header.version_flag && public_header.version != quic_version_) {
- return false;
+
+ if (is_server_ && public_header.version_flag &&
+ public_header.versions[0] != quic_version_) {
+ if (!visitor_->OnProtocolVersionMismatch(public_header.versions[0])) {
+ reader_.reset(NULL);
+ return true;
+ }
}
bool rv;
- if (public_header.reset_flag) {
+ if (!is_server_ && public_header.version_flag) {
+ rv = ProcessVersionNegotiationPacket(&public_header);
+ } else if (public_header.reset_flag) {
rv = ProcessPublicResetPacket(public_header);
} else {
rv = ProcessDataPacket(public_header, packet);
@@ -296,11 +339,26 @@ bool QuicFramer::ProcessPacket(const QuicEncryptedPacket& packet) {
return rv;
}
+bool QuicFramer::ProcessVersionNegotiationPacket(
+ QuicPacketPublicHeader* public_header) {
+ DCHECK(!is_server_);
+ // Try reading at least once to raise error if the packet is invalid.
+ do {
+ QuicVersionTag version;
+ if (!reader_->ReadBytes(&version, kQuicVersionSize)) {
+ set_detailed_error("Unable to read supported version in negotiation.");
+ return RaiseError(QUIC_INVALID_VERSION_NEGOTIATION_PACKET);
+ }
+ public_header->versions.push_back(version);
+ } while (!reader_->IsDoneReading());
+
+ visitor_->OnVersionNegotiationPacket(*public_header);
+ return true;
+}
+
bool QuicFramer::ProcessDataPacket(
const QuicPacketPublicHeader& public_header,
const QuicEncryptedPacket& packet) {
- visitor_->OnPacket();
-
QuicPacketHeader header(public_header);
if (!ProcessPacketHeader(&header, packet)) {
DCHECK_NE(QUIC_NO_ERROR, error_); // ProcessPacketHeader sets the error.
@@ -344,6 +402,7 @@ bool QuicFramer::ProcessPublicResetPacket(
const QuicPacketPublicHeader& public_header) {
QuicPublicResetPacket packet(public_header);
if (!reader_->ReadUInt64(&packet.nonce_proof)) {
+ // TODO(satyamshekhar): Raise error.
set_detailed_error("Unable to read nonce proof.");
return false;
}
@@ -403,6 +462,7 @@ bool QuicFramer::WritePacketHeader(const QuicPacketHeader& header,
}
if (header.public_header.version_flag) {
+ DCHECK(!is_server_);
writer->WriteUInt32(quic_version_);
}
@@ -481,12 +541,21 @@ bool QuicFramer::ProcessPublicHeader(QuicPacketPublicHeader* public_header) {
public_header->version_flag =
(public_flags & PACKET_PUBLIC_FLAGS_VERSION) != 0;
- if (public_header->version_flag &&
- !reader_->ReadUInt32(&public_header->version)) {
- set_detailed_error("Unable to read protocol version.");
+ if (public_header->reset_flag && public_header->version_flag) {
+ set_detailed_error("Got version flag in reset packet");
return false;
}
+ if (public_header->version_flag && is_server_) {
+ QuicVersionTag version;
+ if (!reader_->ReadUInt32(&version)) {
+ // Read the version only if the packet is from the client.
+ // version flag from the server means version negotiation packet.
+ set_detailed_error("Unable to read protocol version.");
+ return false;
+ }
+ public_header->versions.push_back(version);
+ }
return true;
}
@@ -673,6 +742,7 @@ bool QuicFramer::ProcessReceivedInfo(ReceivedPacketInfo* received_info) {
set_detailed_error("Unable to read largest observed.");
return false;
}
+ // TODO(pwestin): read and update delta_time_largest_observed.
uint8 num_missing_packets;
if (!reader_->ReadBytes(&num_missing_packets, 1)) {
@@ -889,8 +959,8 @@ bool QuicFramer::ProcessGoAwayFrame() {
StringPiece QuicFramer::GetAssociatedDataFromEncryptedPacket(
const QuicEncryptedPacket& encrypted, bool includes_version) {
return StringPiece(encrypted.data() + kStartOfHashData,
- GetStartOfEncryptedData(includes_version)
- - kStartOfHashData);
+ GetStartOfEncryptedData(includes_version) -
+ kStartOfHashData);
}
QuicEncryptedPacket* QuicFramer::EncryptPacket(
@@ -1076,6 +1146,8 @@ bool QuicFramer::AppendAckFramePayload(
writer)) {
return false;
}
+ // TODO(pwestin): calculate and add delta_time_largest_observed to the
+ // message.
// We don't check for overflowing uint8 here, because we only can fit 192 acks
// per packet, so if we overflow we will be truncated.
« no previous file with comments | « net/quic/quic_framer.h ('k') | net/quic/quic_framer_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698