summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/quic/quic_stream_factory.cc39
-rw-r--r--net/quic/quic_stream_factory.h12
-rw-r--r--net/quic/quic_stream_factory_test.cc15
-rw-r--r--net/udp/udp_socket_libevent.cc4
-rw-r--r--net/udp/udp_socket_win.cc4
-rw-r--r--tools/metrics/histograms/histograms.xml12
6 files changed, 65 insertions, 21 deletions
diff --git a/net/quic/quic_stream_factory.cc b/net/quic/quic_stream_factory.cc
index e7cd7d8..0c5125b 100644
--- a/net/quic/quic_stream_factory.cc
+++ b/net/quic/quic_stream_factory.cc
@@ -101,7 +101,8 @@ QuicStreamFactory::Job::Job(
host_port_proxy_pair_(host_port_proxy_pair),
is_https_(is_https),
cert_verifier_(cert_verifier),
- net_log_(net_log) {
+ net_log_(net_log),
+ session_(NULL) {
}
QuicStreamFactory::Job::~Job() {
@@ -220,10 +221,16 @@ scoped_ptr<QuicHttpStream> QuicStreamRequest::ReleaseStream() {
int QuicStreamFactory::Job::DoConnect() {
io_state_ = STATE_CONNECT_COMPLETE;
- session_ = factory_->CreateSession(host_port_proxy_pair_, is_https_,
- cert_verifier_, address_list_, net_log_);
+ int rv = factory_->CreateSession(host_port_proxy_pair_, is_https_,
+ cert_verifier_, address_list_, net_log_, &session_);
+ if (rv != OK) {
+ DCHECK(rv != ERR_IO_PENDING);
+ DCHECK(!session_);
+ return rv;
+ }
+
session_->StartReading();
- int rv = session_->CryptoConnect(
+ rv = session_->CryptoConnect(
factory_->require_confirmation() || is_https_,
base::Bind(&QuicStreamFactory::Job::OnIOComplete,
base::Unretained(this)));
@@ -440,19 +447,22 @@ bool QuicStreamFactory::HasActiveSession(
return ContainsKey(active_sessions_, host_port_proxy_pair);
}
-QuicClientSession* QuicStreamFactory::CreateSession(
+int QuicStreamFactory::CreateSession(
const HostPortProxyPair& host_port_proxy_pair,
bool is_https,
CertVerifier* cert_verifier,
const AddressList& address_list,
- const BoundNetLog& net_log) {
+ const BoundNetLog& net_log,
+ QuicClientSession** session) {
QuicGuid guid = random_generator_->RandUint64();
IPEndPoint addr = *address_list.begin();
scoped_ptr<DatagramClientSocket> socket(
client_socket_factory_->CreateDatagramClientSocket(
- DatagramSocket::DEFAULT_BIND, base::Bind(&base::RandInt),
+ DatagramSocket::RANDOM_BIND, base::Bind(&base::RandInt),
net_log.net_log(), net_log.source()));
- socket->Connect(addr);
+ int rv = socket->Connect(addr);
+ if (rv != OK)
+ return rv;
// We should adaptively set this buffer size, but for now, we'll use a size
// that is more than large enough for a full receive window, and yet
@@ -484,17 +494,16 @@ QuicClientSession* QuicStreamFactory::CreateSession(
GetOrCreateCryptoConfig(host_port_proxy_pair);
DCHECK(crypto_config);
- QuicClientSession* session =
- new QuicClientSession(connection, socket.Pass(), writer.Pass(), this,
- quic_crypto_client_stream_factory_,
- host_port_proxy_pair.first.host(), config_,
- crypto_config, net_log.net_log());
- all_sessions_.insert(session); // owning pointer
+ *session = new QuicClientSession(
+ connection, socket.Pass(), writer.Pass(), this,
+ quic_crypto_client_stream_factory_, host_port_proxy_pair.first.host(),
+ config_, crypto_config, net_log.net_log());
+ all_sessions_.insert(*session); // owning pointer
if (is_https) {
crypto_config->SetProofVerifier(
new ProofVerifierChromium(cert_verifier, net_log));
}
- return session;
+ return OK;
}
bool QuicStreamFactory::HasActiveJob(
diff --git a/net/quic/quic_stream_factory.h b/net/quic/quic_stream_factory.h
index 95a3d36..ae0add0 100644
--- a/net/quic/quic_stream_factory.h
+++ b/net/quic/quic_stream_factory.h
@@ -167,12 +167,12 @@ class NET_EXPORT_PRIVATE QuicStreamFactory
void OnJobComplete(Job* job, int rv);
bool HasActiveSession(const HostPortProxyPair& host_port_proxy_pair);
bool HasActiveJob(const HostPortProxyPair& host_port_proxy_pair);
- QuicClientSession* CreateSession(
- const HostPortProxyPair& host_port_proxy_pair,
- bool is_https,
- CertVerifier* cert_verifier,
- const AddressList& address_list,
- const BoundNetLog& net_log);
+ int CreateSession(const HostPortProxyPair& host_port_proxy_pair,
+ bool is_https,
+ CertVerifier* cert_verifier,
+ const AddressList& address_list,
+ const BoundNetLog& net_log,
+ QuicClientSession** session);
void ActivateSession(const HostPortProxyPair& host_port_proxy_pair,
QuicClientSession* session);
diff --git a/net/quic/quic_stream_factory_test.cc b/net/quic/quic_stream_factory_test.cc
index 1c1f8e1..03cc6f7 100644
--- a/net/quic/quic_stream_factory_test.cc
+++ b/net/quic/quic_stream_factory_test.cc
@@ -208,6 +208,21 @@ TEST_F(QuicStreamFactoryTest, Create) {
EXPECT_TRUE(socket_data.at_write_eof());
}
+TEST_F(QuicStreamFactoryTest, FailedCreate) {
+ MockConnect connect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
+ DeterministicSocketData socket_data(NULL, 0, NULL, 0);
+ socket_data.set_connect_data(connect);
+ socket_factory_.AddSocketDataProvider(&socket_data);
+ socket_data.StopAfter(1);
+
+ QuicStreamRequest request(&factory_);
+ EXPECT_EQ(ERR_IO_PENDING, request.Request(host_port_proxy_pair_, is_https_,
+ cert_verifier_.get(), net_log_,
+ callback_.callback()));
+
+ EXPECT_EQ(ERR_ADDRESS_IN_USE, callback_.WaitForResult());
+}
+
TEST_F(QuicStreamFactoryTest, Goaway) {
MockRead reads[] = {
MockRead(ASYNC, OK, 0) // EOF
diff --git a/net/udp/udp_socket_libevent.cc b/net/udp/udp_socket_libevent.cc
index dc40831..457ce88 100644
--- a/net/udp/udp_socket_libevent.cc
+++ b/net/udp/udp_socket_libevent.cc
@@ -15,6 +15,7 @@
#include "base/callback.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
+#include "base/metrics/sparse_histogram.h"
#include "base/metrics/stats_counters.h"
#include "base/posix/eintr_wrapper.h"
#include "base/rand_util.h"
@@ -270,6 +271,7 @@ int UDPSocketLibevent::InternalConnect(const IPEndPoint& address) {
// else connect() does the DatagramSocket::DEFAULT_BIND
if (rv < 0) {
+ UMA_HISTOGRAM_SPARSE_SLOWLY("Net.UdpSocketRandomBindErrorCode", rv);
Close();
return rv;
}
@@ -606,6 +608,8 @@ int UDPSocketLibevent::DoBind(const IPEndPoint& address) {
if (!address.ToSockAddr(storage.addr, &storage.addr_len))
return ERR_ADDRESS_INVALID;
int rv = bind(socket_, storage.addr, storage.addr_len);
+ if (rv < 0)
+ UMA_HISTOGRAM_SPARSE_SLOWLY("Net.UdpSocketBindErrorFromPosix", rv);
return rv < 0 ? MapSystemError(errno) : rv;
}
diff --git a/net/udp/udp_socket_win.cc b/net/udp/udp_socket_win.cc
index 5ab63a5..7b7a528 100644
--- a/net/udp/udp_socket_win.cc
+++ b/net/udp/udp_socket_win.cc
@@ -10,6 +10,7 @@
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram.h"
+#include "base/metrics/sparse_histogram.h"
#include "base/metrics/stats_counters.h"
#include "base/rand_util.h"
#include "net/base/io_buffer.h"
@@ -338,6 +339,7 @@ int UDPSocketWin::InternalConnect(const IPEndPoint& address) {
// else connect() does the DatagramSocket::DEFAULT_BIND
if (rv < 0) {
+ UMA_HISTOGRAM_SPARSE_SLOWLY("Net.UdpSocketRandomBindErrorCode", rv);
Close();
return rv;
}
@@ -663,6 +665,8 @@ int UDPSocketWin::DoBind(const IPEndPoint& address) {
if (!address.ToSockAddr(storage.addr, &storage.addr_len))
return ERR_ADDRESS_INVALID;
int rv = bind(socket_, storage.addr, storage.addr_len);
+ if (rv < 0)
+ UMA_HISTOGRAM_SPARSE_SLOWLY("Net.UdpSocketBindErrorFromWinOS", rv);
return rv < 0 ? MapSystemError(WSAGetLastError()) : rv;
}
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 85463be..5a049ba 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -9965,6 +9965,18 @@ other types of suffix sets.
</summary>
</histogram>
+<histogram name="Net.UdpSocketBindErrorFromPosix" units="PosixError">
+ <summary>Posix error code from call to bind() UDP socket.</summary>
+</histogram>
+
+<histogram name="Net.UdpSocketBindErrorFromWinOS" units="WinError">
+ <summary>Windows error code from call to bind() UDP socket.</summary>
+</histogram>
+
+<histogram name="Net.UdpSocketRandomBindErrorCode" enum="NetErrorCodes">
+ <summary>Chromium error code from call to RandomBind() UDP socket.</summary>
+</histogram>
+
<histogram name="Net.UDPSocketWinClose" units="milliseconds">
<summary>The time spent in closesocket call in UDPSocketWin::Close.</summary>
</histogram>