summaryrefslogtreecommitdiffstats
path: root/net/quic
diff options
context:
space:
mode:
authorrtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-11 08:46:09 +0000
committerrtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-11 08:46:09 +0000
commit118f1b4eb5f8787d80d96bb998600a25f023a97c (patch)
tree7018a8cee802355652822218e1aae33f48253162 /net/quic
parent9576544a7d8cc3e45db9ebdc3e9fb08fb6c4f797 (diff)
downloadchromium_src-118f1b4eb5f8787d80d96bb998600a25f023a97c.zip
chromium_src-118f1b4eb5f8787d80d96bb998600a25f023a97c.tar.gz
chromium_src-118f1b4eb5f8787d80d96bb998600a25f023a97c.tar.bz2
Land Recent QUIC changes.
Remove unused IsWriteBlocked method from QuicConnectionHelperInterface. Merge internal change: 53803217 Add missing QUIC_VERSION_Q011 case in QuicVersionToString. Merge internal change: 53749976 QUIC: don't ignore SetKey and SetNoncePrefix return values. This change causes failures to set the AES-GCM key and nonce to bubble up and kill the connection. I don't think that we've had any failures, but you never know and it would be bad to, say, start transmitting plaintext or something because we didn't notice that we failed to set a key. (The OpenSSL AEAD API doesn't actually let that happen: it zeros the output buffer on any failure, but things might change in the future.) (This is a follow up from a previous CL which altered our AES-128-GCM implementation.) Merge internal change: 53742674 Reduce the length of the QUIC null encryption auth hash from 16 bytes to 12 bytes to match the length of the AES auth hash. Merge internal change: 53693995 R=rch@chromium.org Review URL: https://codereview.chromium.org/26739002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@228145 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/quic')
-rw-r--r--net/quic/crypto/crypto_handshake.cc33
-rw-r--r--net/quic/crypto/crypto_protocol.h1
-rw-r--r--net/quic/crypto/crypto_server_config.cc30
-rw-r--r--net/quic/crypto/crypto_utils.cc24
-rw-r--r--net/quic/crypto/crypto_utils.h2
-rw-r--r--net/quic/crypto/null_decrypter.cc39
-rw-r--r--net/quic/crypto/null_decrypter.h8
-rw-r--r--net/quic/crypto/null_decrypter_test.cc69
-rw-r--r--net/quic/crypto/null_encrypter.cc22
-rw-r--r--net/quic/crypto/null_encrypter.h6
-rw-r--r--net/quic/crypto/null_encrypter_test.cc64
-rw-r--r--net/quic/crypto/quic_decrypter.cc4
-rw-r--r--net/quic/crypto/quic_encrypter.cc4
-rw-r--r--net/quic/quic_connection.h4
-rw-r--r--net/quic/quic_connection_helper.cc4
-rw-r--r--net/quic/quic_connection_helper.h1
-rw-r--r--net/quic/quic_connection_test.cc4
-rw-r--r--net/quic/quic_framer.cc15
-rw-r--r--net/quic/quic_framer.h5
-rw-r--r--net/quic/quic_framer_test.cc5
-rw-r--r--net/quic/quic_packet_generator_test.cc3
-rw-r--r--net/quic/quic_protocol.cc23
-rw-r--r--net/quic/quic_protocol.h9
-rw-r--r--net/quic/quic_protocol_test.cc10
-rw-r--r--net/quic/quic_utils.cc10
-rw-r--r--net/quic/quic_utils.h4
-rw-r--r--net/quic/test_tools/quic_test_utils.cc7
-rw-r--r--net/quic/test_tools/quic_test_utils.h1
28 files changed, 291 insertions, 120 deletions
diff --git a/net/quic/crypto/crypto_handshake.cc b/net/quic/crypto/crypto_handshake.cc
index f5c7f4d..21553ab 100644
--- a/net/quic/crypto/crypto_handshake.cc
+++ b/net/quic/crypto/crypto_handshake.cc
@@ -759,10 +759,13 @@ QuicErrorCode QuicCryptoClientConfig::FillClientHello(
cetv.SetStringPiece(kCIDS, signature);
CrypterPair crypters;
- CryptoUtils::DeriveKeys(out_params->initial_premaster_secret,
- out_params->aead, out_params->client_nonce,
- out_params->server_nonce, hkdf_input,
- CryptoUtils::CLIENT, &crypters);
+ if (!CryptoUtils::DeriveKeys(out_params->initial_premaster_secret,
+ out_params->aead, out_params->client_nonce,
+ out_params->server_nonce, hkdf_input,
+ CryptoUtils::CLIENT, &crypters)) {
+ *error_details = "Symmetric key setup failed";
+ return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED;
+ }
const QuicData& cetv_plaintext = cetv.GetSerialized();
scoped_ptr<QuicData> cetv_ciphertext(crypters.encrypter->EncryptPacket(
@@ -794,10 +797,13 @@ QuicErrorCode QuicCryptoClientConfig::FillClientHello(
hkdf_input.append(QuicCryptoConfig::kInitialLabel, label_len);
hkdf_input.append(out_params->hkdf_input_suffix);
- CryptoUtils::DeriveKeys(out_params->initial_premaster_secret,
- out_params->aead, out_params->client_nonce,
- out_params->server_nonce, hkdf_input,
- CryptoUtils::CLIENT, &out_params->initial_crypters);
+ if (!CryptoUtils::DeriveKeys(
+ out_params->initial_premaster_secret, out_params->aead,
+ out_params->client_nonce, out_params->server_nonce, hkdf_input,
+ CryptoUtils::CLIENT, &out_params->initial_crypters)) {
+ *error_details = "Symmetric key setup failed";
+ return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED;
+ }
return QUIC_NO_ERROR;
}
@@ -904,10 +910,13 @@ QuicErrorCode QuicCryptoClientConfig::ProcessServerHello(
hkdf_input.append(QuicCryptoConfig::kForwardSecureLabel, label_len);
hkdf_input.append(out_params->hkdf_input_suffix);
- CryptoUtils::DeriveKeys(
- out_params->forward_secure_premaster_secret, out_params->aead,
- out_params->client_nonce, out_params->server_nonce, hkdf_input,
- CryptoUtils::CLIENT, &out_params->forward_secure_crypters);
+ if (!CryptoUtils::DeriveKeys(
+ out_params->forward_secure_premaster_secret, out_params->aead,
+ out_params->client_nonce, out_params->server_nonce, hkdf_input,
+ CryptoUtils::CLIENT, &out_params->forward_secure_crypters)) {
+ *error_details = "Symmetric key setup failed";
+ return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED;
+ }
return QUIC_NO_ERROR;
}
diff --git a/net/quic/crypto/crypto_protocol.h b/net/quic/crypto/crypto_protocol.h
index 4580fce..0dcf016 100644
--- a/net/quic/crypto/crypto_protocol.h
+++ b/net/quic/crypto/crypto_protocol.h
@@ -41,6 +41,7 @@ const QuicTag kC255 = TAG('C', '2', '5', '5'); // ECDH, Curve25519
// AEAD algorithms
const QuicTag kNULL = TAG('N', 'U', 'L', 'L'); // null algorithm
+const QuicTag kNULN = TAG('N', 'U', 'L', 'N'); // new null algorithm
const QuicTag kAESG = TAG('A', 'E', 'S', 'G'); // AES128 + GCM-12
// Congestion control feedback types
diff --git a/net/quic/crypto/crypto_server_config.cc b/net/quic/crypto/crypto_server_config.cc
index 7c7d0ff..4ff51c4 100644
--- a/net/quic/crypto/crypto_server_config.cc
+++ b/net/quic/crypto/crypto_server_config.cc
@@ -449,9 +449,12 @@ QuicErrorCode QuicCryptoServerConfig::ProcessClientHello(
hkdf_input.append(requested_config->serialized);
CrypterPair crypters;
- CryptoUtils::DeriveKeys(params->initial_premaster_secret, params->aead,
- info.client_nonce, info.server_nonce, hkdf_input,
- CryptoUtils::SERVER, &crypters);
+ if (!CryptoUtils::DeriveKeys(params->initial_premaster_secret, params->aead,
+ info.client_nonce, info.server_nonce,
+ hkdf_input, CryptoUtils::SERVER, &crypters)) {
+ *error_details = "Symmetric key setup failed";
+ return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED;
+ }
scoped_ptr<QuicData> cetv_plaintext(crypters.decrypter->DecryptPacket(
0 /* sequence number */, StringPiece() /* associated data */,
@@ -486,9 +489,13 @@ QuicErrorCode QuicCryptoServerConfig::ProcessClientHello(
hkdf_input.append(QuicCryptoConfig::kInitialLabel, label_len);
hkdf_input.append(hkdf_suffix);
- CryptoUtils::DeriveKeys(params->initial_premaster_secret, params->aead,
- info.client_nonce, info.server_nonce, hkdf_input,
- CryptoUtils::SERVER, &params->initial_crypters);
+ if (!CryptoUtils::DeriveKeys(params->initial_premaster_secret, params->aead,
+ info.client_nonce, info.server_nonce, hkdf_input,
+ CryptoUtils::SERVER,
+ &params->initial_crypters)) {
+ *error_details = "Symmetric key setup failed";
+ return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED;
+ }
string forward_secure_public_value;
if (ephemeral_key_source_.get()) {
@@ -515,10 +522,13 @@ QuicErrorCode QuicCryptoServerConfig::ProcessClientHello(
label_len);
forward_secure_hkdf_input.append(hkdf_suffix);
- CryptoUtils::DeriveKeys(params->forward_secure_premaster_secret, params->aead,
- info.client_nonce, info.server_nonce,
- forward_secure_hkdf_input, CryptoUtils::SERVER,
- &params->forward_secure_crypters);
+ if (!CryptoUtils::DeriveKeys(
+ params->forward_secure_premaster_secret, params->aead,
+ info.client_nonce, info.server_nonce, forward_secure_hkdf_input,
+ CryptoUtils::SERVER, &params->forward_secure_crypters)) {
+ *error_details = "Symmetric key setup failed";
+ return QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED;
+ }
out->set_tag(kSHLO);
out->SetStringPiece(kSourceAddressTokenTag,
diff --git a/net/quic/crypto/crypto_utils.cc b/net/quic/crypto/crypto_utils.cc
index 469e582..eec8a9d 100644
--- a/net/quic/crypto/crypto_utils.cc
+++ b/net/quic/crypto/crypto_utils.cc
@@ -77,7 +77,7 @@ string CryptoUtils::NormalizeHostname(const char* hostname) {
}
// static
-void CryptoUtils::DeriveKeys(StringPiece premaster_secret,
+bool CryptoUtils::DeriveKeys(StringPiece premaster_secret,
QuicTag aead,
StringPiece client_nonce,
StringPiece server_nonce,
@@ -99,16 +99,22 @@ void CryptoUtils::DeriveKeys(StringPiece premaster_secret,
crypto::HKDF hkdf(premaster_secret, nonce, hkdf_input, key_bytes,
nonce_prefix_bytes);
if (perspective == SERVER) {
- out->encrypter->SetKey(hkdf.server_write_key());
- out->encrypter->SetNoncePrefix(hkdf.server_write_iv());
- out->decrypter->SetKey(hkdf.client_write_key());
- out->decrypter->SetNoncePrefix(hkdf.client_write_iv());
+ if (!out->encrypter->SetKey(hkdf.server_write_key()) ||
+ !out->encrypter->SetNoncePrefix(hkdf.server_write_iv()) ||
+ !out->decrypter->SetKey(hkdf.client_write_key()) ||
+ !out->decrypter->SetNoncePrefix(hkdf.client_write_iv())) {
+ return false;
+ }
} else {
- out->encrypter->SetKey(hkdf.client_write_key());
- out->encrypter->SetNoncePrefix(hkdf.client_write_iv());
- out->decrypter->SetKey(hkdf.server_write_key());
- out->decrypter->SetNoncePrefix(hkdf.server_write_iv());
+ if (!out->encrypter->SetKey(hkdf.client_write_key()) ||
+ !out->encrypter->SetNoncePrefix(hkdf.client_write_iv()) ||
+ !out->decrypter->SetKey(hkdf.server_write_key()) ||
+ !out->decrypter->SetNoncePrefix(hkdf.server_write_iv())) {
+ return false;
+ }
}
+
+ return true;
}
} // namespace net
diff --git a/net/quic/crypto/crypto_utils.h b/net/quic/crypto/crypto_utils.h
index 6dfce2a..147e414 100644
--- a/net/quic/crypto/crypto_utils.h
+++ b/net/quic/crypto/crypto_utils.h
@@ -55,7 +55,7 @@ class NET_EXPORT_PRIVATE CryptoUtils {
// controls whether the server's keys are assigned to |encrypter| or
// |decrypter|. |server_nonce| is optional and, if non-empty, is mixed into
// the key derivation.
- static void DeriveKeys(base::StringPiece premaster_secret,
+ static bool DeriveKeys(base::StringPiece premaster_secret,
QuicTag aead,
base::StringPiece client_nonce,
base::StringPiece server_nonce,
diff --git a/net/quic/crypto/null_decrypter.cc b/net/quic/crypto/null_decrypter.cc
index 7bda75f..77bdad8 100644
--- a/net/quic/crypto/null_decrypter.cc
+++ b/net/quic/crypto/null_decrypter.cc
@@ -11,6 +11,9 @@ using std::string;
namespace net {
+NullDecrypter::NullDecrypter(bool use_short_hash)
+ : use_short_hash_(use_short_hash) {}
+
bool NullDecrypter::SetKey(StringPiece key) { return key.empty(); }
bool NullDecrypter::SetNoncePrefix(StringPiece nonce_prefix) {
@@ -25,7 +28,7 @@ bool NullDecrypter::Decrypt(StringPiece /*nonce*/,
QuicDataReader reader(ciphertext.data(), ciphertext.length());
uint128 hash;
- if (!reader.ReadUInt128(&hash)) {
+ if (!ReadHash(&reader, &hash)) {
return false;
}
@@ -34,8 +37,7 @@ bool NullDecrypter::Decrypt(StringPiece /*nonce*/,
// TODO(rch): avoid buffer copy here
string buffer = associated_data.as_string();
plaintext.AppendToString(&buffer);
-
- if (hash != QuicUtils::FNV1a_128_Hash(buffer.data(), buffer.length())) {
+ if (hash != ComputeHash(buffer)) {
return false;
}
memcpy(output, plaintext.data(), plaintext.length());
@@ -51,7 +53,7 @@ QuicData* NullDecrypter::DecryptPacket(QuicPacketSequenceNumber /*seq_number*/,
QuicDataReader reader(ciphertext.data(), ciphertext.length());
uint128 hash;
- if (!reader.ReadUInt128(&hash)) {
+ if (!ReadHash(&reader, &hash)) {
return NULL;
}
@@ -61,7 +63,7 @@ QuicData* NullDecrypter::DecryptPacket(QuicPacketSequenceNumber /*seq_number*/,
string buffer = associated_data.as_string();
plaintext.AppendToString(&buffer);
- if (hash != QuicUtils::FNV1a_128_Hash(buffer.data(), buffer.length())) {
+ if (hash != ComputeHash(buffer)) {
return NULL;
}
return new QuicData(plaintext.data(), plaintext.length());
@@ -71,4 +73,31 @@ StringPiece NullDecrypter::GetKey() const { return StringPiece(); }
StringPiece NullDecrypter::GetNoncePrefix() const { return StringPiece(); }
+bool NullDecrypter::ReadHash(QuicDataReader* reader, uint128* hash) {
+ if (!use_short_hash_) {
+ return reader->ReadUInt128(hash);
+ }
+
+ uint64 lo;
+ uint32 hi;
+ if (!reader->ReadUInt64(&lo) ||
+ !reader->ReadUInt32(&hi)) {
+ return false;
+ }
+ *hash = hi;
+ *hash <<= 64;
+ *hash += lo;
+ return true;
+}
+
+uint128 NullDecrypter::ComputeHash(const string& data) const {
+ uint128 correct_hash = QuicUtils::FNV1a_128_Hash(data.data(), data.length());
+ if (use_short_hash_) {
+ uint128 mask(GG_UINT64_C(0x0), GG_UINT64_C(0xffffffff));
+ mask <<= 96;
+ correct_hash &= ~mask;
+ }
+ return correct_hash;
+}
+
} // namespace net
diff --git a/net/quic/crypto/null_decrypter.h b/net/quic/crypto/null_decrypter.h
index 01beb2d..60ce9b4 100644
--- a/net/quic/crypto/null_decrypter.h
+++ b/net/quic/crypto/null_decrypter.h
@@ -11,11 +11,14 @@
namespace net {
+class QuicDataReader;
+
// A NullDecrypter is a QuicDecrypter used before a crypto negotiation
// has occurred. It does not actually decrypt the payload, but does
// verify a hash (fnv128) over both the payload and associated data.
class NET_EXPORT_PRIVATE NullDecrypter : public QuicDecrypter {
public:
+ explicit NullDecrypter(bool use_short_hash);
virtual ~NullDecrypter() {}
// QuicDecrypter implementation
@@ -31,6 +34,11 @@ class NET_EXPORT_PRIVATE NullDecrypter : public QuicDecrypter {
base::StringPiece ciphertext) OVERRIDE;
virtual base::StringPiece GetKey() const OVERRIDE;
virtual base::StringPiece GetNoncePrefix() const OVERRIDE;
+
+ private:
+ bool ReadHash(QuicDataReader* reader, uint128* hash);
+ uint128 ComputeHash(const std::string& data) const;
+ bool use_short_hash_;
};
} // namespace net
diff --git a/net/quic/crypto/null_decrypter_test.cc b/net/quic/crypto/null_decrypter_test.cc
index e9b9647..7da3c77 100644
--- a/net/quic/crypto/null_decrypter_test.cc
+++ b/net/quic/crypto/null_decrypter_test.cc
@@ -10,7 +10,12 @@ using base::StringPiece;
namespace net {
namespace test {
-TEST(NullDecrypterTest, Decrypt) {
+class NullDecrypterTest : public ::testing::TestWithParam<bool> {
+};
+
+INSTANTIATE_TEST_CASE_P(HashLength, NullDecrypterTest,
+ ::testing::Values(false, true));
+TEST_P(NullDecrypterTest, Decrypt) {
unsigned char expected[] = {
// fnv hash
0xa0, 0x6f, 0x44, 0x8a,
@@ -21,15 +26,26 @@ TEST(NullDecrypterTest, Decrypt) {
'g', 'o', 'o', 'd',
'b', 'y', 'e', '!',
};
- NullDecrypter decrypter;
- scoped_ptr<QuicData> decrypted(decrypter.DecryptPacket(
- 0, "hello world!", StringPiece(reinterpret_cast<const char*>(expected),
- arraysize(expected))));
+ unsigned char expected_short[] = {
+ // fnv hash
+ 0xa0, 0x6f, 0x44, 0x8a,
+ 0x44, 0xf8, 0x18, 0x3b,
+ 0x47, 0x91, 0xb2, 0x13,
+ // payload
+ 'g', 'o', 'o', 'd',
+ 'b', 'y', 'e', '!',
+ };
+ const char* data =
+ reinterpret_cast<const char*>(GetParam() ? expected_short : expected);
+ size_t len = GetParam() ? arraysize(expected_short) : arraysize(expected);
+ NullDecrypter decrypter(GetParam());
+ scoped_ptr<QuicData> decrypted(
+ decrypter.DecryptPacket(0, "hello world!", StringPiece(data, len)));
ASSERT_TRUE(decrypted.get());
EXPECT_EQ("goodbye!", decrypted->AsStringPiece());
}
-TEST(NullDecrypterTest, BadHash) {
+TEST_P(NullDecrypterTest, BadHash) {
unsigned char expected[] = {
// fnv hash
0x46, 0x11, 0xea, 0x5f,
@@ -40,25 +56,44 @@ TEST(NullDecrypterTest, BadHash) {
'g', 'o', 'o', 'd',
'b', 'y', 'e', '!',
};
- NullDecrypter decrypter;
- scoped_ptr<QuicData> decrypted(decrypter.DecryptPacket(
- 0, "hello world!", StringPiece(reinterpret_cast<const char*>(expected),
- arraysize(expected))));
+ unsigned char expected_short[] = {
+ // fnv hash
+ 0x46, 0x11, 0xea, 0x5f,
+ 0xcf, 0x1d, 0x66, 0x5b,
+ 0xba, 0xf0, 0xbc, 0xfd,
+ // payload
+ 'g', 'o', 'o', 'd',
+ 'b', 'y', 'e', '!',
+ };
+ const char* data =
+ reinterpret_cast<const char*>(GetParam() ? expected_short : expected);
+ size_t len = GetParam() ? arraysize(expected_short) : arraysize(expected);
+ NullDecrypter decrypter(GetParam());
+ scoped_ptr<QuicData> decrypted(
+ decrypter.DecryptPacket(0, "hello world!", StringPiece(data, len)));
ASSERT_FALSE(decrypted.get());
}
-TEST(NullDecrypterTest, ShortInput) {
+TEST_P(NullDecrypterTest, ShortInput) {
unsigned char expected[] = {
// fnv hash (truncated)
0x46, 0x11, 0xea, 0x5f,
0xcf, 0x1d, 0x66, 0x5b,
- 0xba, 0xf0, 0xbc, 0xfd,
- 0x88, 0x79, 0xca,
+ 0x47, 0x91, 0xb2, 0x13,
+ 0xba, 0xf0, 0xbc,
+ };
+ unsigned char expected_short[] = {
+ // fnv hash (truncated)
+ 0x46, 0x11, 0xea, 0x5f,
+ 0xcf, 0x1d, 0x66, 0x5b,
+ 0xba, 0xf0, 0xbc,
};
- NullDecrypter decrypter;
- scoped_ptr<QuicData> decrypted(decrypter.DecryptPacket(
- 0, "hello world!", StringPiece(reinterpret_cast<const char*>(expected),
- arraysize(expected))));
+ const char* data =
+ reinterpret_cast<const char*>(GetParam() ? expected_short : expected);
+ size_t len = GetParam() ? arraysize(expected_short) : arraysize(expected);
+ NullDecrypter decrypter(GetParam());
+ scoped_ptr<QuicData> decrypted(
+ decrypter.DecryptPacket(0, "hello world!", StringPiece(data, len)));
ASSERT_FALSE(decrypted.get());
}
diff --git a/net/quic/crypto/null_encrypter.cc b/net/quic/crypto/null_encrypter.cc
index a0a680d..2d9c386 100644
--- a/net/quic/crypto/null_encrypter.cc
+++ b/net/quic/crypto/null_encrypter.cc
@@ -12,6 +12,10 @@ using std::string;
namespace net {
const size_t kHashSize = 16; // size of uint128 serialized
+const size_t kHashSizeShort = 12; // size of uint128 serialized short
+
+NullEncrypter::NullEncrypter(bool use_short_hash)
+ : use_short_hash_(use_short_hash) {}
bool NullEncrypter::SetKey(StringPiece key) { return key.empty(); }
@@ -27,8 +31,12 @@ bool NullEncrypter::Encrypt(
string buffer = associated_data.as_string();
plaintext.AppendToString(&buffer);
uint128 hash = QuicUtils::FNV1a_128_Hash(buffer.data(), buffer.length());
- QuicUtils::SerializeUint128(hash, output);
- memcpy(output + sizeof(hash), plaintext.data(), plaintext.size());
+ if (use_short_hash_) {
+ QuicUtils::SerializeUint128Short(hash, output);
+ } else {
+ QuicUtils::SerializeUint128(hash, output);
+ }
+ memcpy(output + GetHashLength(), plaintext.data(), plaintext.size());
return true;
}
@@ -36,7 +44,7 @@ QuicData* NullEncrypter::EncryptPacket(
QuicPacketSequenceNumber /*sequence_number*/,
StringPiece associated_data,
StringPiece plaintext) {
- const size_t len = plaintext.size() + sizeof(uint128);
+ const size_t len = plaintext.size() + GetHashLength();
uint8* buffer = new uint8[len];
Encrypt(StringPiece(), associated_data, plaintext, buffer);
return new QuicData(reinterpret_cast<char*>(buffer), len, true);
@@ -47,15 +55,19 @@ size_t NullEncrypter::GetKeySize() const { return 0; }
size_t NullEncrypter::GetNoncePrefixSize() const { return 0; }
size_t NullEncrypter::GetMaxPlaintextSize(size_t ciphertext_size) const {
- return ciphertext_size - kHashSize;
+ return ciphertext_size - GetHashLength();
}
size_t NullEncrypter::GetCiphertextSize(size_t plaintext_size) const {
- return plaintext_size + kHashSize;
+ return plaintext_size + GetHashLength();
}
StringPiece NullEncrypter::GetKey() const { return StringPiece(); }
StringPiece NullEncrypter::GetNoncePrefix() const { return StringPiece(); }
+size_t NullEncrypter::GetHashLength() const {
+ return (use_short_hash_ ? kHashSizeShort : kHashSize);
+}
+
} // namespace net
diff --git a/net/quic/crypto/null_encrypter.h b/net/quic/crypto/null_encrypter.h
index ed05e1f..f3d70f2 100644
--- a/net/quic/crypto/null_encrypter.h
+++ b/net/quic/crypto/null_encrypter.h
@@ -16,6 +16,7 @@ namespace net {
// generate a MAC (fnv128) over both the payload and associated data.
class NET_EXPORT_PRIVATE NullEncrypter : public QuicEncrypter {
public:
+ explicit NullEncrypter(bool use_short_hash_);
virtual ~NullEncrypter() {}
// QuicEncrypter implementation
@@ -34,6 +35,11 @@ class NET_EXPORT_PRIVATE NullEncrypter : public QuicEncrypter {
virtual size_t GetCiphertextSize(size_t plaintext_size) const OVERRIDE;
virtual base::StringPiece GetKey() const OVERRIDE;
virtual base::StringPiece GetNoncePrefix() const OVERRIDE;
+
+ private:
+ size_t GetHashLength() const;
+
+ bool use_short_hash_;
};
} // namespace net
diff --git a/net/quic/crypto/null_encrypter_test.cc b/net/quic/crypto/null_encrypter_test.cc
index 4c00f91..77332a1 100644
--- a/net/quic/crypto/null_encrypter_test.cc
+++ b/net/quic/crypto/null_encrypter_test.cc
@@ -10,7 +10,13 @@ using base::StringPiece;
namespace net {
namespace test {
-TEST(NullEncrypterTest, Encrypt) {
+class NullEncrypterTest : public ::testing::TestWithParam<bool> {
+};
+
+INSTANTIATE_TEST_CASE_P(HashLength, NullEncrypterTest,
+ ::testing::Values(false, true));
+
+TEST_P(NullEncrypterTest, Encrypt) {
unsigned char expected[] = {
// fnv hash
0xa0, 0x6f, 0x44, 0x8a,
@@ -21,27 +27,55 @@ TEST(NullEncrypterTest, Encrypt) {
'g', 'o', 'o', 'd',
'b', 'y', 'e', '!',
};
- NullEncrypter encrypter;
+ unsigned char expected_short[] = {
+ // fnv hash
+ 0xa0, 0x6f, 0x44, 0x8a,
+ 0x44, 0xf8, 0x18, 0x3b,
+ 0x47, 0x91, 0xb2, 0x13,
+ // payload
+ 'g', 'o', 'o', 'd',
+ 'b', 'y', 'e', '!',
+ };
+ NullEncrypter encrypter(GetParam());
scoped_ptr<QuicData> encrypted(
encrypter.EncryptPacket(0, "hello world!", "goodbye!"));
ASSERT_TRUE(encrypted.get());
- test::CompareCharArraysWithHexError(
- "encrypted data", encrypted->data(), encrypted->length(),
- reinterpret_cast<const char*>(expected), arraysize(expected));
+ if (GetParam()) {
+ test::CompareCharArraysWithHexError(
+ "encrypted data", encrypted->data(), encrypted->length(),
+ reinterpret_cast<const char*>(expected_short),
+ arraysize(expected_short));
+ } else {
+ test::CompareCharArraysWithHexError(
+ "encrypted data", encrypted->data(), encrypted->length(),
+ reinterpret_cast<const char*>(expected), arraysize(expected));
+ }
}
-TEST(NullEncrypterTest, GetMaxPlaintextSize) {
- NullEncrypter encrypter;
- EXPECT_EQ(1000u, encrypter.GetMaxPlaintextSize(1016));
- EXPECT_EQ(100u, encrypter.GetMaxPlaintextSize(116));
- EXPECT_EQ(10u, encrypter.GetMaxPlaintextSize(26));
+TEST_P(NullEncrypterTest, GetMaxPlaintextSize) {
+ NullEncrypter encrypter(GetParam());
+ if (GetParam()) {
+ EXPECT_EQ(1000u, encrypter.GetMaxPlaintextSize(1012));
+ EXPECT_EQ(100u, encrypter.GetMaxPlaintextSize(112));
+ EXPECT_EQ(10u, encrypter.GetMaxPlaintextSize(22));
+ } else {
+ EXPECT_EQ(1000u, encrypter.GetMaxPlaintextSize(1016));
+ EXPECT_EQ(100u, encrypter.GetMaxPlaintextSize(116));
+ EXPECT_EQ(10u, encrypter.GetMaxPlaintextSize(26));
+ }
}
-TEST(NullEncrypterTest, GetCiphertextSize) {
- NullEncrypter encrypter;
- EXPECT_EQ(1016u, encrypter.GetCiphertextSize(1000));
- EXPECT_EQ(116u, encrypter.GetCiphertextSize(100));
- EXPECT_EQ(26u, encrypter.GetCiphertextSize(10));
+TEST_P(NullEncrypterTest, GetCiphertextSize) {
+ NullEncrypter encrypter(GetParam());
+ if (GetParam()) {
+ EXPECT_EQ(1012u, encrypter.GetCiphertextSize(1000));
+ EXPECT_EQ(112u, encrypter.GetCiphertextSize(100));
+ EXPECT_EQ(22u, encrypter.GetCiphertextSize(10));
+ } else {
+ EXPECT_EQ(1016u, encrypter.GetCiphertextSize(1000));
+ EXPECT_EQ(116u, encrypter.GetCiphertextSize(100));
+ EXPECT_EQ(26u, encrypter.GetCiphertextSize(10));
+ }
}
} // namespace test
diff --git a/net/quic/crypto/quic_decrypter.cc b/net/quic/crypto/quic_decrypter.cc
index fb19d4c..a06edad 100644
--- a/net/quic/crypto/quic_decrypter.cc
+++ b/net/quic/crypto/quic_decrypter.cc
@@ -15,7 +15,9 @@ QuicDecrypter* QuicDecrypter::Create(QuicTag algorithm) {
case kAESG:
return new Aes128Gcm12Decrypter();
case kNULL:
- return new NullDecrypter();
+ return new NullDecrypter(false);
+ case kNULN:
+ return new NullDecrypter(true);
default:
LOG(FATAL) << "Unsupported algorithm: " << algorithm;
return NULL;
diff --git a/net/quic/crypto/quic_encrypter.cc b/net/quic/crypto/quic_encrypter.cc
index 489da8e..3477aa2 100644
--- a/net/quic/crypto/quic_encrypter.cc
+++ b/net/quic/crypto/quic_encrypter.cc
@@ -15,7 +15,9 @@ QuicEncrypter* QuicEncrypter::Create(QuicTag algorithm) {
case kAESG:
return new Aes128Gcm12Encrypter();
case kNULL:
- return new NullEncrypter();
+ return new NullEncrypter(false);
+ case kNULN:
+ return new NullEncrypter(true);
default:
LOG(FATAL) << "Unsupported algorithm: " << algorithm;
return NULL;
diff --git a/net/quic/quic_connection.h b/net/quic/quic_connection.h
index 5ade4ac..1382e06 100644
--- a/net/quic/quic_connection.h
+++ b/net/quic/quic_connection.h
@@ -181,10 +181,6 @@ class NET_EXPORT_PRIVATE QuicConnectionHelperInterface {
// write blocked.
virtual bool IsWriteBlockedDataBuffered() = 0;
- // Returns true if |error| represents a write-block error code such
- // as EAGAIN or ERR_IO_PENDING.
- virtual bool IsWriteBlocked(int error) = 0;
-
// Creates a new platform-specific alarm which will be configured to
// notify |delegate| when the alarm fires. Caller takes ownership
// of the new alarm, which will not yet be "set" to fire.
diff --git a/net/quic/quic_connection_helper.cc b/net/quic/quic_connection_helper.cc
index 1de5013..6139ba8 100644
--- a/net/quic/quic_connection_helper.cc
+++ b/net/quic/quic_connection_helper.cc
@@ -140,10 +140,6 @@ bool QuicConnectionHelper::IsWriteBlockedDataBuffered() {
return true;
}
-bool QuicConnectionHelper::IsWriteBlocked(int error) {
- return error == ERR_IO_PENDING;
-}
-
QuicAlarm* QuicConnectionHelper::CreateAlarm(QuicAlarm::Delegate* delegate) {
return new QuicChromeAlarm(clock_, task_runner_, delegate);
}
diff --git a/net/quic/quic_connection_helper.h b/net/quic/quic_connection_helper.h
index e530176..761b3df 100644
--- a/net/quic/quic_connection_helper.h
+++ b/net/quic/quic_connection_helper.h
@@ -48,7 +48,6 @@ class NET_EXPORT_PRIVATE QuicConnectionHelper
virtual WriteResult WritePacketToWire(
const QuicEncryptedPacket& packet) OVERRIDE;
virtual bool IsWriteBlockedDataBuffered() OVERRIDE;
- virtual bool IsWriteBlocked(int error) OVERRIDE;
virtual QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) OVERRIDE;
private:
diff --git a/net/quic/quic_connection_test.cc b/net/quic/quic_connection_test.cc
index f861b1b..5e0e86e 100644
--- a/net/quic/quic_connection_test.cc
+++ b/net/quic/quic_connection_test.cc
@@ -305,10 +305,6 @@ class TestConnectionHelper : public QuicConnectionHelperInterface {
return is_write_blocked_data_buffered_;
}
- virtual bool IsWriteBlocked(int error) OVERRIDE {
- return error == ERR_IO_PENDING;
- }
-
virtual QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) OVERRIDE {
return new TestAlarm(delegate);
}
diff --git a/net/quic/quic_framer.cc b/net/quic/quic_framer.cc
index cfc8c95..e360ffe 100644
--- a/net/quic/quic_framer.cc
+++ b/net/quic/quic_framer.cc
@@ -118,6 +118,10 @@ QuicPacketSequenceNumber ClosestTo(QuicPacketSequenceNumber target,
return (Delta(target, a) < Delta(target, b)) ? a : b;
}
+QuicTag GetNullTag(QuicVersion version) {
+ return version >= QUIC_VERSION_11 ? kNULN : kNULL;
+}
+
} // namespace
QuicFramer::QuicFramer(QuicVersion version,
@@ -129,12 +133,12 @@ QuicFramer::QuicFramer(QuicVersion version,
last_sequence_number_(0),
last_serialized_guid_(0),
quic_version_(version),
- decrypter_(QuicDecrypter::Create(kNULL)),
+ decrypter_(QuicDecrypter::Create(GetNullTag(version))),
alternative_decrypter_latch_(false),
is_server_(is_server),
creation_time_(creation_time) {
DCHECK(IsSupportedVersion(version));
- encrypter_[ENCRYPTION_NONE].reset(QuicEncrypter::Create(kNULL));
+ encrypter_[ENCRYPTION_NONE].reset(QuicEncrypter::Create(GetNullTag(version)));
}
QuicFramer::~QuicFramer() {}
@@ -1828,6 +1832,13 @@ QuicPacketSequenceNumber QuicFramer::CalculateLargestObserved(
return *largest_written;
}
+void QuicFramer::set_version(const QuicVersion version) {
+ DCHECK(IsSupportedVersion(version));
+ quic_version_ = version;
+ SetDecrypter(QuicDecrypter::Create(GetNullTag(version)));
+ encrypter_[ENCRYPTION_NONE].reset(QuicEncrypter::Create(GetNullTag(version)));
+}
+
// TODO(ianswett): Use varints or another more compact approach for all deltas.
bool QuicFramer::AppendAckFramePayload(
const QuicAckFrame& frame,
diff --git a/net/quic/quic_framer.h b/net/quic/quic_framer.h
index 8411726..94b77b1 100644
--- a/net/quic/quic_framer.h
+++ b/net/quic/quic_framer.h
@@ -186,10 +186,7 @@ class NET_EXPORT_PRIVATE QuicFramer {
return quic_version_;
}
- void set_version(const QuicVersion version) {
- DCHECK(IsSupportedVersion(version));
- quic_version_ = version;
- }
+ void set_version(const QuicVersion version);
// Does not DCHECK for supported version. Used by tests to set unsupported
// version to trigger version negotiation.
diff --git a/net/quic/quic_framer_test.cc b/net/quic/quic_framer_test.cc
index b3bdbac..a0352de 100644
--- a/net/quic/quic_framer_test.cc
+++ b/net/quic/quic_framer_test.cc
@@ -310,13 +310,12 @@ class QuicFramerTest : public ::testing::TestWithParam<QuicVersion> {
decrypter_(new test::TestDecrypter()),
start_(QuicTime::Zero().Add(QuicTime::Delta::FromMicroseconds(0x10))),
framer_(QuicVersionMax(), start_, true) {
+ version_ = GetParam();
+ framer_.set_version(version_);
framer_.SetDecrypter(decrypter_);
framer_.SetEncrypter(ENCRYPTION_NONE, encrypter_);
framer_.set_visitor(&visitor_);
framer_.set_received_entropy_calculator(&entropy_calculator_);
-
- version_ = GetParam();
- framer_.set_version(version_);
}
// Helper function to get unsigned char representation of digit in the
diff --git a/net/quic/quic_packet_generator_test.cc b/net/quic/quic_packet_generator_test.cc
index 809f8dc..9b3e928 100644
--- a/net/quic/quic_packet_generator_test.cc
+++ b/net/quic/quic_packet_generator_test.cc
@@ -462,8 +462,9 @@ TEST_F(QuicPacketGeneratorTest, ConsumeDataSendsFecAtEnd) {
TEST_F(QuicPacketGeneratorTest, ConsumeData_FramesPreviouslyQueued) {
// Set the packet size be enough for two stream frames with 0 stream offset,
// but not enough for a stream frame of 0 offset and one with non-zero offset.
+ bool use_short_hash = framer_.version() >= QUIC_VERSION_11;
creator_.options()->max_packet_length =
- NullEncrypter().GetCiphertextSize(0) +
+ NullEncrypter(use_short_hash).GetCiphertextSize(0) +
GetPacketHeaderSize(creator_.options()->send_guid_length,
true,
creator_.options()->send_sequence_number_length,
diff --git a/net/quic/quic_protocol.cc b/net/quic/quic_protocol.cc
index 928594e..72843ef 100644
--- a/net/quic/quic_protocol.cc
+++ b/net/quic/quic_protocol.cc
@@ -125,6 +125,8 @@ QuicTag QuicVersionToQuicTag(const QuicVersion version) {
return MakeQuicTag('Q', '0', '0', '9');
case QUIC_VERSION_10:
return MakeQuicTag('Q', '0', '1', '0');
+ case QUIC_VERSION_11:
+ return MakeQuicTag('Q', '0', '1', '1');
default:
// This shold be an ERROR because we should never attempt to convert an
// invalid QuicVersion to be written to the wire.
@@ -134,19 +136,15 @@ QuicTag QuicVersionToQuicTag(const QuicVersion version) {
}
QuicVersion QuicTagToQuicVersion(const QuicTag version_tag) {
- const QuicTag quic_tag_v9 = MakeQuicTag('Q', '0', '0', '9');
- const QuicTag quic_tag_v10 = MakeQuicTag('Q', '0', '1', '0');
-
- if (version_tag == quic_tag_v9) {
- return QUIC_VERSION_9;
- } else if (version_tag == quic_tag_v10) {
- return QUIC_VERSION_10;
- } else {
- // Reading from the client so this should not be considered an ERROR.
- DLOG(INFO) << "Unsupported QuicTag version: "
- << QuicUtils::TagToString(version_tag);
- return QUIC_VERSION_UNSUPPORTED;
+ for (size_t i = 0; i < arraysize(kSupportedQuicVersions); ++i) {
+ if (version_tag == QuicVersionToQuicTag(kSupportedQuicVersions[i])) {
+ return kSupportedQuicVersions[i];
+ }
}
+ // Reading from the client so this should not be considered an ERROR.
+ DLOG(INFO) << "Unsupported QuicTag version: "
+ << QuicUtils::TagToString(version_tag);
+ return QUIC_VERSION_UNSUPPORTED;
}
#define RETURN_STRING_LITERAL(x) \
@@ -157,6 +155,7 @@ string QuicVersionToString(const QuicVersion version) {
switch (version) {
RETURN_STRING_LITERAL(QUIC_VERSION_9);
RETURN_STRING_LITERAL(QUIC_VERSION_10);
+ RETURN_STRING_LITERAL(QUIC_VERSION_11);
default:
return "QUIC_VERSION_UNSUPPORTED";
}
diff --git a/net/quic/quic_protocol.h b/net/quic/quic_protocol.h
index c42d1fe..ad42eb4 100644
--- a/net/quic/quic_protocol.h
+++ b/net/quic/quic_protocol.h
@@ -191,7 +191,8 @@ enum QuicVersion {
QUIC_VERSION_UNSUPPORTED = 0,
QUIC_VERSION_9 = 9,
- QUIC_VERSION_10 = 10, // Current version.
+ QUIC_VERSION_10 = 10,
+ QUIC_VERSION_11 = 11, // Current version.
};
// This vector contains QUIC versions which we currently support.
@@ -199,7 +200,7 @@ enum QuicVersion {
// element, with subsequent elements in descending order (versions can be
// skipped as necessary).
static const QuicVersion kSupportedQuicVersions[] =
- {QUIC_VERSION_10, QUIC_VERSION_9};
+ {QUIC_VERSION_11, QUIC_VERSION_10, QUIC_VERSION_9};
typedef std::vector<QuicVersion> QuicVersionVector;
@@ -405,9 +406,11 @@ enum QuicErrorCode {
QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT = 44,
// The server config for a server has expired.
QUIC_CRYPTO_SERVER_CONFIG_EXPIRED = 45,
+ // We failed to setup the symmetric keys for a connection.
+ QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED = 53,
// No error. Used as bound while iterating.
- QUIC_LAST_ERROR = 53,
+ QUIC_LAST_ERROR = 54,
};
struct NET_EXPORT_PRIVATE QuicPacketPublicHeader {
diff --git a/net/quic/quic_protocol_test.cc b/net/quic/quic_protocol_test.cc
index 13c7eb4..0b96e4d 100644
--- a/net/quic/quic_protocol_test.cc
+++ b/net/quic/quic_protocol_test.cc
@@ -63,7 +63,7 @@ TEST(QuicProtocolTest, QuicVersionToQuicTag) {
// default case (i.e. all supported versions should be successfully converted
// to valid QuicTags).
for (size_t i = 0; i < arraysize(kSupportedQuicVersions); ++i) {
- const QuicVersion& version = kSupportedQuicVersions[i];
+ QuicVersion version = kSupportedQuicVersions[i];
EXPECT_LT(0u, QuicVersionToQuicTag(version));
}
}
@@ -99,7 +99,7 @@ TEST(QuicProtocolTest, QuicTagToQuicVersion) {
QuicTagToQuicVersion(MakeQuicTag('Q', '0', '1', '0')));
for (size_t i = 0; i < arraysize(kSupportedQuicVersions); ++i) {
- const QuicVersion& version = kSupportedQuicVersions[i];
+ QuicVersion version = kSupportedQuicVersions[i];
// Get the tag from the version (we can loop over QuicVersions easily).
QuicTag tag = QuicVersionToQuicTag(version);
@@ -139,6 +139,12 @@ TEST(QuicProtocolTest, QuicVersionToString) {
EXPECT_EQ("QUIC_VERSION_10,QUIC_VERSION_9,",
QuicVersionArrayToString(multiple_versions,
arraysize(multiple_versions)));
+
+ // Make sure that all supported versions are present in QuicVersionToString.
+ for (size_t i = 0; i < arraysize(kSupportedQuicVersions); ++i) {
+ QuicVersion version = kSupportedQuicVersions[i];
+ EXPECT_NE("QUIC_VERSION_UNSUPPORTED", QuicVersionToString(version));
+ }
}
} // namespace
diff --git a/net/quic/quic_utils.cc b/net/quic/quic_utils.cc
index a5a0eec..eb092b3 100644
--- a/net/quic/quic_utils.cc
+++ b/net/quic/quic_utils.cc
@@ -111,6 +111,15 @@ void QuicUtils::SerializeUint128(uint128 v, uint8* out) {
memcpy(out + sizeof(lo), &hi, sizeof(hi));
}
+// static
+void QuicUtils::SerializeUint128Short(uint128 v, uint8* out) {
+ const uint64 lo = Uint128Low64(v);
+ const uint64 hi = Uint128High64(v);
+ // This assumes that the system is little-endian.
+ memcpy(out, &lo, sizeof(lo));
+ memcpy(out + sizeof(lo), &hi, sizeof(hi) / 2);
+}
+
#define RETURN_STRING_LITERAL(x) \
case x: \
return #x;
@@ -189,6 +198,7 @@ const char* QuicUtils::ErrorToString(QuicErrorCode error) {
RETURN_STRING_LITERAL(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT);
RETURN_STRING_LITERAL(QUIC_CRYPTO_SERVER_CONFIG_EXPIRED);
RETURN_STRING_LITERAL(QUIC_INVALID_CHANNEL_ID_SIGNATURE);
+ RETURN_STRING_LITERAL(QUIC_CRYPTO_SYMMETRIC_KEY_SETUP_FAILED);
RETURN_STRING_LITERAL(QUIC_LAST_ERROR);
// Intentionally have no default case, so we'll break the build
// if we add errors and don't put them here.
diff --git a/net/quic/quic_utils.h b/net/quic/quic_utils.h
index 37eb9d2..280a3aa 100644
--- a/net/quic/quic_utils.h
+++ b/net/quic/quic_utils.h
@@ -46,6 +46,10 @@ class NET_EXPORT_PRIVATE QuicUtils {
// SerializeUint128 writes |v| in little-endian form to |out|.
static void SerializeUint128(uint128 v, uint8* out);
+ // SerializeUint128 writes the first 96 bits of |v| in little-endian form
+ // to |out|.
+ static void SerializeUint128Short(uint128 v, uint8* out);
+
// Returns the name of the QuicRstStreamErrorCode as a char*
static const char* StreamErrorToString(QuicRstStreamErrorCode error);
diff --git a/net/quic/test_tools/quic_test_utils.cc b/net/quic/test_tools/quic_test_utils.cc
index f32b761..ceb6418 100644
--- a/net/quic/test_tools/quic_test_utils.cc
+++ b/net/quic/test_tools/quic_test_utils.cc
@@ -404,12 +404,13 @@ size_t GetPacketLengthForOneStream(
InFecGroup is_in_fec_group,
size_t* payload_length) {
*payload_length = 1;
+ bool use_short_hash = version >= QUIC_VERSION_11;
const size_t stream_length =
- NullEncrypter().GetCiphertextSize(*payload_length) +
+ NullEncrypter(use_short_hash).GetCiphertextSize(*payload_length) +
QuicPacketCreator::StreamFramePacketOverhead(
version, PACKET_8BYTE_GUID, include_version,
sequence_number_length, is_in_fec_group);
- const size_t ack_length = NullEncrypter().GetCiphertextSize(
+ const size_t ack_length = NullEncrypter(use_short_hash).GetCiphertextSize(
QuicFramer::GetMinAckFrameSize()) +
GetPacketHeaderSize(PACKET_8BYTE_GUID, include_version,
sequence_number_length, is_in_fec_group);
@@ -417,7 +418,7 @@ size_t GetPacketLengthForOneStream(
*payload_length = 1 + ack_length - stream_length;
}
- return NullEncrypter().GetCiphertextSize(*payload_length) +
+ return NullEncrypter(use_short_hash).GetCiphertextSize(*payload_length) +
QuicPacketCreator::StreamFramePacketOverhead(
version, PACKET_8BYTE_GUID, include_version,
sequence_number_length, is_in_fec_group);
diff --git a/net/quic/test_tools/quic_test_utils.h b/net/quic/test_tools/quic_test_utils.h
index fd29824..5449e87 100644
--- a/net/quic/test_tools/quic_test_utils.h
+++ b/net/quic/test_tools/quic_test_utils.h
@@ -200,7 +200,6 @@ class MockHelper : public QuicConnectionHelperInterface {
MOCK_METHOD1(WritePacketToWire,
WriteResult(const QuicEncryptedPacket& packet));
MOCK_METHOD0(IsWriteBlockedDataBuffered, bool());
- MOCK_METHOD1(IsWriteBlocked, bool(int stream_id));
virtual QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate);
private: