Land Recent QUIC Changes 

Alter the serialisation format of the crypto messages.

This changes the format of the crypto messages so that:
  * We can cope with > 65K values in order to be robust to
    post-quantum algorithms in the future.
  * Rather than encoding lengths, we encode the offset one byte past the end of
    the value. This allows an implementation to binary search the header
    without having to do all the allocation and copying the we currently do.

Merge internal change: 44699015

Automated rollback of changelist 44685914.

Rollback: Bugfix infinite wait

Merge internal change: 44693957

QUIC: retransmit packets with the correct encryption.

This change does four things:
  * Splits the concept of a completed handshake in two: when encryption is
    established and when the server has confirmed the handshake. In order to do
    0-RTT, we have to start sending after the first of those events.
  * Retransmits packets using the same encryption level as they were sent with.
    Without this, the loss of a client hello message is fatal to the connection
    because it will be retransmitted under encryption and the server will never
    be able to process it.
  * Makes decryption failures an ignored error. This is needed because, if a
    client hello message is lost, the subsequent packets will be encrypted and
    the server won't have the decrypter to process them.
  * Changes how decrypters are handled by the framer. A server now replaces its
    decrypter completely - thus removing the NullDecrypter. The client now has
    latching alternative decrypters which replace the primary decrypter when
    used. This doesn't completely close the hole: the connection still needs to
    worry about plaintext packets injected into the client.

This change does not implement the correct fallback for the server rejecting a
full client hello. It also doesn't implement a limit for the number of packets
that we'll send without the server confirming the handshake. I'm hoping that
rch can do that much more easily than I can!

Merge internal change: 44690884

[email protected]

Review URL: https://chromiumcodereview.appspot.com/14718011

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@198099 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/net/quic/quic_protocol.h b/net/quic/quic_protocol.h
index d4f23de..efb2459 100644
--- a/net/quic/quic_protocol.h
+++ b/net/quic/quic_protocol.h
@@ -224,6 +224,8 @@
   QUIC_CRYPTO_TOO_MANY_REJECTS,
   // The client rejected the server's certificate chain or signature.
   QUIC_PROOF_INVALID,
+  // A crypto message was received with a duplicate tag.
+  QUIC_CRYPTO_DUPLICATE_TAG,
 
   // No error. Used as bound while iterating.
   QUIC_LAST_ERROR,
@@ -461,6 +463,18 @@
   std::string reason_phrase;
 };
 
+// EncryptionLevel enumerates the stages of encryption that a QUIC connection
+// progresses through. When retransmitting a packet, the encryption level needs
+// to be specified so that it is retransmitted at a level which the peer can
+// understand.
+enum EncryptionLevel {
+  ENCRYPTION_NONE = 0,
+  ENCRYPTION_INITIAL = 1,
+  ENCRYPTION_FORWARD_SECURE = 2,
+
+  NUM_ENCRYPTION_LEVELS,
+};
+
 struct NET_EXPORT_PRIVATE QuicFrame {
   QuicFrame() {}
   explicit QuicFrame(QuicPaddingFrame* padding_frame)
@@ -628,8 +642,14 @@
   const QuicFrame& AddNonStreamFrame(const QuicFrame& frame);
   const QuicFrames& frames() const { return frames_; }
 
+  void set_encryption_level(EncryptionLevel level);
+  EncryptionLevel encryption_level() const {
+    return encryption_level_;
+  }
+
  private:
   QuicFrames frames_;
+  EncryptionLevel encryption_level_;
   // Data referenced by the StringPiece of a QuicStreamFrame.
   std::vector<std::string*> stream_data_;