OLD | NEW |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |