blob: 42a3f2efd5f0f79a1c984aa21a074f88d1bc32aa [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/basictypes.h"
#include "base/message_loop.h"
#include "base/stringprintf.h"
#include "chrome/browser/net/network_stats.h"
#include "net/base/host_resolver.h"
#include "net/base/mock_host_resolver.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "net/test/test_server.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
namespace chrome_browser_net {
class NetworkStatsTest : public PlatformTest {
public:
NetworkStatsTest() {}
protected:
virtual void TearDown() {
// Flush the message loop to make application verifiers happy.
message_loop_.RunAllPending();
}
MessageLoopForIO message_loop_;
};
class NetworkStatsTestUDP : public NetworkStatsTest {
public:
NetworkStatsTestUDP()
: test_server_(net::TestServer::TYPE_UDP_ECHO,
net::TestServer::kLocalhost,
FilePath(FILE_PATH_LITERAL("net/data"))) {
}
protected:
void RunUDPEchoTest(int bytes, int packets, bool has_proxy) {
net::TestCompletionCallback cb;
scoped_ptr<net::MockHostResolver> host_resolver(
new net::MockHostResolver());
// We will use HISTOGRAM_PORT_MAX as the PortIndex enum for testing
// purposes.
NetworkStats* udp_stats_client = new NetworkStats();
EXPECT_TRUE(udp_stats_client->Start(host_resolver.get(),
test_server_.host_port_pair(),
NetworkStats::HISTOGRAM_PORT_MAX,
has_proxy,
bytes,
packets,
cb.callback()));
int rv = cb.WaitForResult();
// Check there were no errors during connect/write/read to echo UDP server.
EXPECT_EQ(0, rv);
}
net::TestServer test_server_;
};
TEST_F(NetworkStatsTestUDP, UDPEcho100BytesHasProxy) {
ASSERT_TRUE(test_server_.Start());
RunUDPEchoTest(100, 1, true);
}
TEST_F(NetworkStatsTestUDP, UDPEcho100BytesNoProxy) {
ASSERT_TRUE(test_server_.Start());
RunUDPEchoTest(100, 1, false);
}
TEST_F(NetworkStatsTestUDP, UDPEcho500BytesHasProxy) {
ASSERT_TRUE(test_server_.Start());
RunUDPEchoTest(500, 1, true);
}
TEST_F(NetworkStatsTestUDP, UDPEcho500BytesNoProxy) {
ASSERT_TRUE(test_server_.Start());
RunUDPEchoTest(500, 1, false);
}
TEST_F(NetworkStatsTestUDP, UDPEcho1KBytesHasProxy) {
ASSERT_TRUE(test_server_.Start());
RunUDPEchoTest(1024, 1, true);
}
TEST_F(NetworkStatsTestUDP, UDPEcho1KBytesNoProxy) {
ASSERT_TRUE(test_server_.Start());
RunUDPEchoTest(1024, 1, false);
}
TEST_F(NetworkStatsTestUDP, UDPEchoMultiplePacketsHasProxy) {
ASSERT_TRUE(test_server_.Start());
RunUDPEchoTest(1024, 4, true);
}
TEST_F(NetworkStatsTestUDP, UDPEchoMultiplePacketsNoProxy) {
ASSERT_TRUE(test_server_.Start());
RunUDPEchoTest(1024, 4, false);
}
TEST_F(NetworkStatsTestUDP, VerifyBytesInvalidHeaders) {
const uint32 KBytesToSend = 100;
const uint32 packets_to_send = 1;
NetworkStats network_stats;
net::TestCompletionCallback cb;
network_stats.Initialize(KBytesToSend,
NetworkStats::HISTOGRAM_PORT_MAX,
true,
packets_to_send,
cb.callback());
uint32 packet_number = network_stats.packet_number();
network_stats.set_base_packet_number(packet_number);
std::string message;
EXPECT_EQ(NetworkStats::ZERO_LENGTH_ERROR,
network_stats.VerifyBytes(message));
std::string version = base::StringPrintf("%02d", 1);
std::string invalid_checksum = base::StringPrintf("%010d", 0);
std::string payload_size = base::StringPrintf("%07d", KBytesToSend);
std::string invalid_key = base::StringPrintf("%06d", -1);
std::string key_string = base::StringPrintf("%06d", 899999);
std::string packet_number_string = base::StringPrintf("%010d", packet_number);
std::string short_payload(packet_number_string +
"1234567890123456789012345678901234567890123456789012345678901234567890");
std::string long_payload(packet_number_string +
"1234567890123456789012345678901234567890123456789012345678901234567890"
"1234567890123456789012345678901234567890123456789012345678901234567890");
message = version;
EXPECT_EQ(NetworkStats::NO_CHECKSUM_ERROR,
network_stats.VerifyBytes(message));
message = version + invalid_checksum;
EXPECT_EQ(NetworkStats::NO_PAYLOAD_SIZE_ERROR,
network_stats.VerifyBytes(message));
message = version + invalid_checksum + payload_size;
EXPECT_EQ(NetworkStats::NO_KEY_ERROR, network_stats.VerifyBytes(message));
message = version + invalid_checksum + payload_size + invalid_key;
EXPECT_EQ(NetworkStats::NO_PAYLOAD_ERROR, network_stats.VerifyBytes(message));
message = version + invalid_checksum + payload_size + invalid_key +
short_payload;
EXPECT_EQ(NetworkStats::INVALID_KEY_ERROR,
network_stats.VerifyBytes(message));
message = version + invalid_checksum + payload_size + key_string +
short_payload;
EXPECT_EQ(NetworkStats::TOO_SHORT_PAYLOAD,
network_stats.VerifyBytes(message));
message = version + invalid_checksum + payload_size + key_string +
long_payload;
EXPECT_EQ(NetworkStats::TOO_LONG_PAYLOAD, network_stats.VerifyBytes(message));
}
TEST_F(NetworkStatsTestUDP, VerifyBytesInvalidChecksum) {
const uint32 KBytesToSend = 100;
const uint32 packets_to_send = 1;
NetworkStats network_stats;
net::TestCompletionCallback cb;
network_stats.Initialize(KBytesToSend,
NetworkStats::HISTOGRAM_PORT_MAX,
true,
packets_to_send,
cb.callback());
uint32 packet_number = network_stats.packet_number();
network_stats.set_base_packet_number(packet_number);
std::string message;
EXPECT_EQ(NetworkStats::ZERO_LENGTH_ERROR,
network_stats.VerifyBytes(message));
std::string version = base::StringPrintf("%02d", 1);
std::string invalid_checksum = base::StringPrintf("%010d", 0);
std::string payload_size = base::StringPrintf("%07d", KBytesToSend);
std::string key_string = base::StringPrintf("%06d", 899999);
std::string packet_number_string = base::StringPrintf("%010d", packet_number);
scoped_refptr<net::IOBuffer> payload(new net::IOBuffer(KBytesToSend));
// Copy the Packet number into the payload.
size_t packet_number_size = packet_number_string.size();
memcpy(payload->data(), packet_number_string.c_str(), packet_number_size);
// Get random bytes to fill rest of the payload.
network_stats.stream_.GetBytes(payload->data() + packet_number_size,
KBytesToSend - packet_number_size);
// Calculate checksum for the payload.
char* payload_data = payload->data();
uint32 sum = network_stats.GetChecksum(payload_data, KBytesToSend);
std::string checksum = base::StringPrintf("%010d", sum);
char encoded_data[KBytesToSend];
memset(encoded_data, 0, KBytesToSend);
const char* key = key_string.c_str();
network_stats.Crypt(
key, key_string.length(), payload_data, KBytesToSend, encoded_data);
std::string encoded_payload(encoded_data, KBytesToSend);
// Test invalid checksum error by sending wrong checksum.
message = version + invalid_checksum + payload_size + key_string +
encoded_payload;
EXPECT_EQ(NetworkStats::INVALID_CHECKSUM, network_stats.VerifyBytes(message));
}
TEST_F(NetworkStatsTestUDP, VerifyBytesPreviousPacket) {
const uint32 KBytesToSend = 100;
const uint32 packets_to_send = 1;
NetworkStats network_stats;
net::TestCompletionCallback cb;
network_stats.Initialize(KBytesToSend,
NetworkStats::HISTOGRAM_PORT_MAX,
true,
packets_to_send,
cb.callback());
uint32 packet_number = network_stats.packet_number();
network_stats.set_base_packet_number(packet_number);
uint32 prev_packet_number = packet_number - 1;
std::string message;
std::string version = base::StringPrintf("%02d", 1);
std::string payload_size = base::StringPrintf("%07d", KBytesToSend);
std::string key_string = base::StringPrintf("%06d", 899999);
std::string prev_packet_number_string =
base::StringPrintf("%010d", prev_packet_number);
// Copy the previous packet number into the payload.
scoped_refptr<net::IOBuffer> payload(new net::IOBuffer(KBytesToSend));
size_t packet_number_size = prev_packet_number_string.size();
memcpy(payload->data(), prev_packet_number_string.c_str(),
packet_number_size);
// Get random bytes to fill rest of the payload.
network_stats.stream_.GetBytes(payload->data() + packet_number_size,
KBytesToSend - packet_number_size);
// Calculate checksum for the previous packet number payload.
char* payload_data = payload->data();
uint32 sum = network_stats.GetChecksum(payload_data, KBytesToSend);
std::string checksum = base::StringPrintf("%010d", sum);
char encoded_data[KBytesToSend];
memset(encoded_data, 0, KBytesToSend);
const char* key = key_string.c_str();
network_stats.Crypt(
key, key_string.length(), payload_data, KBytesToSend, encoded_data);
std::string encoded_payload(encoded_data, KBytesToSend);
message = version + checksum + payload_size + key_string + encoded_payload;
EXPECT_EQ(NetworkStats::PREVIOUS_PACKET_NUMBER,
network_stats.VerifyBytes(message));
EXPECT_EQ(0u, network_stats.packets_received_mask());
}
TEST_F(NetworkStatsTestUDP, VerifyBytesInvalidPacketNumber) {
const uint32 KBytesToSend = 100;
const uint32 packets_to_send = 1;
NetworkStats network_stats;
net::TestCompletionCallback cb;
network_stats.Initialize(KBytesToSend,
NetworkStats::HISTOGRAM_PORT_MAX,
true,
packets_to_send,
cb.callback());
uint32 packet_number = network_stats.packet_number();
network_stats.set_base_packet_number(packet_number);
uint32 corrupt_packet_number = packet_number + 1;
std::string message;
std::string version = base::StringPrintf("%02d", 1);
std::string payload_size = base::StringPrintf("%07d", KBytesToSend);
std::string key_string = base::StringPrintf("%06d", 899999);
std::string corrupt_packet_number_string =
base::StringPrintf("%010d", corrupt_packet_number);
scoped_refptr<net::IOBuffer> payload(new net::IOBuffer(KBytesToSend));
size_t packet_number_size = corrupt_packet_number_string.size();
memcpy(payload->data(), corrupt_packet_number_string.c_str(),
packet_number_size);
// Get random bytes to fill rest of the payload.
network_stats.stream_.GetBytes(payload->data() + packet_number_size,
KBytesToSend - packet_number_size);
// Calculate checksum for the corrupt packet number payload.
char* payload_data = payload->data();
uint32 sum = network_stats.GetChecksum(payload_data, KBytesToSend);
std::string checksum = base::StringPrintf("%010d", sum);
char encoded_data[KBytesToSend];
memset(encoded_data, 0, KBytesToSend);
const char* key = key_string.c_str();
network_stats.Crypt(
key, key_string.length(), payload_data, KBytesToSend, encoded_data);
std::string encoded_payload(encoded_data, KBytesToSend);
message = version + checksum + payload_size + key_string + encoded_payload;
EXPECT_EQ(NetworkStats::INVALID_PACKET_NUMBER,
network_stats.VerifyBytes(message));
EXPECT_EQ(0u, network_stats.packets_received_mask());
}
TEST_F(NetworkStatsTestUDP, VerifyBytesPatternChanged) {
const uint32 KBytesToSend = 100;
const uint32 packets_to_send = 1;
NetworkStats network_stats;
net::TestCompletionCallback cb;
network_stats.Initialize(KBytesToSend,
NetworkStats::HISTOGRAM_PORT_MAX,
true,
packets_to_send,
cb.callback());
uint32 packet_number = network_stats.packet_number();
network_stats.set_base_packet_number(packet_number);
std::string message;
std::string version = base::StringPrintf("%02d", 1);
std::string payload_size = base::StringPrintf("%07d", KBytesToSend);
std::string key_string = base::StringPrintf("%06d", 899999);
std::string packet_number_string = base::StringPrintf("%010d", packet_number);
scoped_refptr<net::IOBuffer> payload(new net::IOBuffer(KBytesToSend));
// Copy the Packet number into the payload.
size_t packet_number_size = packet_number_string.size();
memcpy(payload->data(), packet_number_string.c_str(), packet_number_size);
// Get random bytes to fill rest of the payload.
network_stats.stream_.GetBytes(payload->data() + packet_number_size,
KBytesToSend - packet_number_size);
// Calculate checksum for the payload.
char* payload_data = payload->data();
uint32 sum = network_stats.GetChecksum(payload_data, KBytesToSend);
std::string checksum = base::StringPrintf("%010d", sum);
const char* key = key_string.c_str();
// Corrupt the randomly generated bytes in payload data.
char corrupted_data_2[KBytesToSend];
memcpy(corrupted_data_2, payload_data, KBytesToSend);
char temp_char_1 = corrupted_data_2[packet_number_size];
corrupted_data_2[packet_number_size] =
corrupted_data_2[packet_number_size + 1];
corrupted_data_2[packet_number_size + 1] = temp_char_1;
char encoded_corrupted_data_2[KBytesToSend];
memset(encoded_corrupted_data_2, 0, KBytesToSend);
network_stats.Crypt(key,
key_string.length(),
corrupted_data_2,
KBytesToSend,
encoded_corrupted_data_2);
std::string invalid_payload(encoded_corrupted_data_2, KBytesToSend);
message = version + checksum + payload_size + key_string + invalid_payload;
EXPECT_EQ(NetworkStats::PATTERN_CHANGED, network_stats.VerifyBytes(message));
EXPECT_EQ(0u, network_stats.packets_received_mask());
}
TEST_F(NetworkStatsTestUDP, VerifyBytes) {
const uint32 KBytesToSend = 100;
const uint32 packets_to_send = 1;
NetworkStats network_stats;
net::TestCompletionCallback cb;
network_stats.Initialize(KBytesToSend,
NetworkStats::HISTOGRAM_PORT_MAX,
true,
packets_to_send,
cb.callback());
uint32 packet_number = network_stats.packet_number();
network_stats.set_base_packet_number(packet_number);
std::string message;
std::string version = base::StringPrintf("%02d", 1);
std::string payload_size = base::StringPrintf("%07d", KBytesToSend);
std::string key_string = base::StringPrintf("%06d", 899999);
std::string packet_number_string = base::StringPrintf("%010d", packet_number);
scoped_refptr<net::IOBuffer> payload(new net::IOBuffer(KBytesToSend));
// Copy the Packet number into the payload.
size_t packet_number_size = packet_number_string.size();
memcpy(payload->data(), packet_number_string.c_str(), packet_number_size);
// Get random bytes to fill rest of the payload.
network_stats.stream_.GetBytes(payload->data() + packet_number_size,
KBytesToSend - packet_number_size);
// Calculate checksum for the payload.
char* payload_data = payload->data();
uint32 sum = network_stats.GetChecksum(payload_data, KBytesToSend);
std::string checksum = base::StringPrintf("%010d", sum);
char encoded_data[KBytesToSend];
memset(encoded_data, 0, KBytesToSend);
const char* key = key_string.c_str();
network_stats.Crypt(
key, key_string.length(), payload_data, KBytesToSend, encoded_data);
std::string encoded_payload(encoded_data, KBytesToSend);
message = version + checksum + payload_size + key_string + encoded_payload;
EXPECT_EQ(NetworkStats::SUCCESS, network_stats.VerifyBytes(message));
EXPECT_EQ(1u, network_stats.packets_received_mask());
}
} // namespace chrome_browser_net