QUIC - disable QUIC if packet loss rate is bad for a connection.

Goal - Improve quality of service (QOS) in chromium when QUIC is
enabled. For some users when QUIC is enabled, their access to QUIC
based servers doesn't work well. This could be due to either high loss
rate while using UDP or service providers blacklisting ports 80/443 for
QUIC traffic.

+ One simple approach (which would detect breakage quickly) would be
  to look at the packet loss (received) when the crypto handshake
  is confirmed. When packet loss is "really bad", say over
  50% for 5 handshakes in a row, we will disable QUIC.

+ For a connection is packet loss is higher than the packet loss
  threshold, then we mark that port as recently broken. This would
  require crypto handshake confirmation.

+ Added two parameters - number of "lossy" connections (defaults to 0)
  and packet loss threshold (defaults to 1000%) params to determine
  when to disable QUIC. These parameters will be controlled by finch
  in the next CL.

[email protected], [email protected],[email protected]

Review URL: https://codereview.chromium.org/1025573002

Cr-Commit-Position: refs/heads/master@{#322630}
diff --git a/net/quic/quic_stream_factory.h b/net/quic/quic_stream_factory.h
index c550590..48e9996a 100644
--- a/net/quic/quic_stream_factory.h
+++ b/net/quic/quic_stream_factory.h
@@ -108,6 +108,8 @@
       bool enable_connection_racing,
       bool enable_non_blocking_io,
       bool disable_disk_cache,
+      int max_number_of_lossy_connections,
+      float packet_loss_threshold,
       int socket_receive_buffer_size,
       const QuicTagVector& connection_options);
   ~QuicStreamFactory() override;
@@ -124,6 +126,15 @@
              const BoundNetLog& net_log,
              QuicStreamRequest* request);
 
+  // Returns false if |packet_loss_rate| is less than |packet_loss_threshold_|
+  // otherwise it returns true and closes the session and marks QUIC as recently
+  // broken for the port of the session. Increments
+  // |number_of_lossy_connections_| by port.
+  bool OnHandshakeConfirmed(QuicClientSession* session, float packet_loss_rate);
+
+  // Returns true if QUIC is disabled for this port.
+  bool IsQuicDisabled(uint16 port);
+
   // Called by a session when it becomes idle.
   void OnIdleSession(QuicClientSession* session);
 
@@ -327,6 +338,16 @@
   // Set if we do not want to load server config from the disk cache.
   bool disable_disk_cache_;
 
+  // Set if we want to disable QUIC when there is high packet loss rate.
+  // Specifies the maximum number of connections with high packet loss in a row
+  // after which QUIC will be disabled.
+  int max_number_of_lossy_connections_;
+  // Specifies packet loss rate in franction after which a connection is closed
+  // and is considered as a lossy connection.
+  float packet_loss_threshold_;
+  // Count number of lossy connections by port.
+  std::map<uint16, int> number_of_lossy_connections_;
+
   // Size of the UDP receive buffer.
   int socket_receive_buffer_size_;