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

Side by Side Diff: net/quic/crypto/crypto_framer.cc

Issue 11125002: Add QuicFramer and friends. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix final comments. Created 8 years, 2 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/quic/crypto/crypto_framer.h ('k') | net/quic/crypto/crypto_framer_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 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 #include "net/quic/crypto/crypto_framer.h"
6
7 #include "net/quic/quic_data_reader.h"
8 #include "net/quic/quic_data_writer.h"
9 #include "net/quic/quic_protocol.h"
10
11 using base::StringPiece;
12
13 namespace net {
14
15 CryptoFramer::CryptoFramer()
16 : visitor_(NULL) {
17 Clear();
18 }
19
20 CryptoFramer::~CryptoFramer() {}
21
22 bool CryptoFramer::ProcessInput(StringPiece input) {
23 DCHECK_EQ(QUIC_NO_ERROR, error_);
24 if (error_ != QUIC_NO_ERROR) {
25 return false;
26 }
27 // Add this data to the buffer.
28 buffer_.append(input.data(), input.length());
29 QuicDataReader reader(buffer_.data(), buffer_.length());
30
31 switch (state_) {
32 case STATE_READING_TAG:
33 if (reader.BytesRemaining() < sizeof(uint32)) {
34 break;
35 }
36 reader.ReadUInt32(&message_tag_);
37 state_ = STATE_READING_NUM_ENTRIES;
38 case STATE_READING_NUM_ENTRIES:
39 if (reader.BytesRemaining() < sizeof(uint16)) {
40 break;
41 }
42 reader.ReadUInt16(&num_entries_);
43 if (num_entries_ > kMaxEntries) {
44 error_ = QUIC_CRYPTO_TOO_MANY_ENTRIES;
45 return false;
46 }
47 state_ = STATE_READING_KEY_TAGS;
48 case STATE_READING_KEY_TAGS:
49 if (reader.BytesRemaining() < num_entries_ * sizeof(uint32)) {
50 break;
51 }
52 for (int i = 0; i < num_entries_; ++i) {
53 CryptoTag tag;
54 reader.ReadUInt32(&tag);
55 if (i > 0 && tag <= tags_.back()) {
56 error_ = QUIC_CRYPTO_TAGS_OUT_OF_ORDER;
57 return false;
58 }
59 tags_.push_back(tag);
60 }
61 state_ = STATE_READING_LENGTHS;
62 case STATE_READING_LENGTHS:
63 if (reader.BytesRemaining() < num_entries_ * sizeof(uint16)) {
64 break;
65 }
66 values_len_ = 0;
67 for (int i = 0; i < num_entries_; ++i) {
68 uint16 len;
69 reader.ReadUInt16(&len);
70 tag_length_map_[tags_[i]] = len;
71 values_len_ += len;
72 if (len == 0 && i != num_entries_ - 1) {
73 error_ = QUIC_CRYPTO_INVALID_VALUE_LENGTH;
74 return false;
75 }
76 }
77 state_ = STATE_READING_VALUES;
78 case STATE_READING_VALUES:
79 if (reader.BytesRemaining() < values_len_) {
80 break;
81 }
82 for (int i = 0; i < num_entries_; ++i) {
83 StringPiece value;
84 reader.ReadStringPiece(&value, tag_length_map_[tags_[i]]);
85 tag_value_map_[tags_[i]] = value;
86 }
87 CryptoHandshakeMessage message;
88 message.tag = message_tag_;
89 message.tag_value_map.swap(tag_value_map_);
90 visitor_->OnHandshakeMessage(message);
91 Clear();
92 state_ = STATE_READING_TAG;
93 break;
94 }
95 // Save any left over data
96 buffer_ = reader.PeekRemainingPayload().as_string();
97 return true;
98 }
99
100 bool CryptoFramer::ConstructHandshakeMessage(
101 const CryptoHandshakeMessage& message,
102 QuicData** packet) {
103 if (message.tag_value_map.size() > kMaxEntries) {
104 return false;
105 }
106 size_t len = sizeof(uint32); // message tag
107 len += sizeof(uint16); // number of map entries
108 CryptoTagValueMap::const_iterator it = message.tag_value_map.begin();
109 while (it != message.tag_value_map.end()) {
110 len += sizeof(uint32); // tag
111 len += sizeof(uint16); // value len
112 len += it->second.length(); // value
113 if (it->second.length() == 0) {
114 return false;
115 }
116 ++it;
117 }
118 if (message.tag_value_map.size() % 2 == 1) {
119 len += sizeof(uint16); // padding
120 }
121
122 QuicDataWriter writer(len);
123 CHECK(writer.WriteUInt32(message.tag));
124 CHECK(writer.WriteUInt16(message.tag_value_map.size()));
125 // Tags
126 for (it = message.tag_value_map.begin();
127 it != message.tag_value_map.end(); ++it) {
128 CHECK(writer.WriteUInt32(it->first));
129 }
130 // Lengths
131 for (it = message.tag_value_map.begin();
132 it != message.tag_value_map.end(); ++it) {
133 CHECK(writer.WriteUInt16(it->second.length()));
134 }
135 // Possible padding
136 if (message.tag_value_map.size() % 2 == 1) {
137 CHECK(writer.WriteUInt16(0xABAB));
138 }
139 // Values
140 for (it = message.tag_value_map.begin();
141 it != message.tag_value_map.end(); ++it) {
142 CHECK(writer.WriteBytes(it->second.data(), it->second.length()));
143 }
144 *packet = new QuicData(writer.take(), len, true);
145 return true;
146 }
147
148 void CryptoFramer::Clear() {
149 tag_value_map_.clear();
150 tag_length_map_.clear();
151 tags_.clear();
152 error_ = QUIC_NO_ERROR;
153 state_ = STATE_READING_TAG;
154 }
155
156 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/crypto/crypto_framer.h ('k') | net/quic/crypto/crypto_framer_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698