1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/tools/quic/quic_client.h" 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <errno.h> 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <netinet/in.h> 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <string.h> 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <sys/epoll.h> 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <sys/socket.h> 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <unistd.h> 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/logging.h" 15c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "net/quic/congestion_control/tcp_receiver.h" 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/quic/crypto/quic_random.h" 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/quic/quic_connection.h" 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/quic/quic_data_reader.h" 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/quic/quic_protocol.h" 20e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "net/quic/quic_server_id.h" 214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "net/tools/balsa/balsa_headers.h" 226d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "net/tools/epoll_server/epoll_server.h" 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/tools/quic/quic_epoll_connection_helper.h" 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/tools/quic/quic_socket_utils.h" 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/tools/quic/quic_spdy_client_stream.h" 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#ifndef SO_RXQ_OVFL 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define SO_RXQ_OVFL 40 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace net { 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace tools { 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const int kEpollFlags = EPOLLIN | EPOLLOUT | EPOLLET; 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)QuicClient::QuicClient(IPEndPoint server_address, 37e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const QuicServerId& server_id, 381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const QuicVersionVector& supported_versions, 396d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) bool print_response, 406d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) EpollServer* epoll_server) 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : server_address_(server_address), 42e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch server_id_(server_id), 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) local_port_(0), 446d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) epoll_server_(epoll_server), 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fd_(-1), 461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) helper_(CreateQuicConnectionHelper()), 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) initialized_(false), 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) packets_dropped_(0), 49558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch overflow_supported_(false), 501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) supported_versions_(supported_versions), 51f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) print_response_(print_response) { 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) config_.SetDefaults(); 53b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 54b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 55b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)QuicClient::QuicClient(IPEndPoint server_address, 56e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const QuicServerId& server_id, 57e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const QuicVersionVector& supported_versions, 58f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool print_response, 596d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) const QuicConfig& config, 606d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) EpollServer* epoll_server) 61b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) : server_address_(server_address), 62e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch server_id_(server_id), 63b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) config_(config), 64b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) local_port_(0), 656d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) epoll_server_(epoll_server), 66b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) fd_(-1), 671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) helper_(CreateQuicConnectionHelper()), 68b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) initialized_(false), 69b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) packets_dropped_(0), 70558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch overflow_supported_(false), 711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) supported_versions_(supported_versions), 72f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) print_response_(print_response) { 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)QuicClient::~QuicClient() { 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (connected()) { 7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) session()->connection()->SendConnectionClosePacket( 78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) QUIC_PEER_GOING_AWAY, ""); 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 806d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (fd_ > 0) { 816d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) epoll_server_->UnregisterFD(fd_); 826d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) } 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool QuicClient::Initialize() { 8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!initialized_); 8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 886d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) epoll_server_->set_timeout_in_us(50 * 1000); 89b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) crypto_config_.SetDefaults(); 90b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!CreateUDPSocket()) { 92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return false; 93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 956d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) epoll_server_->RegisterFD(fd_, this, kEpollFlags); 96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) initialized_ = true; 97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return true; 98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 10003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)QuicClient::DummyPacketWriterFactory::DummyPacketWriterFactory( 10103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) QuicPacketWriter* writer) 10203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) : writer_(writer) {} 10303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 10403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)QuicClient::DummyPacketWriterFactory::~DummyPacketWriterFactory() {} 10503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 10603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)QuicPacketWriter* QuicClient::DummyPacketWriterFactory::Create( 10703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) QuicConnection* /*connection*/) const { 10803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return writer_; 10903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 11003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 11103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool QuicClient::CreateUDPSocket() { 11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int address_family = server_address_.GetSockAddrFamily(); 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fd_ = socket(address_family, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP); 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (fd_ < 0) { 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "CreateSocket() failed: " << strerror(errno); 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int get_overflow = 1; 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int rc = setsockopt(fd_, SOL_SOCKET, SO_RXQ_OVFL, &get_overflow, 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) sizeof(get_overflow)); 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (rc < 0) { 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DLOG(WARNING) << "Socket overflow detection not supported"; 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) overflow_supported_ = true; 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!QuicSocketUtils::SetReceiveBufferSize(fd_, 1300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch TcpReceiver::kReceiveWindowTCP)) { 131c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return false; 132c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 133c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 1340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!QuicSocketUtils::SetSendBufferSize(fd_, 1350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch TcpReceiver::kReceiveWindowTCP)) { 136c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return false; 137c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 138c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch rc = QuicSocketUtils::SetGetAddressInfo(fd_, address_family); 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (rc < 0) { 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "IP detection not supported" << strerror(errno); 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (bind_to_address_.size() != 0) { 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client_address_ = IPEndPoint(bind_to_address_, local_port_); 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (address_family == AF_INET) { 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPAddressNumber any4; 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CHECK(net::ParseIPLiteralToNumber("0.0.0.0", &any4)); 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client_address_ = IPEndPoint(any4, local_port_); 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPAddressNumber any6; 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CHECK(net::ParseIPLiteralToNumber("::", &any6)); 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client_address_ = IPEndPoint(any6, local_port_); 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) sockaddr_storage raw_addr; 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) socklen_t raw_addr_len = sizeof(raw_addr); 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CHECK(client_address_.ToSockAddr(reinterpret_cast<sockaddr*>(&raw_addr), 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &raw_addr_len)); 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rc = bind(fd_, 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) reinterpret_cast<const sockaddr*>(&raw_addr), 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) sizeof(raw_addr)); 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (rc < 0) { 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "Bind failed: " << strerror(errno); 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SockaddrStorage storage; 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (getsockname(fd_, storage.addr, &storage.addr_len) != 0 || 171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) !client_address_.FromSockAddr(storage.addr, storage.addr_len)) { 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "Unable to get self address. Error: " << strerror(errno); 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool QuicClient::Connect() { 179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!StartConnect()) { 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (EncryptionBeingEstablished()) { 183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WaitForEvents(); 184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return session_->connection()->connected(); 186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool QuicClient::StartConnect() { 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(initialized_); 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!connected()); 191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) QuicPacketWriter* writer = CreateQuicPacketWriter(); 1931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 19403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DummyPacketWriterFactory factory(writer); 19503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session_.reset(new QuicClientSession( 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) config_, 1985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new QuicConnection(GenerateConnectionId(), 1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) server_address_, 2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) helper_.get(), 20103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) factory, 20203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /* owns_writer= */ false, 20303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /* is_server= */ false, 2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) supported_versions_))); 20503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Reset |writer_| after |session_| so that the old writer outlives the old 2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // session. 2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (writer_.get() != writer) { 2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) writer_.reset(writer); 2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 211116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch session_->InitializeSession(server_id_, &crypto_config_); 212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return session_->CryptoConnect(); 213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool QuicClient::EncryptionBeingEstablished() { 216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return !session_->IsEncryptionEstablished() && 217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session_->connection()->connected(); 218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void QuicClient::Disconnect() { 221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(initialized_); 222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (connected()) { 224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) session()->connection()->SendConnectionClose(QUIC_PEER_GOING_AWAY); 225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 2266d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) epoll_server_->UnregisterFD(fd_); 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) close(fd_); 228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fd_ = -1; 22990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) initialized_ = false; 230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void QuicClient::SendRequestsAndWaitForResponse( 23346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const base::CommandLine::StringVector& args) { 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (size_t i = 0; i < args.size(); ++i) { 235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) BalsaHeaders headers; 236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) headers.SetRequestFirstlineFromStringPieces("GET", args[i], "HTTP/1.1"); 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QuicSpdyClientStream* stream = CreateReliableClientStream(); 238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(stream != NULL); 2394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) stream->SendRequest(headers, "", true); 2404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) stream->set_visitor(this); 241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 243f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) while (WaitForEvents()) {} 244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)QuicSpdyClientStream* QuicClient::CreateReliableClientStream() { 247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!connected()) { 248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return NULL; 249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return session_->CreateOutgoingDataStream(); 252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void QuicClient::WaitForStreamToClose(QuicStreamId id) { 255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(connected()); 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 257cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) while (connected() && !session_->IsClosedStream(id)) { 2586d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) epoll_server_->WaitForEventsAndExecuteCallbacks(); 259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void QuicClient::WaitForCryptoHandshakeConfirmed() { 2637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(connected()); 2647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) while (connected() && !session_->IsCryptoHandshakeConfirmed()) { 2666d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) epoll_server_->WaitForEventsAndExecuteCallbacks(); 2677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 2687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 2697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool QuicClient::WaitForEvents() { 271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(connected()); 272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2736d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) epoll_server_->WaitForEventsAndExecuteCallbacks(); 274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return session_->num_active_requests() != 0; 275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void QuicClient::OnEvent(int fd, EpollEvent* event) { 278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK_EQ(fd, fd_); 279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (event->in_events & EPOLLIN) { 281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (connected() && ReadAndProcessPacket()) { 282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (connected() && (event->in_events & EPOLLOUT)) { 2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) writer_->SetWritable(); 286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session_->connection()->OnCanWrite(); 287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (event->in_events & EPOLLERR) { 2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DVLOG(1) << "Epollerr"; 290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void QuicClient::OnClose(QuicDataStream* stream) { 2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QuicSpdyClientStream* client_stream = 2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static_cast<QuicSpdyClientStream*>(stream); 2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (response_listener_.get() != NULL) { 2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) response_listener_->OnCompleteResponse( 2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) stream->id(), client_stream->headers(), client_stream->data()); 2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!print_response_) { 3024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 3034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 3044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const BalsaHeaders& headers = client_stream->headers(); 3064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) printf("%s\n", headers.first_line().as_string().c_str()); 3074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (BalsaHeaders::const_header_lines_iterator i = 3084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) headers.header_lines_begin(); 3094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) i != headers.header_lines_end(); ++i) { 3104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) printf("%s: %s\n", i->first.as_string().c_str(), 3114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) i->second.as_string().c_str()); 3124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 3134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) printf("%s\n", client_stream->data().c_str()); 3144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 3154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool QuicClient::connected() const { 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return session_.get() && session_->connection() && 318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session_->connection()->connected(); 319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 321a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)QuicConnectionId QuicClient::GenerateConnectionId() { 3221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return QuicRandom::GetInstance()->RandUint64(); 3231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 3241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3252385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochQuicEpollConnectionHelper* QuicClient::CreateQuicConnectionHelper() { 3266d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return new QuicEpollConnectionHelper(epoll_server_); 3271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 3281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)QuicPacketWriter* QuicClient::CreateQuicPacketWriter() { 3301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return new QuicDefaultPacketWriter(fd_); 3312385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch} 3322385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 333e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochint QuicClient::ReadPacket(char* buffer, 334e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch int buffer_len, 335e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IPEndPoint* server_address, 336e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IPAddressNumber* client_ip) { 337e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return QuicSocketUtils::ReadPacket( 338e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch fd_, buffer, buffer_len, overflow_supported_ ? &packets_dropped_ : NULL, 339e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch client_ip, server_address); 340e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 341e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool QuicClient::ReadAndProcessPacket() { 343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Allocate some extra space so we can send an error if the server goes over 344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // the limit. 345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) char buf[2 * kMaxPacketSize]; 346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPEndPoint server_address; 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPAddressNumber client_ip; 349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 350e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch int bytes_read = ReadPacket(buf, arraysize(buf), &server_address, &client_ip); 351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (bytes_read < 0) { 353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicEncryptedPacket packet(buf, bytes_read, false); 357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPEndPoint client_address(client_ip, client_address_.port()); 359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session_->connection()->ProcessUdpPacket( 360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client_address, server_address, packet); 361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace tools 365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace net 366