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" |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
125 const QuicVersionVector& supported_versions, | 125 const QuicVersionVector& supported_versions, |
126 int fd, | 126 int fd, |
127 EpollServer* epoll_server) | 127 EpollServer* epoll_server) |
128 : config_(config), | 128 : config_(config), |
129 crypto_config_(crypto_config), | 129 crypto_config_(crypto_config), |
130 time_wait_list_manager_( | 130 time_wait_list_manager_( |
131 new QuicTimeWaitListManager(this, epoll_server, supported_versions)), | 131 new QuicTimeWaitListManager(this, epoll_server, supported_versions)), |
132 delete_sessions_alarm_(new DeleteSessionsAlarm(this)), | 132 delete_sessions_alarm_(new DeleteSessionsAlarm(this)), |
133 epoll_server_(epoll_server), | 133 epoll_server_(epoll_server), |
134 fd_(fd), | 134 fd_(fd), |
135 write_blocked_(false), | |
136 helper_(new QuicEpollConnectionHelper(epoll_server_)), | 135 helper_(new QuicEpollConnectionHelper(epoll_server_)), |
137 writer_(new QuicDefaultPacketWriter(fd)), | 136 writer_(new QuicDefaultPacketWriter(fd)), |
138 supported_versions_(supported_versions), | 137 supported_versions_(supported_versions), |
139 current_packet_(NULL), | 138 current_packet_(NULL), |
140 framer_(supported_versions, /*unused*/ QuicTime::Zero(), true), | 139 framer_(supported_versions, /*unused*/ QuicTime::Zero(), true), |
141 framer_visitor_(new QuicFramerVisitor(this)) { | 140 framer_visitor_(new QuicFramerVisitor(this)) { |
142 framer_.set_visitor(framer_visitor_.get()); | 141 framer_.set_visitor(framer_visitor_.get()); |
143 } | 142 } |
144 | 143 |
145 QuicDispatcher::~QuicDispatcher() { | 144 QuicDispatcher::~QuicDispatcher() { |
146 STLDeleteValues(&session_map_); | 145 STLDeleteValues(&session_map_); |
147 STLDeleteElements(&closed_session_list_); | 146 STLDeleteElements(&closed_session_list_); |
148 } | 147 } |
149 | 148 |
150 void QuicDispatcher::set_fd(int fd) { | 149 void QuicDispatcher::set_fd(int fd) { |
151 fd_ = fd; | 150 fd_ = fd; |
152 writer_.reset(new QuicDefaultPacketWriter(fd)); | 151 writer_.reset(new QuicDefaultPacketWriter(fd)); |
153 } | 152 } |
154 | 153 |
| 154 // TODO(fnk): remove the Writer interface implementation in favor of |
| 155 // direct requests for blocked list placement from Connection/Session. |
155 WriteResult QuicDispatcher::WritePacket(const char* buffer, size_t buf_len, | 156 WriteResult QuicDispatcher::WritePacket(const char* buffer, size_t buf_len, |
156 const IPAddressNumber& self_address, | 157 const IPAddressNumber& self_address, |
157 const IPEndPoint& peer_address, | 158 const IPEndPoint& peer_address, |
158 QuicBlockedWriterInterface* writer) { | 159 QuicBlockedWriterInterface* writer) { |
159 if (write_blocked_) { | 160 if (IsWriteBlocked()) { |
160 write_blocked_list_.insert(make_pair(writer, true)); | 161 write_blocked_list_.insert(make_pair(writer, true)); |
161 return WriteResult(WRITE_STATUS_BLOCKED, EAGAIN); | 162 return WriteResult(WRITE_STATUS_BLOCKED, EAGAIN); |
162 } | 163 } |
163 | 164 |
164 WriteResult result = | 165 WriteResult result = |
165 writer_->WritePacket(buffer, buf_len, self_address, peer_address, writer); | 166 writer_->WritePacket(buffer, buf_len, self_address, peer_address, writer); |
166 if (result.status == WRITE_STATUS_BLOCKED) { | 167 if (result.status == WRITE_STATUS_BLOCKED) { |
| 168 DCHECK(IsWriteBlocked()); |
167 write_blocked_list_.insert(make_pair(writer, true)); | 169 write_blocked_list_.insert(make_pair(writer, true)); |
168 write_blocked_ = true; | |
169 } | 170 } |
170 return result; | 171 return result; |
171 } | 172 } |
172 | 173 |
173 bool QuicDispatcher::IsWriteBlockedDataBuffered() const { | 174 bool QuicDispatcher::IsWriteBlockedDataBuffered() const { |
174 return writer_->IsWriteBlockedDataBuffered(); | 175 return writer_->IsWriteBlockedDataBuffered(); |
175 } | 176 } |
176 | 177 |
| 178 bool QuicDispatcher::IsWriteBlocked() const { |
| 179 return writer_->IsWriteBlocked(); |
| 180 } |
| 181 |
| 182 void QuicDispatcher::SetWritable() { |
| 183 writer_->SetWritable(); |
| 184 } |
| 185 |
177 void QuicDispatcher::ProcessPacket(const IPEndPoint& server_address, | 186 void QuicDispatcher::ProcessPacket(const IPEndPoint& server_address, |
178 const IPEndPoint& client_address, | 187 const IPEndPoint& client_address, |
179 const QuicEncryptedPacket& packet) { | 188 const QuicEncryptedPacket& packet) { |
180 current_server_address_ = server_address; | 189 current_server_address_ = server_address; |
181 current_client_address_ = client_address; | 190 current_client_address_ = client_address; |
182 current_packet_ = &packet; | 191 current_packet_ = &packet; |
183 // ProcessPacket will cause the packet to be dispatched in | 192 // ProcessPacket will cause the packet to be dispatched in |
184 // OnUnauthenticatedPublicHeader, or sent to the time wait list manager | 193 // OnUnauthenticatedPublicHeader, or sent to the time wait list manager |
185 // in OnAuthenticatedHeader. | 194 // in OnAuthenticatedHeader. |
186 framer_.ProcessPacket(packet); | 195 framer_.ProcessPacket(packet); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 time_wait_list_manager_->AddGuidToTimeWait(it->first, | 265 time_wait_list_manager_->AddGuidToTimeWait(it->first, |
257 connection->version(), | 266 connection->version(), |
258 connection_close_packet); | 267 connection_close_packet); |
259 session_map_.erase(it); | 268 session_map_.erase(it); |
260 } | 269 } |
261 | 270 |
262 void QuicDispatcher::DeleteSessions() { | 271 void QuicDispatcher::DeleteSessions() { |
263 STLDeleteElements(&closed_session_list_); | 272 STLDeleteElements(&closed_session_list_); |
264 } | 273 } |
265 | 274 |
266 void QuicDispatcher::UseWriter(QuicPacketWriter* writer) { | |
267 writer_.reset(writer); | |
268 } | |
269 | |
270 bool QuicDispatcher::OnCanWrite() { | 275 bool QuicDispatcher::OnCanWrite() { |
271 // We got an EPOLLOUT: the socket should not be blocked. | 276 // We got an EPOLLOUT: the socket should not be blocked. |
272 write_blocked_ = false; | 277 SetWritable(); |
273 | 278 |
274 // Give each writer one attempt to write. | 279 // Give each writer one attempt to write. |
275 int num_writers = write_blocked_list_.size(); | 280 int num_writers = write_blocked_list_.size(); |
276 for (int i = 0; i < num_writers; ++i) { | 281 for (int i = 0; i < num_writers; ++i) { |
277 if (write_blocked_list_.empty()) { | 282 if (write_blocked_list_.empty()) { |
278 break; | 283 break; |
279 } | 284 } |
280 QuicBlockedWriterInterface* writer = write_blocked_list_.begin()->first; | 285 QuicBlockedWriterInterface* writer = write_blocked_list_.begin()->first; |
281 write_blocked_list_.erase(write_blocked_list_.begin()); | 286 write_blocked_list_.erase(write_blocked_list_.begin()); |
282 bool can_write_more = writer->OnCanWrite(); | 287 bool can_write_more = writer->OnCanWrite(); |
283 if (write_blocked_) { | 288 if (IsWriteBlocked()) { |
284 // We were unable to write. Wait for the next EPOLLOUT. | 289 // We were unable to write. Wait for the next EPOLLOUT. |
285 // In this case, the session would have been added to the blocked list | 290 // In this case, the session would have been added to the blocked list |
286 // up in WritePacket. | 291 // up in WritePacket. |
287 return false; | 292 return false; |
288 } | 293 } |
289 // The socket is not blocked but the writer has ceded work. Add it to the | 294 // The socket is not blocked but the writer has ceded work. Add it to the |
290 // end of the list. | 295 // end of the list. |
291 if (can_write_more) { | 296 if (can_write_more) { |
292 write_blocked_list_.insert(make_pair(writer, true)); | 297 write_blocked_list_.insert(make_pair(writer, true)); |
293 } | 298 } |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
350 framer_.set_version(time_wait_list_manager_->GetQuicVersionFromGuid( | 355 framer_.set_version(time_wait_list_manager_->GetQuicVersionFromGuid( |
351 header.guid)); | 356 header.guid)); |
352 | 357 |
353 // Continue parsing the packet to extract the sequence number. Then | 358 // Continue parsing the packet to extract the sequence number. Then |
354 // send it to the time wait manager in OnUnathenticatedHeader. | 359 // send it to the time wait manager in OnUnathenticatedHeader. |
355 return true; | 360 return true; |
356 } | 361 } |
357 | 362 |
358 } // namespace tools | 363 } // namespace tools |
359 } // namespace net | 364 } // namespace net |
OLD | NEW |