• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef NET_QUIC_CRYPTO_CRYPTO_HANDSHAKE_MESSAGE_H_
6 #define NET_QUIC_CRYPTO_CRYPTO_HANDSHAKE_MESSAGE_H_
7 
8 #include <string>
9 #include <vector>
10 
11 #include "base/memory/scoped_ptr.h"
12 #include "base/strings/string_piece.h"
13 #include "net/base/net_export.h"
14 #include "net/quic/quic_protocol.h"
15 
16 namespace net {
17 
18 // An intermediate format of a handshake message that's convenient for a
19 // CryptoFramer to serialize from or parse into.
20 class NET_EXPORT_PRIVATE CryptoHandshakeMessage {
21  public:
22   CryptoHandshakeMessage();
23   CryptoHandshakeMessage(const CryptoHandshakeMessage& other);
24   ~CryptoHandshakeMessage();
25 
26   CryptoHandshakeMessage& operator=(const CryptoHandshakeMessage& other);
27 
28   // Clears state.
29   void Clear();
30 
31   // GetSerialized returns the serialized form of this message and caches the
32   // result. Subsequently altering the message does not invalidate the cache.
33   const QuicData& GetSerialized() const;
34 
35   // MarkDirty invalidates the cache created by |GetSerialized|.
36   void MarkDirty();
37 
38   // SetValue sets an element with the given tag to the raw, memory contents of
39   // |v|.
SetValue(QuicTag tag,const T & v)40   template<class T> void SetValue(QuicTag tag, const T& v) {
41     tag_value_map_[tag] =
42         std::string(reinterpret_cast<const char*>(&v), sizeof(v));
43   }
44 
45   // SetVector sets an element with the given tag to the raw contents of an
46   // array of elements in |v|.
SetVector(QuicTag tag,const std::vector<T> & v)47   template<class T> void SetVector(QuicTag tag, const std::vector<T>& v) {
48     if (v.empty()) {
49       tag_value_map_[tag] = std::string();
50     } else {
51       tag_value_map_[tag] = std::string(reinterpret_cast<const char*>(&v[0]),
52                                         v.size() * sizeof(T));
53     }
54   }
55 
56   // Returns the message tag.
tag()57   QuicTag tag() const { return tag_; }
58   // Sets the message tag.
set_tag(QuicTag tag)59   void set_tag(QuicTag tag) { tag_ = tag; }
60 
tag_value_map()61   const QuicTagValueMap& tag_value_map() const { return tag_value_map_; }
62 
63   // SetTaglist sets an element with the given tag to contain a list of tags,
64   // passed as varargs. The argument list must be terminated with a 0 element.
65   void SetTaglist(QuicTag tag, ...);
66 
67   void SetStringPiece(QuicTag tag, base::StringPiece value);
68 
69   // Erase removes a tag/value, if present, from the message.
70   void Erase(QuicTag tag);
71 
72   // GetTaglist finds an element with the given tag containing zero or more
73   // tags. If such a tag doesn't exist, it returns false. Otherwise it sets
74   // |out_tags| and |out_len| to point to the array of tags and returns true.
75   // The array points into the CryptoHandshakeMessage and is valid only for as
76   // long as the CryptoHandshakeMessage exists and is not modified.
77   QuicErrorCode GetTaglist(QuicTag tag, const QuicTag** out_tags,
78                            size_t* out_len) const;
79 
80   bool GetStringPiece(QuicTag tag, base::StringPiece* out) const;
81 
82   // GetNthValue24 interprets the value with the given tag to be a series of
83   // 24-bit, length prefixed values and it returns the subvalue with the given
84   // index.
85   QuicErrorCode GetNthValue24(QuicTag tag,
86                               unsigned index,
87                               base::StringPiece* out) const;
88   QuicErrorCode GetUint16(QuicTag tag, uint16* out) const;
89   QuicErrorCode GetUint32(QuicTag tag, uint32* out) const;
90   QuicErrorCode GetUint64(QuicTag tag, uint64* out) const;
91 
92   // size returns 4 (message tag) + 2 (uint16, number of entries) +
93   // (4 (tag) + 4 (end offset))*tag_value_map_.size() + ∑ value sizes.
94   size_t size() const;
95 
96   // set_minimum_size sets the minimum number of bytes that the message should
97   // consume. The CryptoFramer will add a PAD tag as needed when serializing in
98   // order to ensure this. Setting a value of 0 disables padding.
99   //
100   // Padding is useful in order to ensure that messages are a minimum size. A
101   // QUIC server can require a minimum size in order to reduce the
102   // amplification factor of any mirror DoS attack.
103   void set_minimum_size(size_t min_bytes);
104 
105   size_t minimum_size() const;
106 
107   // DebugString returns a multi-line, string representation of the message
108   // suitable for including in debug output.
109   std::string DebugString() const;
110 
111  private:
112   // GetPOD is a utility function for extracting a plain-old-data value. If
113   // |tag| exists in the message, and has a value of exactly |len| bytes then
114   // it copies |len| bytes of data into |out|. Otherwise |len| bytes at |out|
115   // are zeroed out.
116   //
117   // If used to copy integers then this assumes that the machine is
118   // little-endian.
119   QuicErrorCode GetPOD(QuicTag tag, void* out, size_t len) const;
120 
121   std::string DebugStringInternal(size_t indent) const;
122 
123   QuicTag tag_;
124   QuicTagValueMap tag_value_map_;
125 
126   size_t minimum_size_;
127 
128   // The serialized form of the handshake message. This member is constructed
129   // lasily.
130   mutable scoped_ptr<QuicData> serialized_;
131 };
132 
133 }  // namespace net
134 
135 #endif  // NET_QUIC_CRYPTO_CRYPTO_HANDSHAKE_MESSAGE_H_
136