| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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/flip_server/sm_connection.h" | 5 #include "net/tools/flip_server/sm_connection.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <netinet/tcp.h> | 8 #include <netinet/tcp.h> |
| 9 #include <sys/socket.h> | 9 #include <sys/socket.h> |
| 10 #include <unistd.h> | 10 #include <unistd.h> |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 47 ssl_state_(ssl_state), | 47 ssl_state_(ssl_state), |
| 48 memory_cache_(memory_cache), | 48 memory_cache_(memory_cache), |
| 49 acceptor_(acceptor), | 49 acceptor_(acceptor), |
| 50 read_buffer_(kSpdySegmentSize * 40), | 50 read_buffer_(kSpdySegmentSize * 40), |
| 51 sm_spdy_interface_(NULL), | 51 sm_spdy_interface_(NULL), |
| 52 sm_http_interface_(NULL), | 52 sm_http_interface_(NULL), |
| 53 sm_streamer_interface_(NULL), | 53 sm_streamer_interface_(NULL), |
| 54 sm_interface_(NULL), | 54 sm_interface_(NULL), |
| 55 log_prefix_(log_prefix), | 55 log_prefix_(log_prefix), |
| 56 max_bytes_sent_per_dowrite_(4096), | 56 max_bytes_sent_per_dowrite_(4096), |
| 57 ssl_(NULL) { | 57 ssl_(NULL) {} |
| 58 } | |
| 59 | 58 |
| 60 SMConnection::~SMConnection() { | 59 SMConnection::~SMConnection() { |
| 61 if (initialized()) | 60 if (initialized()) |
| 62 Reset(); | 61 Reset(); |
| 63 } | 62 } |
| 64 | 63 |
| 65 EpollServer* SMConnection::epoll_server() { | 64 EpollServer* SMConnection::epoll_server() { return epoll_server_; } |
| 66 return epoll_server_; | |
| 67 } | |
| 68 | 65 |
| 69 void SMConnection::ReadyToSend() { | 66 void SMConnection::ReadyToSend() { |
| 70 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | 67 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
| 71 << "Setting ready to send: EPOLLIN | EPOLLOUT"; | 68 << "Setting ready to send: EPOLLIN | EPOLLOUT"; |
| 72 epoll_server_->SetFDReady(fd_, EPOLLIN | EPOLLOUT); | 69 epoll_server_->SetFDReady(fd_, EPOLLIN | EPOLLOUT); |
| 73 } | 70 } |
| 74 | 71 |
| 75 void SMConnection::EnqueueDataFrame(DataFrame* df) { | 72 void SMConnection::EnqueueDataFrame(DataFrame* df) { |
| 76 output_list_.push_back(df); | 73 output_list_.push_back(df); |
| 77 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "EnqueueDataFrame: " | 74 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "EnqueueDataFrame: " |
| (...skipping 19 matching lines...) Expand all Loading... |
| 97 if (fd == -1) { | 94 if (fd == -1) { |
| 98 // If fd == -1, then we are initializing a new connection that will | 95 // If fd == -1, then we are initializing a new connection that will |
| 99 // connect to the backend. | 96 // connect to the backend. |
| 100 // | 97 // |
| 101 // ret: -1 == error | 98 // ret: -1 == error |
| 102 // 0 == connection in progress | 99 // 0 == connection in progress |
| 103 // 1 == connection complete | 100 // 1 == connection complete |
| 104 // TODO(kelindsay): is_numeric_host_address value needs to be detected | 101 // TODO(kelindsay): is_numeric_host_address value needs to be detected |
| 105 server_ip_ = server_ip; | 102 server_ip_ = server_ip; |
| 106 server_port_ = server_port; | 103 server_port_ = server_port; |
| 107 int ret = CreateConnectedSocket(&fd_, | 104 int ret = CreateConnectedSocket( |
| 108 server_ip, | 105 &fd_, server_ip, server_port, true, acceptor_->disable_nagle_); |
| 109 server_port, | |
| 110 true, | |
| 111 acceptor_->disable_nagle_); | |
| 112 | 106 |
| 113 if (ret < 0) { | 107 if (ret < 0) { |
| 114 LOG(ERROR) << "-1 Could not create connected socket"; | 108 LOG(ERROR) << "-1 Could not create connected socket"; |
| 115 return; | 109 return; |
| 116 } else if (ret == 1) { | 110 } else if (ret == 1) { |
| 117 DCHECK_NE(-1, fd_); | 111 DCHECK_NE(-1, fd_); |
| 118 connection_complete_ = true; | 112 connection_complete_ = true; |
| 119 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | 113 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
| 120 << "Connection complete to: " << server_ip_ << ":" | 114 << "Connection complete to: " << server_ip_ << ":" << server_port_ |
| 121 << server_port_ << " "; | 115 << " "; |
| 122 } | 116 } |
| 123 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | 117 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
| 124 << "Connecting to server: " << server_ip_ << ":" | 118 << "Connecting to server: " << server_ip_ << ":" << server_port_ |
| 125 << server_port_ << " "; | 119 << " "; |
| 126 } else { | 120 } else { |
| 127 // If fd != -1 then we are initializing a connection that has just been | 121 // If fd != -1 then we are initializing a connection that has just been |
| 128 // accepted from the listen socket. | 122 // accepted from the listen socket. |
| 129 connection_complete_ = true; | 123 connection_complete_ = true; |
| 130 if (epoll_server_ && registered_in_epoll_server_ && fd_ != -1) { | 124 if (epoll_server_ && registered_in_epoll_server_ && fd_ != -1) { |
| 131 epoll_server_->UnregisterFD(fd_); | 125 epoll_server_->UnregisterFD(fd_); |
| 132 } | 126 } |
| 133 if (fd_ != -1) { | 127 if (fd_ != -1) { |
| 134 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | 128 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
| 135 << "Closing pre-existing fd"; | 129 << "Closing pre-existing fd"; |
| 136 close(fd_); | 130 close(fd_); |
| 137 fd_ = -1; | 131 fd_ = -1; |
| 138 } | 132 } |
| 139 | 133 |
| 140 fd_ = fd; | 134 fd_ = fd; |
| 141 } | 135 } |
| 142 | 136 |
| 143 registered_in_epoll_server_ = false; | 137 registered_in_epoll_server_ = false; |
| 144 // Set the last read time here as the idle checker will start from | 138 // Set the last read time here as the idle checker will start from |
| 145 // now. | 139 // now. |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 254 return; | 248 return; |
| 255 Reset(); | 249 Reset(); |
| 256 if (connection_pool_) | 250 if (connection_pool_) |
| 257 connection_pool_->SMConnectionDone(this); | 251 connection_pool_->SMConnectionDone(this); |
| 258 if (sm_interface_) | 252 if (sm_interface_) |
| 259 sm_interface_->ResetForNewConnection(); | 253 sm_interface_->ResetForNewConnection(); |
| 260 last_read_time_ = 0; | 254 last_read_time_ = 0; |
| 261 } | 255 } |
| 262 | 256 |
| 263 void SMConnection::HandleEvents() { | 257 void SMConnection::HandleEvents() { |
| 264 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "Received: " | 258 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
| 265 << EpollServer::EventMaskToString(events_).c_str(); | 259 << "Received: " << EpollServer::EventMaskToString(events_).c_str(); |
| 266 | 260 |
| 267 if (events_ & EPOLLIN) { | 261 if (events_ & EPOLLIN) { |
| 268 if (!DoRead()) | 262 if (!DoRead()) |
| 269 goto handle_close_or_error; | 263 goto handle_close_or_error; |
| 270 } | 264 } |
| 271 | 265 |
| 272 if (events_ & EPOLLOUT) { | 266 if (events_ & EPOLLOUT) { |
| 273 // Check if we have connected or not | 267 // Check if we have connected or not |
| 274 if (connection_complete_ == false) { | 268 if (connection_complete_ == false) { |
| 275 int sock_error; | 269 int sock_error; |
| 276 socklen_t sock_error_len = sizeof(sock_error); | 270 socklen_t sock_error_len = sizeof(sock_error); |
| 277 int ret = getsockopt(fd_, SOL_SOCKET, SO_ERROR, &sock_error, | 271 int ret = |
| 278 &sock_error_len); | 272 getsockopt(fd_, SOL_SOCKET, SO_ERROR, &sock_error, &sock_error_len); |
| 279 if (ret != 0) { | 273 if (ret != 0) { |
| 280 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | 274 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
| 281 << "getsockopt error: " << errno << ": " << strerror(errno); | 275 << "getsockopt error: " << errno << ": " << strerror(errno); |
| 282 goto handle_close_or_error; | 276 goto handle_close_or_error; |
| 283 } | 277 } |
| 284 if (sock_error == 0) { | 278 if (sock_error == 0) { |
| 285 connection_complete_ = true; | 279 connection_complete_ = true; |
| 286 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | 280 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
| 287 << "Connection complete to " << server_ip_ << ":" | 281 << "Connection complete to " << server_ip_ << ":" |
| 288 << server_port_ << " "; | 282 << server_port_ << " "; |
| 289 } else if (sock_error == EINPROGRESS) { | 283 } else if (sock_error == EINPROGRESS) { |
| 290 return; | 284 return; |
| 291 } else { | 285 } else { |
| 292 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | 286 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
| 293 << "error connecting to server"; | 287 << "error connecting to server"; |
| 294 goto handle_close_or_error; | 288 goto handle_close_or_error; |
| 295 } | 289 } |
| 296 } | 290 } |
| 297 if (!DoWrite()) | 291 if (!DoWrite()) |
| 298 goto handle_close_or_error; | 292 goto handle_close_or_error; |
| 299 } | 293 } |
| 300 | 294 |
| 301 if (events_ & (EPOLLHUP | EPOLLERR)) { | 295 if (events_ & (EPOLLHUP | EPOLLERR)) { |
| 302 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "!!! Got HUP or ERR"; | 296 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "!!! Got HUP or ERR"; |
| 303 goto handle_close_or_error; | 297 goto handle_close_or_error; |
| 304 } | 298 } |
| 305 return; | 299 return; |
| 306 | 300 |
| 307 handle_close_or_error: | 301 handle_close_or_error: |
| 308 Cleanup("HandleEvents"); | 302 Cleanup("HandleEvents"); |
| 309 } | 303 } |
| 310 | 304 |
| 311 // Decide if SPDY was negotiated. | 305 // Decide if SPDY was negotiated. |
| 312 bool SMConnection::WasSpdyNegotiated(SpdyMajorVersion* version_negotiated) { | 306 bool SMConnection::WasSpdyNegotiated(SpdyMajorVersion* version_negotiated) { |
| 313 *version_negotiated = SPDY3; | 307 *version_negotiated = SPDY3; |
| 314 if (force_spdy()) | 308 if (force_spdy()) |
| 315 return true; | 309 return true; |
| 316 | 310 |
| 317 // If this is an SSL connection, check if NPN specifies SPDY. | 311 // If this is an SSL connection, check if NPN specifies SPDY. |
| 318 if (ssl_) { | 312 if (ssl_) { |
| 319 const unsigned char *npn_proto; | 313 const unsigned char* npn_proto; |
| 320 unsigned int npn_proto_len; | 314 unsigned int npn_proto_len; |
| 321 SSL_get0_next_proto_negotiated(ssl_, &npn_proto, &npn_proto_len); | 315 SSL_get0_next_proto_negotiated(ssl_, &npn_proto, &npn_proto_len); |
| 322 if (npn_proto_len > 0) { | 316 if (npn_proto_len > 0) { |
| 323 std::string npn_proto_str((const char *)npn_proto, npn_proto_len); | 317 std::string npn_proto_str((const char*)npn_proto, npn_proto_len); |
| 324 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | 318 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
| 325 << "NPN protocol detected: " << npn_proto_str; | 319 << "NPN protocol detected: " << npn_proto_str; |
| 326 if (!strncmp(reinterpret_cast<const char*>(npn_proto), | 320 if (!strncmp(reinterpret_cast<const char*>(npn_proto), |
| 327 "spdy/2", npn_proto_len)) { | 321 "spdy/2", |
| 322 npn_proto_len)) { |
| 328 *version_negotiated = SPDY2; | 323 *version_negotiated = SPDY2; |
| 329 return true; | 324 return true; |
| 330 } | 325 } |
| 331 if (!strncmp(reinterpret_cast<const char*>(npn_proto), | 326 if (!strncmp(reinterpret_cast<const char*>(npn_proto), |
| 332 "spdy/3", npn_proto_len)) { | 327 "spdy/3", |
| 328 npn_proto_len)) { |
| 333 *version_negotiated = SPDY3; | 329 *version_negotiated = SPDY3; |
| 334 return true; | 330 return true; |
| 335 } | 331 } |
| 336 if (!strncmp(reinterpret_cast<const char*>(npn_proto), | 332 if (!strncmp(reinterpret_cast<const char*>(npn_proto), |
| 337 "spdy/4a2", npn_proto_len)) { | 333 "spdy/4a2", |
| 334 npn_proto_len)) { |
| 338 *version_negotiated = SPDY4; | 335 *version_negotiated = SPDY4; |
| 339 return true; | 336 return true; |
| 340 } | 337 } |
| 341 } | 338 } |
| 342 } | 339 } |
| 343 | 340 |
| 344 return false; | 341 return false; |
| 345 } | 342 } |
| 346 | 343 |
| 347 bool SMConnection::SetupProtocolInterfaces() { | 344 bool SMConnection::SetupProtocolInterfaces() { |
| 348 DCHECK(!protocol_detected_); | 345 DCHECK(!protocol_detected_); |
| 349 protocol_detected_ = true; | 346 protocol_detected_ = true; |
| 350 | 347 |
| 351 SpdyMajorVersion version; | 348 SpdyMajorVersion version; |
| 352 bool spdy_negotiated = WasSpdyNegotiated(&version); | 349 bool spdy_negotiated = WasSpdyNegotiated(&version); |
| 353 bool using_ssl = ssl_ != NULL; | 350 bool using_ssl = ssl_ != NULL; |
| 354 | 351 |
| 355 if (using_ssl) | 352 if (using_ssl) |
| 356 VLOG(1) << (SSL_session_reused(ssl_) ? "Resumed" : "Renegotiated") | 353 VLOG(1) << (SSL_session_reused(ssl_) ? "Resumed" : "Renegotiated") |
| 357 << " SSL Session."; | 354 << " SSL Session."; |
| 358 | 355 |
| 359 if (acceptor_->spdy_only_ && !spdy_negotiated) { | 356 if (acceptor_->spdy_only_ && !spdy_negotiated) { |
| 360 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | 357 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
| 361 << "SPDY proxy only, closing HTTPS connection."; | 358 << "SPDY proxy only, closing HTTPS connection."; |
| 362 return false; | 359 return false; |
| 363 } | 360 } |
| 364 | 361 |
| 365 switch (acceptor_->flip_handler_type_) { | 362 switch (acceptor_->flip_handler_type_) { |
| 366 case FLIP_HANDLER_HTTP_SERVER: | 363 case FLIP_HANDLER_HTTP_SERVER: { |
| 367 { | 364 DCHECK(!spdy_negotiated); |
| 368 DCHECK(!spdy_negotiated); | 365 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
| 369 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | 366 << (sm_http_interface_ ? "Creating" : "Reusing") |
| 370 << (sm_http_interface_ ? "Creating" : "Reusing") | 367 << " HTTP interface."; |
| 371 << " HTTP interface."; | 368 if (!sm_http_interface_) |
| 372 if (!sm_http_interface_) | 369 sm_http_interface_ = new HttpSM(this, NULL, memory_cache_, acceptor_); |
| 373 sm_http_interface_ = new HttpSM(this, | 370 sm_interface_ = sm_http_interface_; |
| 374 NULL, | 371 break; |
| 375 memory_cache_, | 372 } |
| 376 acceptor_); | 373 case FLIP_HANDLER_PROXY: { |
| 377 sm_interface_ = sm_http_interface_; | 374 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
| 375 << (sm_streamer_interface_ ? "Creating" : "Reusing") |
| 376 << " PROXY Streamer interface."; |
| 377 if (!sm_streamer_interface_) { |
| 378 sm_streamer_interface_ = |
| 379 new StreamerSM(this, NULL, epoll_server_, acceptor_); |
| 380 sm_streamer_interface_->set_is_request(); |
| 378 } | 381 } |
| 382 sm_interface_ = sm_streamer_interface_; |
| 383 // If spdy is not negotiated, the streamer interface will proxy all |
| 384 // data to the origin server. |
| 385 if (!spdy_negotiated) |
| 386 break; |
| 387 } |
| 388 // Otherwise fall through into the case below. |
| 389 case FLIP_HANDLER_SPDY_SERVER: { |
| 390 DCHECK(spdy_negotiated); |
| 391 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
| 392 << (sm_spdy_interface_ ? "Creating" : "Reusing") |
| 393 << " SPDY interface."; |
| 394 if (!sm_spdy_interface_) |
| 395 sm_spdy_interface_ = new SpdySM( |
| 396 this, NULL, epoll_server_, memory_cache_, acceptor_, version); |
| 397 sm_interface_ = sm_spdy_interface_; |
| 379 break; | 398 break; |
| 380 case FLIP_HANDLER_PROXY: | 399 } |
| 381 { | |
| 382 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | |
| 383 << (sm_streamer_interface_ ? "Creating" : "Reusing") | |
| 384 << " PROXY Streamer interface."; | |
| 385 if (!sm_streamer_interface_) { | |
| 386 sm_streamer_interface_ = new StreamerSM(this, | |
| 387 NULL, | |
| 388 epoll_server_, | |
| 389 acceptor_); | |
| 390 sm_streamer_interface_->set_is_request(); | |
| 391 } | |
| 392 sm_interface_ = sm_streamer_interface_; | |
| 393 // If spdy is not negotiated, the streamer interface will proxy all | |
| 394 // data to the origin server. | |
| 395 if (!spdy_negotiated) | |
| 396 break; | |
| 397 } | |
| 398 // Otherwise fall through into the case below. | |
| 399 case FLIP_HANDLER_SPDY_SERVER: | |
| 400 { | |
| 401 DCHECK(spdy_negotiated); | |
| 402 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | |
| 403 << (sm_spdy_interface_ ? "Creating" : "Reusing") | |
| 404 << " SPDY interface."; | |
| 405 if (!sm_spdy_interface_) | |
| 406 sm_spdy_interface_ = new SpdySM(this, | |
| 407 NULL, | |
| 408 epoll_server_, | |
| 409 memory_cache_, | |
| 410 acceptor_, | |
| 411 version); | |
| 412 sm_interface_ = sm_spdy_interface_; | |
| 413 } | |
| 414 break; | |
| 415 } | 400 } |
| 416 | 401 |
| 417 CorkSocket(); | 402 CorkSocket(); |
| 418 if (!sm_interface_->PostAcceptHook()) | 403 if (!sm_interface_->PostAcceptHook()) |
| 419 return false; | 404 return false; |
| 420 | 405 |
| 421 return true; | 406 return true; |
| 422 } | 407 } |
| 423 | 408 |
| 424 bool SMConnection::DoRead() { | 409 bool SMConnection::DoRead() { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | 447 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
| 463 << "Got EAGAIN while reading"; | 448 << "Got EAGAIN while reading"; |
| 464 goto done; | 449 goto done; |
| 465 case EINTR: | 450 case EINTR: |
| 466 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | 451 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
| 467 << "Got EINTR while reading"; | 452 << "Got EINTR while reading"; |
| 468 continue; | 453 continue; |
| 469 default: | 454 default: |
| 470 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | 455 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
| 471 << "While calling recv, got error: " | 456 << "While calling recv, got error: " |
| 472 << (ssl_?"(ssl error)":strerror(stored_errno)); | 457 << (ssl_ ? "(ssl error)" : strerror(stored_errno)); |
| 473 goto error_or_close; | 458 goto error_or_close; |
| 474 } | 459 } |
| 475 } else if (bytes_read > 0) { | 460 } else if (bytes_read > 0) { |
| 476 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "read " << bytes_read | 461 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "read " << bytes_read |
| 477 << " bytes"; | 462 << " bytes"; |
| 478 last_read_time_ = time(NULL); | 463 last_read_time_ = time(NULL); |
| 479 // If the protocol hasn't been detected yet, set up the handlers | 464 // If the protocol hasn't been detected yet, set up the handlers |
| 480 // we'll need. | 465 // we'll need. |
| 481 if (!protocol_detected_) { | 466 if (!protocol_detected_) { |
| 482 if (!SetupProtocolInterfaces()) { | 467 if (!SetupProtocolInterfaces()) { |
| 483 LOG(ERROR) << "Error setting up protocol interfaces."; | 468 LOG(ERROR) << "Error setting up protocol interfaces."; |
| 484 goto error_or_close; | 469 goto error_or_close; |
| 485 } | 470 } |
| 486 } | 471 } |
| 487 read_buffer_.AdvanceWritablePtr(bytes_read); | 472 read_buffer_.AdvanceWritablePtr(bytes_read); |
| 488 if (!DoConsumeReadData()) | 473 if (!DoConsumeReadData()) |
| 489 goto error_or_close; | 474 goto error_or_close; |
| 490 continue; | 475 continue; |
| 491 } else { // bytes_read == 0 | 476 } else { // bytes_read == 0 |
| 492 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | 477 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
| 493 << "0 bytes read with recv call."; | 478 << "0 bytes read with recv call."; |
| 494 } | 479 } |
| 495 goto error_or_close; | 480 goto error_or_close; |
| 496 } | 481 } |
| 497 done: | 482 done: |
| 498 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "DoRead done!"; | 483 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "DoRead done!"; |
| 499 return true; | 484 return true; |
| 500 | 485 |
| 501 error_or_close: | 486 error_or_close: |
| 502 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | 487 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
| 503 << "DoRead(): error_or_close. " | 488 << "DoRead(): error_or_close. " |
| 504 << "Cleaning up, then returning false"; | 489 << "Cleaning up, then returning false"; |
| 505 Cleanup("DoRead"); | 490 Cleanup("DoRead"); |
| 506 return false; | 491 return false; |
| 507 } | 492 } |
| 508 | 493 |
| 509 bool SMConnection::DoConsumeReadData() { | 494 bool SMConnection::DoConsumeReadData() { |
| 510 char* bytes; | 495 char* bytes; |
| 511 int size; | 496 int size; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 529 << sm_interface_->ErrorAsString(); | 514 << sm_interface_->ErrorAsString(); |
| 530 // this causes everything to be closed/cleaned up. | 515 // this causes everything to be closed/cleaned up. |
| 531 events_ |= EPOLLOUT; | 516 events_ |= EPOLLOUT; |
| 532 return false; | 517 return false; |
| 533 } | 518 } |
| 534 read_buffer_.GetReadablePtr(&bytes, &size); | 519 read_buffer_.GetReadablePtr(&bytes, &size); |
| 535 } | 520 } |
| 536 return true; | 521 return true; |
| 537 } | 522 } |
| 538 | 523 |
| 539 void SMConnection::HandleResponseFullyRead() { | 524 void SMConnection::HandleResponseFullyRead() { sm_interface_->Cleanup(); } |
| 540 sm_interface_->Cleanup(); | |
| 541 } | |
| 542 | 525 |
| 543 bool SMConnection::DoWrite() { | 526 bool SMConnection::DoWrite() { |
| 544 size_t bytes_sent = 0; | 527 size_t bytes_sent = 0; |
| 545 int flags = MSG_NOSIGNAL | MSG_DONTWAIT; | 528 int flags = MSG_NOSIGNAL | MSG_DONTWAIT; |
| 546 if (fd_ == -1) { | 529 if (fd_ == -1) { |
| 547 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | 530 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
| 548 << "DoWrite: fd == -1. Returning false."; | 531 << "DoWrite: fd == -1. Returning false."; |
| 549 return false; | 532 return false; |
| 550 } | 533 } |
| 551 if (output_list_.empty()) { | 534 if (output_list_.empty()) { |
| 552 VLOG(2) << log_prefix_ << "DoWrite: Output list empty."; | 535 VLOG(2) << log_prefix_ << "DoWrite: Output list empty."; |
| 553 if (sm_interface_) { | 536 if (sm_interface_) { |
| 554 sm_interface_->GetOutput(); | 537 sm_interface_->GetOutput(); |
| 555 } | 538 } |
| 556 if (output_list_.empty()) { | 539 if (output_list_.empty()) { |
| 557 events_ &= ~EPOLLOUT; | 540 events_ &= ~EPOLLOUT; |
| 558 } | 541 } |
| 559 } | 542 } |
| 560 while (!output_list_.empty()) { | 543 while (!output_list_.empty()) { |
| 561 VLOG(2) << log_prefix_ << "DoWrite: Items in output list: " | 544 VLOG(2) << log_prefix_ |
| 562 << output_list_.size(); | 545 << "DoWrite: Items in output list: " << output_list_.size(); |
| 563 if (bytes_sent >= max_bytes_sent_per_dowrite_) { | 546 if (bytes_sent >= max_bytes_sent_per_dowrite_) { |
| 564 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | 547 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
| 565 << " byte sent >= max bytes sent per write: Setting EPOLLOUT: " | 548 << " byte sent >= max bytes sent per write: Setting EPOLLOUT: " |
| 566 << bytes_sent; | 549 << bytes_sent; |
| 567 events_ |= EPOLLOUT; | 550 events_ |= EPOLLOUT; |
| 568 break; | 551 break; |
| 569 } | 552 } |
| 570 if (sm_interface_ && output_list_.size() < 2) { | 553 if (sm_interface_ && output_list_.size() < 2) { |
| 571 sm_interface_->GetOutput(); | 554 sm_interface_->GetOutput(); |
| 572 } | 555 } |
| 573 DataFrame* data_frame = output_list_.front(); | 556 DataFrame* data_frame = output_list_.front(); |
| 574 const char* bytes = data_frame->data; | 557 const char* bytes = data_frame->data; |
| 575 int size = data_frame->size; | 558 int size = data_frame->size; |
| 576 bytes += data_frame->index; | 559 bytes += data_frame->index; |
| 577 size -= data_frame->index; | 560 size -= data_frame->index; |
| 578 DCHECK_GE(size, 0); | 561 DCHECK_GE(size, 0); |
| 579 if (size <= 0) { | 562 if (size <= 0) { |
| 580 output_list_.pop_front(); | 563 output_list_.pop_front(); |
| 581 delete data_frame; | 564 delete data_frame; |
| 582 continue; | 565 continue; |
| 583 } | 566 } |
| 584 | 567 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 599 events_ &= ~EPOLLOUT; | 582 events_ &= ~EPOLLOUT; |
| 600 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | 583 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
| 601 << "Got EAGAIN while writing"; | 584 << "Got EAGAIN while writing"; |
| 602 goto done; | 585 goto done; |
| 603 case EINTR: | 586 case EINTR: |
| 604 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | 587 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
| 605 << "Got EINTR while writing"; | 588 << "Got EINTR while writing"; |
| 606 continue; | 589 continue; |
| 607 default: | 590 default: |
| 608 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | 591 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
| 609 << "While calling send, got error: " << stored_errno | 592 << "While calling send, got error: " << stored_errno << ": " |
| 610 << ": " << (ssl_?"":strerror(stored_errno)); | 593 << (ssl_ ? "" : strerror(stored_errno)); |
| 611 goto error_or_close; | 594 goto error_or_close; |
| 612 } | 595 } |
| 613 } else if (bytes_written > 0) { | 596 } else if (bytes_written > 0) { |
| 614 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "Wrote: " | 597 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
| 615 << bytes_written << " bytes"; | 598 << "Wrote: " << bytes_written << " bytes"; |
| 616 data_frame->index += bytes_written; | 599 data_frame->index += bytes_written; |
| 617 bytes_sent += bytes_written; | 600 bytes_sent += bytes_written; |
| 618 continue; | 601 continue; |
| 619 } else if (bytes_written == -2) { | 602 } else if (bytes_written == -2) { |
| 620 // -2 handles SSL_ERROR_WANT_* errors | 603 // -2 handles SSL_ERROR_WANT_* errors |
| 621 events_ &= ~EPOLLOUT; | 604 events_ &= ~EPOLLOUT; |
| 622 goto done; | 605 goto done; |
| 623 } | 606 } |
| 624 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT | 607 VLOG(1) << log_prefix_ << ACCEPTOR_CLIENT_IDENT |
| 625 << "0 bytes written with send call."; | 608 << "0 bytes written with send call."; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 653 } | 636 } |
| 654 if (fd_ >= 0) { | 637 if (fd_ >= 0) { |
| 655 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "Closing connection"; | 638 VLOG(2) << log_prefix_ << ACCEPTOR_CLIENT_IDENT << "Closing connection"; |
| 656 close(fd_); | 639 close(fd_); |
| 657 fd_ = -1; | 640 fd_ = -1; |
| 658 } | 641 } |
| 659 read_buffer_.Clear(); | 642 read_buffer_.Clear(); |
| 660 initialized_ = false; | 643 initialized_ = false; |
| 661 protocol_detected_ = false; | 644 protocol_detected_ = false; |
| 662 events_ = 0; | 645 events_ = 0; |
| 663 for (std::list<DataFrame*>::iterator i = | 646 for (std::list<DataFrame*>::iterator i = output_list_.begin(); |
| 664 output_list_.begin(); | |
| 665 i != output_list_.end(); | 647 i != output_list_.end(); |
| 666 ++i) { | 648 ++i) { |
| 667 delete *i; | 649 delete *i; |
| 668 } | 650 } |
| 669 output_list_.clear(); | 651 output_list_.clear(); |
| 670 } | 652 } |
| 671 | 653 |
| 672 // static | 654 // static |
| 673 SMConnection* SMConnection::NewSMConnection(EpollServer* epoll_server, | 655 SMConnection* SMConnection::NewSMConnection(EpollServer* epoll_server, |
| 674 SSLState *ssl_state, | 656 SSLState* ssl_state, |
| 675 MemoryCache* memory_cache, | 657 MemoryCache* memory_cache, |
| 676 FlipAcceptor *acceptor, | 658 FlipAcceptor* acceptor, |
| 677 std::string log_prefix) { | 659 std::string log_prefix) { |
| 678 return new SMConnection(epoll_server, ssl_state, memory_cache, | 660 return new SMConnection( |
| 679 acceptor, log_prefix); | 661 epoll_server, ssl_state, memory_cache, acceptor, log_prefix); |
| 680 } | 662 } |
| 681 | 663 |
| 682 } // namespace net | 664 } // namespace net |
| OLD | NEW |