| OLD | NEW |
| (Empty) | |
| 1 #include "net/quic/quic_potential_connection_store.h" |
| 2 |
| 3 #include <list> |
| 4 #include <string> |
| 5 |
| 6 #include "base/stl_util.h" |
| 7 #include "net/quic/test_tools/mock_clock.h" |
| 8 #include "net/quic/test_tools/quic_test_utils.h" |
| 9 #include "testing/gmock/include/gmock/gmock.h" |
| 10 #include "testing/gtest/include/gtest/gtest.h" |
| 11 |
| 12 namespace net { |
| 13 |
| 14 typedef QuicPotentialConnectionStore::BufferedPacket BufferedPacket; |
| 15 typedef QuicPotentialConnectionStore::EnqueuePacketResult EnqueuePacketResult; |
| 16 |
| 17 static const size_t kDefaultMaxConnectionsInStore = 100; |
| 18 |
| 19 namespace test { |
| 20 class QuicPotentialConnectionStorePeer { |
| 21 public: |
| 22 static QuicAlarm* expiration_alarm(QuicPotentialConnectionStore* store) { |
| 23 return store->expiration_alarm_.get(); |
| 24 } |
| 25 }; |
| 26 |
| 27 namespace { |
| 28 |
| 29 typedef QuicPotentialConnectionStore::BufferedPacket BufferedPacket; |
| 30 typedef QuicPotentialConnectionStore::BufferedPacketList BufferedPacketList; |
| 31 |
| 32 class QuicPotentialConnectionStoreVisitor |
| 33 : public QuicPotentialConnectionStore::VisitorInterface { |
| 34 public: |
| 35 QuicPotentialConnectionStoreVisitor() {} |
| 36 |
| 37 ~QuicPotentialConnectionStoreVisitor() override {} |
| 38 |
| 39 void OnExpiredPackets(QuicConnectionId connection_id, |
| 40 BufferedPacketList early_arrived_packets) override { |
| 41 last_expired_packet_queue_ = std::move(early_arrived_packets); |
| 42 } |
| 43 |
| 44 // The packets queue for most recently expirect connection. |
| 45 BufferedPacketList last_expired_packet_queue_; |
| 46 }; |
| 47 |
| 48 class QuicPotentialConnectionStoreTest : public ::testing::Test { |
| 49 public: |
| 50 QuicPotentialConnectionStoreTest() |
| 51 : store_(&visitor_, &clock_, &alarm_factory_), |
| 52 server_address_(Loopback6(), 65535), |
| 53 client_address_(Loopback6(), 65535), |
| 54 data_packet_(packet_content_.data(), packet_content_.size()) {} |
| 55 |
| 56 protected: |
| 57 QuicPotentialConnectionStoreVisitor visitor_; |
| 58 MockClock clock_; |
| 59 MockAlarmFactory alarm_factory_; |
| 60 QuicPotentialConnectionStore store_; |
| 61 IPEndPoint server_address_; |
| 62 IPEndPoint client_address_; |
| 63 std::string packet_content_ = "some encrypted content"; |
| 64 QuicEncryptedPacket data_packet_; |
| 65 }; |
| 66 |
| 67 TEST_F(QuicPotentialConnectionStoreTest, SimpleEnqueueAndDeliverPacket) { |
| 68 QuicConnectionId connection_id = 1; |
| 69 store_.EnqueuePacket(connection_id, data_packet_, server_address_, |
| 70 client_address_); |
| 71 std::list<BufferedPacket> queue = store_.DeliverPackets(connection_id); |
| 72 ASSERT_EQ(1u, queue.size()); |
| 73 // Check content of the only packet in the queue. |
| 74 EXPECT_EQ(packet_content_, queue.front().packet->AsStringPiece()); |
| 75 EXPECT_EQ(client_address_, queue.front().client_address); |
| 76 EXPECT_EQ(server_address_, queue.front().server_address); |
| 77 // No more packets on connection 1 should remain in the store. |
| 78 EXPECT_TRUE(store_.DeliverPackets(connection_id).empty()); |
| 79 } |
| 80 |
| 81 TEST_F(QuicPotentialConnectionStoreTest, |
| 82 DifferentPacketAddressOnOneConnection) { |
| 83 IPEndPoint addr_with_new_port(Loopback4(), 256); |
| 84 QuicConnectionId connection_id = 1; |
| 85 store_.EnqueuePacket(connection_id, data_packet_, server_address_, |
| 86 client_address_); |
| 87 store_.EnqueuePacket(connection_id, data_packet_, server_address_, |
| 88 addr_with_new_port); |
| 89 std::list<BufferedPacket> queue = store_.DeliverPackets(connection_id); |
| 90 ASSERT_EQ(2u, queue.size()); |
| 91 // The address migration path should be preserved. |
| 92 EXPECT_EQ(client_address_, queue.front().client_address); |
| 93 EXPECT_EQ(addr_with_new_port, queue.back().client_address); |
| 94 } |
| 95 |
| 96 TEST_F(QuicPotentialConnectionStoreTest, |
| 97 EnqueueAndDeliverMultiplePacketsOnMultipleConnections) { |
| 98 size_t num_connections = 10; |
| 99 for (QuicConnectionId connection_id = 1; connection_id <= num_connections; |
| 100 ++connection_id) { |
| 101 store_.EnqueuePacket(connection_id, data_packet_, server_address_, |
| 102 client_address_); |
| 103 store_.EnqueuePacket(connection_id, data_packet_, server_address_, |
| 104 client_address_); |
| 105 } |
| 106 |
| 107 // Deliver packets in reversed order. |
| 108 for (QuicConnectionId connection_id = num_connections; connection_id > 0; |
| 109 --connection_id) { |
| 110 std::list<BufferedPacket> queue = store_.DeliverPackets(connection_id); |
| 111 ASSERT_EQ(2u, queue.size()); |
| 112 } |
| 113 } |
| 114 |
| 115 TEST_F(QuicPotentialConnectionStoreTest, |
| 116 FailToBufferTooManyPacketsOnExistingConnection) { |
| 117 // Tests that for one connection, only limited number of packets can be |
| 118 // buffered. |
| 119 size_t num_packets = kDefaultMaxUndecryptablePackets + 1; |
| 120 QuicConnectionId connection_id = 1; |
| 121 for (size_t i = 1; i <= num_packets; ++i) { |
| 122 // Only first |kDefaultMaxUndecryptablePackets packets| will be buffered. |
| 123 EnqueuePacketResult result = store_.EnqueuePacket( |
| 124 connection_id, data_packet_, server_address_, client_address_); |
| 125 if (i <= kDefaultMaxUndecryptablePackets) { |
| 126 EXPECT_EQ(EnqueuePacketResult::SUCCESS, result); |
| 127 } else { |
| 128 EXPECT_EQ(EnqueuePacketResult::TOO_MANY_PACKETS, result); |
| 129 } |
| 130 } |
| 131 |
| 132 // Only first |kDefaultMaxUndecryptablePackets| packets are kept in the store |
| 133 // and can be delivered. |
| 134 EXPECT_EQ(kDefaultMaxUndecryptablePackets, |
| 135 store_.DeliverPackets(connection_id).size()); |
| 136 } |
| 137 |
| 138 TEST_F(QuicPotentialConnectionStoreTest, |
| 139 FailToBufferPacketsForTooManyConnections) { |
| 140 // Tests that store can only keep early arrived packets for limited number of |
| 141 // connections. |
| 142 size_t num_connections = kDefaultMaxConnectionsInStore + 1; |
| 143 for (size_t connection_id = 1; connection_id <= num_connections; |
| 144 ++connection_id) { |
| 145 EnqueuePacketResult result = store_.EnqueuePacket( |
| 146 connection_id, data_packet_, server_address_, client_address_); |
| 147 if (connection_id <= kDefaultMaxConnectionsInStore) { |
| 148 EXPECT_EQ(EnqueuePacketResult::SUCCESS, result); |
| 149 } else { |
| 150 EXPECT_EQ(EnqueuePacketResult::TOO_MANY_CONNECTIONS, result); |
| 151 } |
| 152 } |
| 153 // Store only keeps early arrived packets upto |kDefaultMaxConnectionsInStore| |
| 154 // connections. |
| 155 for (size_t connection_id = 1; connection_id <= num_connections; |
| 156 ++connection_id) { |
| 157 std::list<BufferedPacket> queue = store_.DeliverPackets(connection_id); |
| 158 if (connection_id <= kDefaultMaxConnectionsInStore) { |
| 159 EXPECT_EQ(1u, queue.size()); |
| 160 } else { |
| 161 EXPECT_EQ(0u, queue.size()); |
| 162 } |
| 163 } |
| 164 } |
| 165 |
| 166 TEST_F(QuicPotentialConnectionStoreTest, PacketQueueExpiredBeforeDelivery) { |
| 167 QuicConnectionId connection_id = 1; |
| 168 store_.EnqueuePacket(connection_id, data_packet_, server_address_, |
| 169 client_address_); |
| 170 // Packet for another connection arrive 1ms later. |
| 171 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1)); |
| 172 QuicConnectionId connection_id2 = 2; |
| 173 // Use different client address to differetiate packets from different |
| 174 // connections. |
| 175 IPEndPoint another_client_address(Loopback4(), 255); |
| 176 store_.EnqueuePacket(connection_id2, data_packet_, server_address_, |
| 177 another_client_address); |
| 178 // Advance clock to the time when connection 1 expires. |
| 179 clock_.AdvanceTime(QuicPotentialConnectionStorePeer::expiration_alarm(&store_) |
| 180 ->deadline() |
| 181 .Subtract(clock_.ApproximateNow())); |
| 182 ASSERT_GE( |
| 183 clock_.ApproximateNow(), |
| 184 QuicPotentialConnectionStorePeer::expiration_alarm(&store_)->deadline()); |
| 185 // Fire alarm to remove long-staying connection 1 packets. |
| 186 alarm_factory_.FireAlarm( |
| 187 QuicPotentialConnectionStorePeer::expiration_alarm(&store_)); |
| 188 EXPECT_EQ(1u, visitor_.last_expired_packet_queue_.buffered_packets.size()); |
| 189 // Try to deliver packets, but packet queue has been removed so no |
| 190 // packets can be returned. |
| 191 ASSERT_EQ(0u, store_.DeliverPackets(connection_id).size()); |
| 192 |
| 193 // Deliver packets on connection 2. And the queue for connection 2 should be |
| 194 // returned. |
| 195 std::list<BufferedPacket> queue = store_.DeliverPackets(connection_id2); |
| 196 ASSERT_EQ(1u, queue.size()); |
| 197 // Packets in connection 2 should use another client address. |
| 198 EXPECT_EQ(another_client_address, queue.front().client_address); |
| 199 |
| 200 // Test the alarm is reset by enqueueing 2 packets for 3rd connection and wait |
| 201 // for them to expire. |
| 202 QuicConnectionId connection_id3 = 3; |
| 203 store_.EnqueuePacket(connection_id3, data_packet_, server_address_, |
| 204 client_address_); |
| 205 store_.EnqueuePacket(connection_id3, data_packet_, server_address_, |
| 206 client_address_); |
| 207 clock_.AdvanceTime(QuicPotentialConnectionStorePeer::expiration_alarm(&store_) |
| 208 ->deadline() |
| 209 .Subtract(clock_.ApproximateNow())); |
| 210 alarm_factory_.FireAlarm( |
| 211 QuicPotentialConnectionStorePeer::expiration_alarm(&store_)); |
| 212 // |last_expired_packet_queue_| should be updated. |
| 213 EXPECT_EQ(2u, visitor_.last_expired_packet_queue_.buffered_packets.size()); |
| 214 } |
| 215 |
| 216 } // namespace |
| 217 } // namespace test |
| 218 } // namespace net |
| OLD | NEW |