// Be conservative, and just use double a typical TCP ICWND for HTTP.
const int32 kServerInecureInitialCongestionWindow = 20;
+const char kDummyHostname[] = "quic.global.props";
+const uint16 kDummyPort = 0;
+
void HistogramCreateSessionFailure(enum CreateSessionFailure error) {
UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.CreationError", error,
CREATION_ERROR_MAX);
return config;
}
+class DefaultPacketWriterFactory : public QuicConnection::PacketWriterFactory {
+ public:
+ explicit DefaultPacketWriterFactory(DatagramClientSocket* socket)
+ : socket_(socket) {}
+ virtual ~DefaultPacketWriterFactory() {}
+
+ virtual QuicPacketWriter* Create(QuicConnection* connection) const OVERRIDE;
+
+ private:
+ DatagramClientSocket* socket_;
+};
+
+QuicPacketWriter* DefaultPacketWriterFactory::Create(
+ QuicConnection* connection) const {
+ scoped_ptr<QuicDefaultPacketWriter> writer(
+ new QuicDefaultPacketWriter(socket_));
+ writer->SetConnection(connection);
+ return writer.release();
+}
+
} // namespace
QuicStreamFactory::IpAliasKey::IpAliasKey() {}
CompletionCallback callback_;
AddressList address_list_;
base::TimeTicks disk_cache_load_start_time_;
+ base::TimeTicks dns_resolution_start_time_;
base::WeakPtrFactory<Job> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(Job);
};
}
io_state_ = STATE_RESOLVE_HOST_COMPLETE;
+ dns_resolution_start_time_ = base::TimeTicks::Now();
return host_resolver_.Resolve(
HostResolver::RequestInfo(server_id_.host_port_pair()),
DEFAULT_PRIORITY,
}
int QuicStreamFactory::Job::DoResolveHostComplete(int rv) {
+ UMA_HISTOGRAM_TIMES("Net.QuicSession.HostResolutionTime",
+ base::TimeTicks::Now() - dns_resolution_start_time_);
if (rv != OK)
return rv;
bool enable_port_selection,
bool enable_time_based_loss_detection,
bool always_require_handshake_confirmation,
+ bool disable_connection_pooling,
const QuicTagVector& connection_options)
: require_confirmation_(true),
host_resolver_(host_resolver),
enable_port_selection_(enable_port_selection),
always_require_handshake_confirmation_(
always_require_handshake_confirmation),
+ disable_connection_pooling_(disable_connection_pooling),
port_seed_(random_generator_->RandUint64()),
+ check_persisted_supports_quic_(true),
weak_factory_(this) {
DCHECK(transport_security_state_);
crypto_config_.SetDefaults();
STLDeleteValues(&active_jobs_);
}
+void QuicStreamFactory::set_require_confirmation(bool require_confirmation) {
+ require_confirmation_ = require_confirmation;
+ if (http_server_properties_ && (!(local_address_ == IPEndPoint()))) {
+ // TODO(rtenneti): Delete host_port_pair and persist data in globals.
+ HostPortPair host_port_pair(kDummyHostname, kDummyPort);
+ http_server_properties_->SetSupportsQuic(
+ host_port_pair, !require_confirmation,
+ local_address_.ToStringWithoutPort());
+ }
+}
+
int QuicStreamFactory::Create(const HostPortPair& host_port_pair,
bool is_https,
PrivacyMode privacy_mode,
const QuicServerId& server_id,
const AddressList& address_list) {
DCHECK(!HasActiveSession(server_id));
+ if (disable_connection_pooling_) {
+ return false;
+ }
for (size_t i = 0; i < address_list.size(); ++i) {
const IPEndPoint& address = address_list[i];
const IpAliasKey ip_alias_key(address, server_id.is_https());
void QuicStreamFactory::OnJobComplete(Job* job, int rv) {
if (rv == OK) {
if (!always_require_handshake_confirmation_)
- require_confirmation_ = false;
+ set_require_confirmation(false);
// Create all the streams, but do not notify them yet.
for (RequestSet::iterator it = job_requests_map_[job].begin();
void QuicStreamFactory::OnIPAddressChanged() {
CloseAllSessions(ERR_NETWORK_CHANGED);
- require_confirmation_ = true;
+ set_require_confirmation(true);
}
void QuicStreamFactory::OnCertAdded(const X509Certificate* cert) {
return rv;
}
- scoped_ptr<QuicDefaultPacketWriter> writer(
- new QuicDefaultPacketWriter(socket.get()));
+ socket->GetLocalAddress(&local_address_);
+ if (check_persisted_supports_quic_ && http_server_properties_) {
+ check_persisted_supports_quic_ = false;
+ // TODO(rtenneti): Delete host_port_pair and persist data in globals.
+ HostPortPair host_port_pair(kDummyHostname, kDummyPort);
+ SupportsQuic supports_quic(true, local_address_.ToStringWithoutPort());
+ if (http_server_properties_->GetSupportsQuic(
+ host_port_pair).Equals(supports_quic)) {
+ require_confirmation_ = false;
+ }
+ }
+
+ DefaultPacketWriterFactory packet_writer_factory(socket.get());
if (!helper_.get()) {
helper_.reset(new QuicConnectionHelper(
QuicConnection* connection = new QuicConnection(connection_id,
addr,
helper_.get(),
- writer.get(),
- false /* owns_writer */,
+ packet_writer_factory,
+ true /* owns_writer */,
false /* is_server */,
supported_versions_);
- writer->SetConnection(connection);
connection->set_max_packet_length(max_packet_length_);
InitializeCachedStateInCryptoConfig(server_id, server_info);
}
*session = new QuicClientSession(
- connection, socket.Pass(), writer.Pass(), this,
- quic_crypto_client_stream_factory_, transport_security_state_,
- server_info.Pass(), server_id, config, &crypto_config_,
+ connection, socket.Pass(), this, transport_security_state_,
+ server_info.Pass(), config,
base::MessageLoop::current()->message_loop_proxy().get(),
net_log.net_log());
all_sessions_[*session] = server_id; // owning pointer
- (*session)->InitializeSession();
+ (*session)->InitializeSession(server_id, &crypto_config_,
+ quic_crypto_client_stream_factory_);
bool closed_during_initialize =
!ContainsKey(all_sessions_, *session) ||
!(*session)->connection()->connected();