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

Side by Side Diff: net/tools/quic/quic_dispatcher.cc

Issue 123303003: Move all the packet parsing logic into QuicDispatcher from the (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 11 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/tools/quic/quic_dispatcher.h ('k') | net/tools/quic/quic_dispatcher_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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/tools/quic/quic_dispatcher.h" 5 #include "net/tools/quic/quic_dispatcher.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/stl_util.h" 10 #include "base/stl_util.h"
11 #include "net/quic/quic_blocked_writer_interface.h" 11 #include "net/quic/quic_blocked_writer_interface.h"
12 #include "net/quic/quic_utils.h" 12 #include "net/quic/quic_utils.h"
13 #include "net/tools/quic/quic_default_packet_writer.h" 13 #include "net/tools/quic/quic_default_packet_writer.h"
14 #include "net/tools/quic/quic_epoll_connection_helper.h" 14 #include "net/tools/quic/quic_epoll_connection_helper.h"
15 #include "net/tools/quic/quic_socket_utils.h" 15 #include "net/tools/quic/quic_socket_utils.h"
16 16
17 namespace net { 17 namespace net {
18 namespace tools { 18 namespace tools {
19 19
20 using base::StringPiece;
20 using std::make_pair; 21 using std::make_pair;
21 22
22 class DeleteSessionsAlarm : public EpollAlarm { 23 class DeleteSessionsAlarm : public EpollAlarm {
23 public: 24 public:
24 explicit DeleteSessionsAlarm(QuicDispatcher* dispatcher) 25 explicit DeleteSessionsAlarm(QuicDispatcher* dispatcher)
25 : dispatcher_(dispatcher) { 26 : dispatcher_(dispatcher) {
26 } 27 }
27 28
28 virtual int64 OnAlarm() OVERRIDE { 29 virtual int64 OnAlarm() OVERRIDE {
29 EpollAlarm::OnAlarm(); 30 EpollAlarm::OnAlarm();
30 dispatcher_->DeleteSessions(); 31 dispatcher_->DeleteSessions();
31 return 0; 32 return 0;
32 } 33 }
33 34
34 private: 35 private:
35 QuicDispatcher* dispatcher_; 36 QuicDispatcher* dispatcher_;
36 }; 37 };
37 38
39 class QuicDispatcher::QuicFramerVisitor : public QuicFramerVisitorInterface {
40 public:
41 explicit QuicFramerVisitor(QuicDispatcher* dispatcher)
42 : dispatcher_(dispatcher) {
43 }
44
45 // QuicFramerVisitorInterface implementation
46 virtual void OnPacket() OVERRIDE {}
47 virtual bool OnUnauthenticatedPublicHeader(
48 const QuicPacketPublicHeader& header) OVERRIDE {
49 return dispatcher_->OnUnauthenticatedPublicHeader(header);
50 }
51 virtual bool OnUnauthenticatedHeader(
52 const QuicPacketHeader& header) OVERRIDE {
53 dispatcher_->OnUnauthenticatedHeader(header);
54 return false;
55 }
56 virtual void OnError(QuicFramer* framer) OVERRIDE {
57 DLOG(INFO) << QuicUtils::ErrorToString(framer->error());
58 }
59
60 // The following methods should never get called because we always return
61 // false from OnUnauthenticatedHeader(). As a result, we never process the
62 // payload of the packet.
63 virtual bool OnProtocolVersionMismatch(
64 QuicVersion /*received_version*/) OVERRIDE {
65 DCHECK(false);
66 return false;
67 }
68 virtual void OnPublicResetPacket(
69 const QuicPublicResetPacket& /*packet*/) OVERRIDE {
70 DCHECK(false);
71 }
72 virtual void OnVersionNegotiationPacket(
73 const QuicVersionNegotiationPacket& /*packet*/) OVERRIDE {
74 DCHECK(false);
75 }
76 virtual void OnPacketComplete() OVERRIDE {
77 DCHECK(false);
78 }
79 virtual bool OnPacketHeader(const QuicPacketHeader& /*header*/) OVERRIDE {
80 DCHECK(false);
81 return false;
82 }
83 virtual void OnRevivedPacket() OVERRIDE {
84 DCHECK(false);
85 }
86 virtual void OnFecProtectedPayload(StringPiece /*payload*/) OVERRIDE {
87 DCHECK(false);
88 }
89 virtual bool OnStreamFrame(const QuicStreamFrame& /*frame*/) OVERRIDE {
90 DCHECK(false);
91 return false;
92 }
93 virtual bool OnAckFrame(const QuicAckFrame& /*frame*/) OVERRIDE {
94 DCHECK(false);
95 return false;
96 }
97 virtual bool OnCongestionFeedbackFrame(
98 const QuicCongestionFeedbackFrame& /*frame*/) OVERRIDE {
99 DCHECK(false);
100 return false;
101 }
102 virtual bool OnRstStreamFrame(const QuicRstStreamFrame& /*frame*/) OVERRIDE {
103 DCHECK(false);
104 return false;
105 }
106 virtual bool OnConnectionCloseFrame(
107 const QuicConnectionCloseFrame & /*frame*/) OVERRIDE {
108 DCHECK(false);
109 return false;
110 }
111 virtual bool OnGoAwayFrame(const QuicGoAwayFrame& /*frame*/) OVERRIDE {
112 DCHECK(false);
113 return false;
114 }
115 virtual void OnFecData(const QuicFecData& /*fec*/) OVERRIDE {
116 DCHECK(false);
117 }
118
119 private:
120 QuicDispatcher* dispatcher_;
121 };
122
38 QuicDispatcher::QuicDispatcher(const QuicConfig& config, 123 QuicDispatcher::QuicDispatcher(const QuicConfig& config,
39 const QuicCryptoServerConfig& crypto_config, 124 const QuicCryptoServerConfig& crypto_config,
40 const QuicVersionVector& supported_versions, 125 const QuicVersionVector& supported_versions,
41 int fd, 126 int fd,
42 EpollServer* epoll_server) 127 EpollServer* epoll_server)
43 : config_(config), 128 : config_(config),
44 crypto_config_(crypto_config), 129 crypto_config_(crypto_config),
45 time_wait_list_manager_( 130 time_wait_list_manager_(
46 new QuicTimeWaitListManager(this, epoll_server, supported_versions)), 131 new QuicTimeWaitListManager(this, epoll_server, supported_versions)),
47 delete_sessions_alarm_(new DeleteSessionsAlarm(this)), 132 delete_sessions_alarm_(new DeleteSessionsAlarm(this)),
48 epoll_server_(epoll_server), 133 epoll_server_(epoll_server),
49 fd_(fd), 134 fd_(fd),
50 write_blocked_(false), 135 write_blocked_(false),
51 helper_(new QuicEpollConnectionHelper(epoll_server_)), 136 helper_(new QuicEpollConnectionHelper(epoll_server_)),
52 writer_(new QuicDefaultPacketWriter(fd)), 137 writer_(new QuicDefaultPacketWriter(fd)),
53 supported_versions_(supported_versions) { 138 supported_versions_(supported_versions),
139 current_packet_(NULL),
140 framer_(supported_versions, /*unused*/ QuicTime::Zero(), true),
141 framer_visitor_(new QuicFramerVisitor(this)) {
142 framer_.set_visitor(framer_visitor_.get());
54 } 143 }
55 144
56 QuicDispatcher::~QuicDispatcher() { 145 QuicDispatcher::~QuicDispatcher() {
57 STLDeleteValues(&session_map_); 146 STLDeleteValues(&session_map_);
58 STLDeleteElements(&closed_session_list_); 147 STLDeleteElements(&closed_session_list_);
59 } 148 }
60 149
61 void QuicDispatcher::set_fd(int fd) { 150 void QuicDispatcher::set_fd(int fd) {
62 fd_ = fd; 151 fd_ = fd;
63 writer_.reset(new QuicDefaultPacketWriter(fd)); 152 writer_.reset(new QuicDefaultPacketWriter(fd));
(...skipping 16 matching lines...) Expand all
80 } 169 }
81 return result; 170 return result;
82 } 171 }
83 172
84 bool QuicDispatcher::IsWriteBlockedDataBuffered() const { 173 bool QuicDispatcher::IsWriteBlockedDataBuffered() const {
85 return writer_->IsWriteBlockedDataBuffered(); 174 return writer_->IsWriteBlockedDataBuffered();
86 } 175 }
87 176
88 void QuicDispatcher::ProcessPacket(const IPEndPoint& server_address, 177 void QuicDispatcher::ProcessPacket(const IPEndPoint& server_address,
89 const IPEndPoint& client_address, 178 const IPEndPoint& client_address,
90 QuicGuid guid,
91 bool has_version_flag,
92 const QuicEncryptedPacket& packet) { 179 const QuicEncryptedPacket& packet) {
180 current_server_address_ = server_address;
181 current_client_address_ = client_address;
182 current_packet_ = &packet;
183 // ProcessPacket will cause the packet to be dispatched in
184 // OnUnauthenticatedPublicHeader, or sent to the time wait list manager
185 // in OnAuthenticatedHeader.
186 framer_.ProcessPacket(packet);
187 // TODO(rjshade): Return a status describing if/why a packet was dropped,
188 // and log somehow. Maybe expose as a varz.
189 }
190
191 bool QuicDispatcher::OnUnauthenticatedPublicHeader(
192 const QuicPacketPublicHeader& header) {
93 QuicSession* session = NULL; 193 QuicSession* session = NULL;
94 194
195 QuicGuid guid = header.guid;
95 SessionMap::iterator it = session_map_.find(guid); 196 SessionMap::iterator it = session_map_.find(guid);
96 if (it == session_map_.end()) { 197 if (it == session_map_.end()) {
198 if (header.reset_flag) {
199 return false;
200 }
97 if (time_wait_list_manager_->IsGuidInTimeWait(guid)) { 201 if (time_wait_list_manager_->IsGuidInTimeWait(guid)) {
98 time_wait_list_manager_->ProcessPacket(server_address, 202 return HandlePacketForTimeWait(header);
99 client_address,
100 guid,
101 packet);
102 return;
103 } 203 }
104 204
105 // Ensure the packet has a version negotiation bit set before creating a new 205 // Ensure the packet has a version negotiation bit set before creating a new
106 // session for it. All initial packets for a new connection are required to 206 // session for it. All initial packets for a new connection are required to
107 // have the flag set. Otherwise it may be a stray packet. 207 // have the flag set. Otherwise it may be a stray packet.
108 if (has_version_flag) { 208 if (header.version_flag) {
109 session = CreateQuicSession(guid, server_address, client_address); 209 session = CreateQuicSession(guid, current_server_address_,
210 current_client_address_);
110 } 211 }
111 212
112 if (session == NULL) { 213 if (session == NULL) {
113 DLOG(INFO) << "Failed to create session for " << guid; 214 DLOG(INFO) << "Failed to create session for " << guid;
114 // Add this guid fo the time-wait state, to safely reject future packets. 215 // Add this guid fo the time-wait state, to safely reject future packets.
115 // We don't know the version here, so assume latest. 216
116 // TODO(ianswett): Produce a no-version version negotiation packet. 217 if (header.version_flag &&
117 time_wait_list_manager_->AddGuidToTimeWait(guid, 218 !framer_.IsSupportedVersion(header.versions.front())) {
118 supported_versions_.front(), 219 // TODO(ianswett): Produce a no-version version negotiation packet.
119 NULL); 220 return false;
120 time_wait_list_manager_->ProcessPacket(server_address, 221 }
121 client_address, 222
122 guid, 223 // Use the version in the packet if possible, otherwise assume the latest.
123 packet); 224 QuicVersion version = header.version_flag ? header.versions.front() :
124 return; 225 supported_versions_.front();
226 time_wait_list_manager_->AddGuidToTimeWait(guid, version, NULL);
227 DCHECK(time_wait_list_manager_->IsGuidInTimeWait(guid));
228 return HandlePacketForTimeWait(header);
125 } 229 }
126 DLOG(INFO) << "Created new session for " << guid; 230 DLOG(INFO) << "Created new session for " << guid;
127 session_map_.insert(make_pair(guid, session)); 231 session_map_.insert(make_pair(guid, session));
128 } else { 232 } else {
129 session = it->second; 233 session = it->second;
130 } 234 }
131 235
132 session->connection()->ProcessUdpPacket( 236 session->connection()->ProcessUdpPacket(
133 server_address, client_address, packet); 237 current_server_address_, current_client_address_, *current_packet_);
238
239 // Do not parse the packet further. The session will process it completely.
240 return false;
241 }
242
243 void QuicDispatcher::OnUnauthenticatedHeader(const QuicPacketHeader& header) {
244 DCHECK(time_wait_list_manager_->IsGuidInTimeWait(header.public_header.guid));
245 time_wait_list_manager_->ProcessPacket(current_server_address_,
246 current_client_address_,
247 header.public_header.guid,
248 header.packet_sequence_number);
134 } 249 }
135 250
136 void QuicDispatcher::CleanUpSession(SessionMap::iterator it) { 251 void QuicDispatcher::CleanUpSession(SessionMap::iterator it) {
137 QuicConnection* connection = it->second->connection(); 252 QuicConnection* connection = it->second->connection();
138 QuicEncryptedPacket* connection_close_packet = 253 QuicEncryptedPacket* connection_close_packet =
139 connection->ReleaseConnectionClosePacket(); 254 connection->ReleaseConnectionClosePacket();
140 write_blocked_list_.erase(connection); 255 write_blocked_list_.erase(connection);
141 time_wait_list_manager_->AddGuidToTimeWait(it->first, 256 time_wait_list_manager_->AddGuidToTimeWait(it->first,
142 connection->version(), 257 connection->version(),
143 connection_close_packet); 258 connection_close_packet);
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 QuicGuid guid, 331 QuicGuid guid,
217 const IPEndPoint& server_address, 332 const IPEndPoint& server_address,
218 const IPEndPoint& client_address) { 333 const IPEndPoint& client_address) {
219 QuicServerSession* session = new QuicServerSession( 334 QuicServerSession* session = new QuicServerSession(
220 config_, new QuicConnection(guid, client_address, helper_.get(), this, 335 config_, new QuicConnection(guid, client_address, helper_.get(), this,
221 true, supported_versions_), this); 336 true, supported_versions_), this);
222 session->InitializeSession(crypto_config_); 337 session->InitializeSession(crypto_config_);
223 return session; 338 return session;
224 } 339 }
225 340
341 bool QuicDispatcher::HandlePacketForTimeWait(
342 const QuicPacketPublicHeader& header) {
343 if (header.reset_flag) {
344 // Public reset packets do not have sequence numbers, so ignore the packet.
345 return false;
346 }
347
348 // Switch the framer to the correct version, so that the sequence number can
349 // be parsed correctly.
350 framer_.set_version(time_wait_list_manager_->GetQuicVersionFromGuid(
351 header.guid));
352
353 // Continue parsing the packet to extract the sequence number. Then
354 // send it to the time wait manager in OnUnathenticatedHeader.
355 return true;
356 }
357
226 } // namespace tools 358 } // namespace tools
227 } // namespace net 359 } // namespace net
OLDNEW
« no previous file with comments | « net/tools/quic/quic_dispatcher.h ('k') | net/tools/quic/quic_dispatcher_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698