summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorjar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-20 05:41:42 +0000
committerjar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-20 05:41:42 +0000
commitf9f4841b14a9f309ce5ee613f0d4de6afad88767 (patch)
tree390a79375cb846d9c0aba2b708532df92464ec26 /net
parent5fbd065bd1025374e52d3c939fa7f668b79c153a (diff)
downloadchromium_src-f9f4841b14a9f309ce5ee613f0d4de6afad88767.zip
chromium_src-f9f4841b14a9f309ce5ee613f0d4de6afad88767.tar.gz
chromium_src-f9f4841b14a9f309ce5ee613f0d4de6afad88767.tar.bz2
2 experiments: DNS prefetch limit concurrency: TCP split a packet
Some firewalls apparently try to preclude a "syn flood to host" by limiting the number of syn's (used to open a TCP/IP socket) that are outstanding without having received a syn-ack. Presumably this is to prevent a user from participating in a syn-flood attack (which traditional sends a lot of syn packets, with false return addresses, resulting in no responses). Apparently this firewall technology has in some cases been extended to include UDP sessions for which there has been no response, and this may include DNS resolutions. Since the prefetcher currently resolves as many as 8 names simultaneously, this is remarkably close to the reported threshold of 10 un-answered connections. This test attempts to limit connections to 2, 4, or 6, so that we can see if this helps users. In TCP, the RTO remains (under windows) at a full 3 seconds until after the first ack is received. As a result, if the first data packet sent (after the SYN) is lost, then TCP won't resend until after 3 seconds without an ack. As a test, we split up the first packet into two parts (the second part containing only one byte). This is done as an A/B test, and we'll see if we get a measurable improvement in page-load-time latency. Finally, to get better page load stats, I adjusted the PLT histograms so that we record a "final" time for abandoned pages when they are closed (even if they didn't finish rendering, etc.). This should give a much more fair PLT comparison for all network latency experiments. BUG=3041 BUG=12754 r=mbelshe,darin Review URL: http://codereview.chromium.org/1088002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@42181 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r--net/http/http_stream_parser.cc29
1 files changed, 26 insertions, 3 deletions
diff --git a/net/http/http_stream_parser.cc b/net/http/http_stream_parser.cc
index 53c57f1..334e770 100644
--- a/net/http/http_stream_parser.cc
+++ b/net/http/http_stream_parser.cc
@@ -5,6 +5,7 @@
#include "net/http/http_stream_parser.h"
#include "base/compiler_specific.h"
+#include "base/field_trial.h"
#include "base/trace_event.h"
#include "net/base/io_buffer.h"
#include "net/http/http_request_info.h"
@@ -186,17 +187,39 @@ int HttpStreamParser::DoLoop(int result) {
int HttpStreamParser::DoSendHeaders(int result) {
request_headers_->DidConsume(result);
- if (request_headers_->BytesRemaining() > 0) {
+ // Set up a field trial to see if splitting the first packet helps with
+ // latency (loss of the first packet may otherwise cause an RTO of 3 seconds
+ // at least on Windows... but with two packets, the probability of loss
+ // without any ack to alert us should be lower, and receipt of a first ack
+ // will lower the RTO dramatically, so recovery will be fast.).
+ static const FieldTrial* kTrial = FieldTrialList::Find("PacketSplit");
+ static const bool kForceSecondPacket(kTrial && (kTrial->group() == 0));
+ if (kForceSecondPacket)
+ DCHECK_EQ(kTrial->group_name(), "_first_packet_split");
+
+ int bytes_remaining = request_headers_->BytesRemaining();
+ if (bytes_remaining > 0) {
// Record our best estimate of the 'request time' as the time when we send
// out the first bytes of the request headers.
- if (request_headers_->BytesRemaining() == request_headers_->size()) {
+ if (bytes_remaining == request_headers_->size()) {
response_->request_time = base::Time::Now();
+
+ // Note that we ONLY ensure second packet when this is a fresh connection,
+ // as a reused connection (re: reuse_type()) already had traffic, and
+ // hence has an RTO which will provide for a fast packet-loss recovery.
+ // We also avoid splitting out a second packet if we have a request_body_
+ // to send, as it will provide the desired second packet (see bug 38703).
+ if (kForceSecondPacket &&
+ connection_->reuse_type() != ClientSocketHandle::REUSED_IDLE &&
+ (request_body_ == NULL || !request_body_->size()) &&
+ bytes_remaining > 1)
+ --bytes_remaining; // Leave one byte for next packet.
}
// TODO(vandebo) remove when bug 31096 is resolved
CHECK(connection_);
CHECK(connection_->socket());
result = connection_->socket()->Write(request_headers_,
- request_headers_->BytesRemaining(),
+ bytes_remaining,
&io_callback_);
} else if (request_body_ != NULL && request_body_->size()) {
io_state_ = STATE_SENDING_BODY;