| 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_client.h" | 5 #include "net/tools/quic/quic_client.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <netinet/in.h> | 8 #include <netinet/in.h> |
| 9 #include <string.h> | 9 #include <string.h> |
| 10 #include <sys/epoll.h> | 10 #include <sys/epoll.h> |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 supported_versions, | 67 supported_versions, |
| 68 config, | 68 config, |
| 69 new QuicEpollConnectionHelper(epoll_server), | 69 new QuicEpollConnectionHelper(epoll_server), |
| 70 proof_verifier), | 70 proof_verifier), |
| 71 server_address_(server_address), | 71 server_address_(server_address), |
| 72 local_port_(0), | 72 local_port_(0), |
| 73 epoll_server_(epoll_server), | 73 epoll_server_(epoll_server), |
| 74 initialized_(false), | 74 initialized_(false), |
| 75 packets_dropped_(0), | 75 packets_dropped_(0), |
| 76 overflow_supported_(false), | 76 overflow_supported_(false), |
| 77 use_recvmmsg_(false), |
| 77 store_response_(false), | 78 store_response_(false), |
| 78 latest_response_code_(-1), | 79 latest_response_code_(-1), |
| 79 packet_reader_(CreateQuicPacketReader()) {} | 80 packet_reader_(new QuicPacketReader()) {} |
| 80 | 81 |
| 81 QuicClient::~QuicClient() { | 82 QuicClient::~QuicClient() { |
| 82 if (connected()) { | 83 if (connected()) { |
| 83 session()->connection()->SendConnectionCloseWithDetails( | 84 session()->connection()->SendConnectionCloseWithDetails( |
| 84 QUIC_PEER_GOING_AWAY, "Client being torn down"); | 85 QUIC_PEER_GOING_AWAY, "Client being torn down"); |
| 85 } | 86 } |
| 86 | 87 |
| 87 STLDeleteElements(&data_to_resend_on_connect_); | 88 STLDeleteElements(&data_to_resend_on_connect_); |
| 88 STLDeleteElements(&data_sent_before_handshake_); | 89 STLDeleteElements(&data_sent_before_handshake_); |
| 89 | 90 |
| 90 CleanUpAllUDPSockets(); | 91 CleanUpAllUDPSockets(); |
| 91 } | 92 } |
| 92 | 93 |
| 93 bool QuicClient::Initialize() { | 94 bool QuicClient::Initialize() { |
| 94 QuicClientBase::Initialize(); | 95 QuicClientBase::Initialize(); |
| 95 | 96 |
| 97 #if MMSG_MORE |
| 98 use_recvmmsg_ = true; |
| 99 #endif |
| 100 |
| 101 set_num_sent_client_hellos(0); |
| 102 set_num_stateless_rejects_received(0); |
| 103 set_connection_error(QUIC_NO_ERROR); |
| 104 |
| 96 // If an initial flow control window has not explicitly been set, then use the | 105 // If an initial flow control window has not explicitly been set, then use the |
| 97 // same values that Chrome uses. | 106 // same values that Chrome uses. |
| 98 const uint32_t kSessionMaxRecvWindowSize = 15 * 1024 * 1024; // 15 MB | 107 const uint32_t kSessionMaxRecvWindowSize = 15 * 1024 * 1024; // 15 MB |
| 99 const uint32_t kStreamMaxRecvWindowSize = 6 * 1024 * 1024; // 6 MB | 108 const uint32_t kStreamMaxRecvWindowSize = 6 * 1024 * 1024; // 6 MB |
| 100 if (config()->GetInitialStreamFlowControlWindowToSend() == | 109 if (config()->GetInitialStreamFlowControlWindowToSend() == |
| 101 kMinimumFlowControlSendWindow) { | 110 kMinimumFlowControlSendWindow) { |
| 102 config()->SetInitialStreamFlowControlWindowToSend(kStreamMaxRecvWindowSize); | 111 config()->SetInitialStreamFlowControlWindowToSend(kStreamMaxRecvWindowSize); |
| 103 } | 112 } |
| 104 if (config()->GetInitialSessionFlowControlWindowToSend() == | 113 if (config()->GetInitialSessionFlowControlWindowToSend() == |
| 105 kMinimumFlowControlSendWindow) { | 114 kMinimumFlowControlSendWindow) { |
| 106 config()->SetInitialSessionFlowControlWindowToSend( | 115 config()->SetInitialSessionFlowControlWindowToSend( |
| 107 kSessionMaxRecvWindowSize); | 116 kSessionMaxRecvWindowSize); |
| 108 } | 117 } |
| 109 | 118 |
| 110 epoll_server_->set_timeout_in_us(50 * 1000); | 119 epoll_server_->set_timeout_in_us(50 * 1000); |
| 111 | 120 |
| 112 if (!CreateUDPSocket()) { | 121 if (!CreateUDPSocketAndBind()) { |
| 113 return false; | 122 return false; |
| 114 } | 123 } |
| 115 | 124 |
| 116 epoll_server_->RegisterFD(GetLatestFD(), this, kEpollFlags); | 125 epoll_server_->RegisterFD(GetLatestFD(), this, kEpollFlags); |
| 117 initialized_ = true; | 126 initialized_ = true; |
| 118 return true; | 127 return true; |
| 119 } | 128 } |
| 120 | 129 |
| 121 QuicClient::QuicDataToResend::QuicDataToResend(BalsaHeaders* headers, | 130 QuicClient::QuicDataToResend::QuicDataToResend(BalsaHeaders* headers, |
| 122 StringPiece body, | 131 StringPiece body, |
| 123 bool fin) | 132 bool fin) |
| 124 : headers_(headers), body_(body), fin_(fin) {} | 133 : headers_(headers), body_(body), fin_(fin) {} |
| 125 | 134 |
| 126 QuicClient::QuicDataToResend::~QuicDataToResend() { | 135 QuicClient::QuicDataToResend::~QuicDataToResend() { |
| 127 if (headers_) { | 136 if (headers_) { |
| 128 delete headers_; | 137 delete headers_; |
| 129 } | 138 } |
| 130 } | 139 } |
| 131 | 140 |
| 132 bool QuicClient::CreateUDPSocket() { | 141 bool QuicClient::CreateUDPSocketAndBind() { |
| 133 int address_family = server_address_.GetSockAddrFamily(); | 142 int fd = |
| 134 int fd = socket(address_family, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP); | 143 QuicSocketUtils::CreateUDPSocket(server_address_, &overflow_supported_); |
| 135 if (fd < 0) { | 144 if (fd < 0) { |
| 136 LOG(ERROR) << "CreateSocket() failed: " << strerror(errno); | |
| 137 return false; | |
| 138 } | |
| 139 | |
| 140 int get_overflow = 1; | |
| 141 int rc = setsockopt(fd, SOL_SOCKET, SO_RXQ_OVFL, &get_overflow, | |
| 142 sizeof(get_overflow)); | |
| 143 if (rc < 0) { | |
| 144 DLOG(WARNING) << "Socket overflow detection not supported"; | |
| 145 } else { | |
| 146 overflow_supported_ = true; | |
| 147 } | |
| 148 | |
| 149 if (!QuicSocketUtils::SetReceiveBufferSize(fd, kDefaultSocketReceiveBuffer)) { | |
| 150 return false; | |
| 151 } | |
| 152 | |
| 153 if (!QuicSocketUtils::SetSendBufferSize(fd, kDefaultSocketReceiveBuffer)) { | |
| 154 return false; | |
| 155 } | |
| 156 | |
| 157 rc = QuicSocketUtils::SetGetAddressInfo(fd, address_family); | |
| 158 if (rc < 0) { | |
| 159 LOG(ERROR) << "IP detection not supported" << strerror(errno); | |
| 160 return false; | 145 return false; |
| 161 } | 146 } |
| 162 | 147 |
| 163 IPEndPoint client_address; | 148 IPEndPoint client_address; |
| 164 if (bind_to_address_.size() != 0) { | 149 if (bind_to_address_.size() != 0) { |
| 165 client_address = IPEndPoint(bind_to_address_, local_port_); | 150 client_address = IPEndPoint(bind_to_address_, local_port_); |
| 166 } else if (address_family == AF_INET) { | 151 } else if (server_address_.GetSockAddrFamily() == AF_INET) { |
| 167 client_address = IPEndPoint(IPAddress(0, 0, 0, 0), local_port_); | 152 client_address = IPEndPoint(IPAddress(0, 0, 0, 0), local_port_); |
| 168 } else { | 153 } else { |
| 169 IPAddress any6; | 154 IPAddress any6; |
| 170 CHECK(any6.AssignFromIPLiteral("::")); | 155 CHECK(any6.AssignFromIPLiteral("::")); |
| 171 client_address = IPEndPoint(any6, local_port_); | 156 client_address = IPEndPoint(any6, local_port_); |
| 172 } | 157 } |
| 173 | 158 |
| 174 sockaddr_storage raw_addr; | 159 sockaddr_storage raw_addr; |
| 175 socklen_t raw_addr_len = sizeof(raw_addr); | 160 socklen_t raw_addr_len = sizeof(raw_addr); |
| 176 CHECK(client_address.ToSockAddr(reinterpret_cast<sockaddr*>(&raw_addr), | 161 CHECK(client_address.ToSockAddr(reinterpret_cast<sockaddr*>(&raw_addr), |
| 177 &raw_addr_len)); | 162 &raw_addr_len)); |
| 178 rc = bind(fd, reinterpret_cast<const sockaddr*>(&raw_addr), sizeof(raw_addr)); | 163 int rc = |
| 164 bind(fd, reinterpret_cast<const sockaddr*>(&raw_addr), sizeof(raw_addr)); |
| 179 if (rc < 0) { | 165 if (rc < 0) { |
| 180 LOG(ERROR) << "Bind failed: " << strerror(errno); | 166 LOG(ERROR) << "Bind failed: " << strerror(errno); |
| 181 return false; | 167 return false; |
| 182 } | 168 } |
| 183 | 169 |
| 184 SockaddrStorage storage; | 170 SockaddrStorage storage; |
| 185 if (getsockname(fd, storage.addr, &storage.addr_len) != 0 || | 171 if (getsockname(fd, storage.addr, &storage.addr_len) != 0 || |
| 186 !client_address.FromSockAddr(storage.addr, storage.addr_len)) { | 172 !client_address.FromSockAddr(storage.addr, storage.addr_len)) { |
| 187 LOG(ERROR) << "Unable to get self address. Error: " << strerror(errno); | 173 LOG(ERROR) << "Unable to get self address. Error: " << strerror(errno); |
| 188 } | 174 } |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 383 } | 369 } |
| 384 | 370 |
| 385 bool QuicClient::MigrateSocket(const IPAddress& new_host) { | 371 bool QuicClient::MigrateSocket(const IPAddress& new_host) { |
| 386 if (!connected()) { | 372 if (!connected()) { |
| 387 return false; | 373 return false; |
| 388 } | 374 } |
| 389 | 375 |
| 390 CleanUpUDPSocket(GetLatestFD()); | 376 CleanUpUDPSocket(GetLatestFD()); |
| 391 | 377 |
| 392 bind_to_address_ = new_host; | 378 bind_to_address_ = new_host; |
| 393 if (!CreateUDPSocket()) { | 379 if (!CreateUDPSocketAndBind()) { |
| 394 return false; | 380 return false; |
| 395 } | 381 } |
| 396 | 382 |
| 397 epoll_server_->RegisterFD(GetLatestFD(), this, kEpollFlags); | 383 epoll_server_->RegisterFD(GetLatestFD(), this, kEpollFlags); |
| 398 session()->connection()->SetSelfAddress(GetLatestClientAddress()); | 384 session()->connection()->SetSelfAddress(GetLatestClientAddress()); |
| 399 | 385 |
| 400 QuicPacketWriter* writer = CreateQuicPacketWriter(); | 386 QuicPacketWriter* writer = CreateQuicPacketWriter(); |
| 401 set_writer(writer); | 387 set_writer(writer); |
| 402 session()->connection()->SetQuicPacketWriter(writer, false); | 388 session()->connection()->SetQuicPacketWriter(writer, false); |
| 403 | 389 |
| 404 return true; | 390 return true; |
| 405 } | 391 } |
| 406 | 392 |
| 407 void QuicClient::OnEvent(int fd, EpollEvent* event) { | 393 void QuicClient::OnEvent(int fd, EpollEvent* event) { |
| 408 DCHECK_EQ(fd, GetLatestFD()); | 394 DCHECK_EQ(fd, GetLatestFD()); |
| 409 | 395 |
| 410 if (event->in_events & EPOLLIN) { | 396 if (event->in_events & EPOLLIN) { |
| 411 while (connected()) { | 397 bool more_to_read = true; |
| 412 if ( | 398 while (connected() && more_to_read) { |
| 413 #if MMSG_MORE | 399 if (use_recvmmsg_) { |
| 414 !ReadAndProcessPackets() | 400 more_to_read = packet_reader_->ReadAndDispatchPackets( |
| 415 #else | 401 GetLatestFD(), QuicClient::GetLatestClientAddress().port(), this, |
| 416 !ReadAndProcessPacket() | 402 overflow_supported_ ? &packets_dropped_ : nullptr); |
| 417 #endif | 403 } else { |
| 418 ) { | 404 more_to_read = QuicPacketReader::ReadAndDispatchSinglePacket( |
| 419 break; | 405 GetLatestFD(), QuicClient::GetLatestClientAddress().port(), this, |
| 406 overflow_supported_ ? &packets_dropped_ : nullptr); |
| 420 } | 407 } |
| 421 } | 408 } |
| 422 } | 409 } |
| 423 if (connected() && (event->in_events & EPOLLOUT)) { | 410 if (connected() && (event->in_events & EPOLLOUT)) { |
| 424 writer()->SetWritable(); | 411 writer()->SetWritable(); |
| 425 session()->connection()->OnCanWrite(); | 412 session()->connection()->OnCanWrite(); |
| 426 } | 413 } |
| 427 if (event->in_events & EPOLLERR) { | 414 if (event->in_events & EPOLLERR) { |
| 428 DVLOG(1) << "Epollerr"; | 415 DVLOG(1) << "Epollerr"; |
| 429 } | 416 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 485 | 472 |
| 486 const string& QuicClient::latest_response_trailers() const { | 473 const string& QuicClient::latest_response_trailers() const { |
| 487 QUIC_BUG_IF(!store_response_) << "Response not stored!"; | 474 QUIC_BUG_IF(!store_response_) << "Response not stored!"; |
| 488 return latest_response_trailers_; | 475 return latest_response_trailers_; |
| 489 } | 476 } |
| 490 | 477 |
| 491 QuicPacketWriter* QuicClient::CreateQuicPacketWriter() { | 478 QuicPacketWriter* QuicClient::CreateQuicPacketWriter() { |
| 492 return new QuicDefaultPacketWriter(GetLatestFD()); | 479 return new QuicDefaultPacketWriter(GetLatestFD()); |
| 493 } | 480 } |
| 494 | 481 |
| 495 QuicPacketReader* QuicClient::CreateQuicPacketReader() { | |
| 496 // TODO(rtenneti): Add support for QuicPacketReader. | |
| 497 // return new QuicPacketReader(); | |
| 498 return nullptr; | |
| 499 } | |
| 500 | |
| 501 int QuicClient::ReadPacket(char* buffer, | |
| 502 int buffer_len, | |
| 503 IPEndPoint* server_address, | |
| 504 IPAddress* client_ip) { | |
| 505 return QuicSocketUtils::ReadPacket( | |
| 506 GetLatestFD(), buffer, buffer_len, | |
| 507 overflow_supported_ ? &packets_dropped_ : nullptr, client_ip, | |
| 508 server_address); | |
| 509 } | |
| 510 | |
| 511 bool QuicClient::ReadAndProcessPacket() { | |
| 512 // Allocate some extra space so we can send an error if the server goes over | |
| 513 // the limit. | |
| 514 char buf[2 * kMaxPacketSize]; | |
| 515 | |
| 516 IPEndPoint server_address; | |
| 517 IPAddress client_ip; | |
| 518 | |
| 519 int bytes_read = ReadPacket(buf, arraysize(buf), &server_address, &client_ip); | |
| 520 | |
| 521 if (bytes_read < 0) { | |
| 522 return false; | |
| 523 } | |
| 524 | |
| 525 QuicEncryptedPacket packet(buf, bytes_read, false); | |
| 526 | |
| 527 IPEndPoint client_address(client_ip, | |
| 528 QuicClient::GetLatestClientAddress().port()); | |
| 529 | |
| 530 session()->ProcessUdpPacket(client_address, server_address, packet); | |
| 531 return true; | |
| 532 } | |
| 533 | |
| 534 /* | |
| 535 bool QuicClient::ReadAndProcessPackets() { | |
| 536 return packet_reader_->ReadAndDispatchPackets( | |
| 537 GetLatestFD(), QuicClient::GetLatestClientAddress().port(), this, | |
| 538 overflow_supported_ ? &packets_dropped_ : nullptr); | |
| 539 } | |
| 540 */ | |
| 541 | |
| 542 const IPEndPoint QuicClient::GetLatestClientAddress() const { | 482 const IPEndPoint QuicClient::GetLatestClientAddress() const { |
| 543 if (fd_address_map_.empty()) { | 483 if (fd_address_map_.empty()) { |
| 544 return IPEndPoint(); | 484 return IPEndPoint(); |
| 545 } | 485 } |
| 546 | 486 |
| 547 return fd_address_map_.back().second; | 487 return fd_address_map_.back().second; |
| 548 } | 488 } |
| 549 | 489 |
| 550 int QuicClient::GetLatestFD() const { | 490 int QuicClient::GetLatestFD() const { |
| 551 if (fd_address_map_.empty()) { | 491 if (fd_address_map_.empty()) { |
| 552 return -1; | 492 return -1; |
| 553 } | 493 } |
| 554 | 494 |
| 555 return fd_address_map_.back().first; | 495 return fd_address_map_.back().first; |
| 556 } | 496 } |
| 557 | 497 |
| 558 void QuicClient::ProcessPacket(const IPEndPoint& self_address, | 498 void QuicClient::ProcessPacket(const IPEndPoint& self_address, |
| 559 const IPEndPoint& peer_address, | 499 const IPEndPoint& peer_address, |
| 560 const QuicEncryptedPacket& packet) { | 500 const QuicEncryptedPacket& packet) { |
| 561 session()->connection()->ProcessUdpPacket(self_address, peer_address, packet); | 501 session()->connection()->ProcessUdpPacket(self_address, peer_address, packet); |
| 562 } | 502 } |
| 563 | 503 |
| 564 } // namespace net | 504 } // namespace net |
| OLD | NEW |