| Index: net/tools/quic/end_to_end_test.cc
|
| diff --git a/net/tools/quic/end_to_end_test.cc b/net/tools/quic/end_to_end_test.cc
|
| index ef394b95f2453d21588a6cd1b170418d42ce7697..e06a9eda36db9f2d4eb9c59887a1967a13602c14 100644
|
| --- a/net/tools/quic/end_to_end_test.cc
|
| +++ b/net/tools/quic/end_to_end_test.cc
|
| @@ -28,6 +28,7 @@
|
| #include "net/quic/test_tools/quic_test_utils.h"
|
| #include "net/quic/test_tools/reliable_quic_stream_peer.h"
|
| #include "net/test/gtest_util.h"
|
| +#include "net/tools/epoll_server/epoll_server.h"
|
| #include "net/tools/quic/quic_epoll_connection_helper.h"
|
| #include "net/tools/quic/quic_in_memory_cache.h"
|
| #include "net/tools/quic/quic_packet_writer_wrapper.h"
|
| @@ -46,6 +47,7 @@
|
|
|
| using base::StringPiece;
|
| using base::WaitableEvent;
|
| +using net::EpollServer;
|
| using net::test::GenerateBody;
|
| using net::test::QuicConnectionPeer;
|
| using net::test::QuicSessionPeer;
|
| @@ -953,7 +955,10 @@ class WrongAddressWriter : public QuicPacketWriterWrapper {
|
| IPEndPoint self_address_;
|
| };
|
|
|
| -TEST_P(EndToEndTest, ConnectionMigration) {
|
| +TEST_P(EndToEndTest, ConnectionMigrationClientIPChanged) {
|
| + // Tests that the client's IP can not change during an established QUIC
|
| + // connection. If it changes, the connection is closed by the server as we do
|
| + // not yet support IP migration.
|
| ASSERT_TRUE(Initialize());
|
|
|
| EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
|
| @@ -971,6 +976,59 @@ TEST_P(EndToEndTest, ConnectionMigration) {
|
| EXPECT_EQ(QUIC_ERROR_MIGRATING_ADDRESS, client_->connection_error());
|
| }
|
|
|
| +TEST_P(EndToEndTest, ConnectionMigrationClientPortChanged) {
|
| + // Tests that the client's port can change during an established QUIC
|
| + // connection, and that doing so does not result in the connection being
|
| + // closed by the server.
|
| + FLAGS_quic_allow_port_migration = true;
|
| +
|
| + ASSERT_TRUE(Initialize());
|
| +
|
| + EXPECT_EQ(kFooResponseBody, client_->SendSynchronousRequest("/foo"));
|
| + EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
|
| +
|
| + // Store the client address which was used to send the first request.
|
| + IPEndPoint old_address = client_->client()->client_address();
|
| +
|
| + // Stop listening on the old FD.
|
| + EpollServer* eps = client_->client()->epoll_server();
|
| + int old_fd = client_->client()->fd();
|
| + eps->UnregisterFD(old_fd);
|
| + close(old_fd);
|
| +
|
| + // Create a new socket, which will result in a new ephemeral port.
|
| + QuicClientPeer::CreateUDPSocket(client_->client());
|
| +
|
| + // The packet writer needs to be updated to use the new FD.
|
| + client_->client()->CreateQuicPacketWriter();
|
| +
|
| + // Change the internal state of the client and connection to use the new port,
|
| + // this is done because in a real NAT rebinding the client wouldn't see any
|
| + // port change, and so expects no change to incoming port.
|
| + // This is kind of ugly, but needed as we are simply swapping out the client
|
| + // FD rather than any more complex NAT rebinding simulation.
|
| + int new_port = client_->client()->client_address().port();
|
| + QuicClientPeer::SetClientPort(client_->client(), new_port);
|
| + QuicConnectionPeer::SetSelfAddress(
|
| + client_->client()->session()->connection(),
|
| + IPEndPoint(
|
| + client_->client()->session()->connection()->self_address().address(),
|
| + new_port));
|
| +
|
| + // Register the new FD for epoll events.
|
| + int new_fd = client_->client()->fd();
|
| + eps->RegisterFD(new_fd, client_->client(), EPOLLIN | EPOLLOUT | EPOLLET);
|
| +
|
| + // Send a second request, using the new FD.
|
| + EXPECT_EQ(kBarResponseBody, client_->SendSynchronousRequest("/bar"));
|
| + EXPECT_EQ(200u, client_->response_headers()->parsed_response_code());
|
| +
|
| + // Verify that the client's ephemeral port is different.
|
| + IPEndPoint new_address = client_->client()->client_address();
|
| + EXPECT_EQ(old_address.address(), new_address.address());
|
| + EXPECT_NE(old_address.port(), new_address.port());
|
| +}
|
| +
|
| TEST_P(EndToEndTest, DifferentFlowControlWindows) {
|
| // Client and server can set different initial flow control receive windows.
|
| // These are sent in CHLO/SHLO. Tests that these values are exchanged properly
|
|
|