| 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 |