OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/quic/quic_connection.h" | 5 #include "net/quic/quic_connection.h" |
6 | 6 |
7 #include <string.h> | 7 #include <string.h> |
8 #include <sys/types.h> | 8 #include <sys/types.h> |
| 9 |
9 #include <algorithm> | 10 #include <algorithm> |
10 #include <iterator> | 11 #include <iterator> |
11 #include <limits> | 12 #include <limits> |
12 #include <memory> | 13 #include <memory> |
13 #include <set> | 14 #include <set> |
14 #include <utility> | 15 #include <utility> |
15 | 16 |
16 #include "base/debug/stack_trace.h" | 17 #include "base/debug/stack_trace.h" |
17 #include "base/logging.h" | 18 #include "base/logging.h" |
18 #include "base/stl_util.h" | 19 #include "base/stl_util.h" |
(...skipping 27 matching lines...) Expand all Loading... |
46 namespace { | 47 namespace { |
47 | 48 |
48 // The largest gap in packets we'll accept without closing the connection. | 49 // The largest gap in packets we'll accept without closing the connection. |
49 // This will likely have to be tuned. | 50 // This will likely have to be tuned. |
50 const QuicPacketSequenceNumber kMaxPacketGap = 5000; | 51 const QuicPacketSequenceNumber kMaxPacketGap = 5000; |
51 | 52 |
52 // Limit the number of FEC groups to two. If we get enough out of order packets | 53 // Limit the number of FEC groups to two. If we get enough out of order packets |
53 // that this becomes limiting, we can revisit. | 54 // that this becomes limiting, we can revisit. |
54 const size_t kMaxFecGroups = 2; | 55 const size_t kMaxFecGroups = 2; |
55 | 56 |
56 // Limit the number of undecryptable packets we buffer in | |
57 // expectation of the CHLO/SHLO arriving. | |
58 const size_t kMaxUndecryptablePackets = 10; | |
59 | |
60 // Maximum number of acks received before sending an ack in response. | 57 // Maximum number of acks received before sending an ack in response. |
61 const size_t kMaxPacketsReceivedBeforeAckSend = 20; | 58 const size_t kMaxPacketsReceivedBeforeAckSend = 20; |
62 | 59 |
63 bool Near(QuicPacketSequenceNumber a, QuicPacketSequenceNumber b) { | 60 bool Near(QuicPacketSequenceNumber a, QuicPacketSequenceNumber b) { |
64 QuicPacketSequenceNumber delta = (a > b) ? a - b : b - a; | 61 QuicPacketSequenceNumber delta = (a > b) ? a - b : b - a; |
65 return delta <= kMaxPacketGap; | 62 return delta <= kMaxPacketGap; |
66 } | 63 } |
67 | 64 |
68 // An alarm that is scheduled to send an ack if a timeout occurs. | 65 // An alarm that is scheduled to send an ack if a timeout occurs. |
69 class AckAlarm : public QuicAlarm::Delegate { | 66 class AckAlarm : public QuicAlarm::Delegate { |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 private: | 152 private: |
156 QuicConnection* connection_; | 153 QuicConnection* connection_; |
157 | 154 |
158 DISALLOW_COPY_AND_ASSIGN(PingAlarm); | 155 DISALLOW_COPY_AND_ASSIGN(PingAlarm); |
159 }; | 156 }; |
160 | 157 |
161 } // namespace | 158 } // namespace |
162 | 159 |
163 QuicConnection::QueuedPacket::QueuedPacket(SerializedPacket packet, | 160 QuicConnection::QueuedPacket::QueuedPacket(SerializedPacket packet, |
164 EncryptionLevel level) | 161 EncryptionLevel level) |
165 : serialized_packet(packet), | 162 : serialized_packet(packet), |
166 encryption_level(level), | 163 encryption_level(level), |
167 transmission_type(NOT_RETRANSMISSION), | 164 transmission_type(NOT_RETRANSMISSION), |
168 original_sequence_number(0) { | 165 original_sequence_number(0) { |
169 } | 166 } |
170 | 167 |
171 QuicConnection::QueuedPacket::QueuedPacket( | 168 QuicConnection::QueuedPacket::QueuedPacket( |
172 SerializedPacket packet, | 169 SerializedPacket packet, |
173 EncryptionLevel level, | 170 EncryptionLevel level, |
174 TransmissionType transmission_type, | 171 TransmissionType transmission_type, |
175 QuicPacketSequenceNumber original_sequence_number) | 172 QuicPacketSequenceNumber original_sequence_number) |
176 : serialized_packet(packet), | 173 : serialized_packet(packet), |
177 encryption_level(level), | 174 encryption_level(level), |
178 transmission_type(transmission_type), | 175 transmission_type(transmission_type), |
(...skipping 18 matching lines...) Expand all Loading... |
197 clock_(helper->GetClock()), | 194 clock_(helper->GetClock()), |
198 random_generator_(helper->GetRandomGenerator()), | 195 random_generator_(helper->GetRandomGenerator()), |
199 connection_id_(connection_id), | 196 connection_id_(connection_id), |
200 peer_address_(address), | 197 peer_address_(address), |
201 migrating_peer_port_(0), | 198 migrating_peer_port_(0), |
202 last_packet_revived_(false), | 199 last_packet_revived_(false), |
203 last_size_(0), | 200 last_size_(0), |
204 last_decrypted_packet_level_(ENCRYPTION_NONE), | 201 last_decrypted_packet_level_(ENCRYPTION_NONE), |
205 largest_seen_packet_with_ack_(0), | 202 largest_seen_packet_with_ack_(0), |
206 largest_seen_packet_with_stop_waiting_(0), | 203 largest_seen_packet_with_stop_waiting_(0), |
| 204 max_undecryptable_packets_(0), |
207 pending_version_negotiation_packet_(false), | 205 pending_version_negotiation_packet_(false), |
208 received_packet_manager_(&stats_), | 206 received_packet_manager_(&stats_), |
209 ack_queued_(false), | 207 ack_queued_(false), |
210 num_packets_received_since_last_ack_sent_(0), | 208 num_packets_received_since_last_ack_sent_(0), |
211 stop_waiting_count_(0), | 209 stop_waiting_count_(0), |
212 ack_alarm_(helper->CreateAlarm(new AckAlarm(this))), | 210 ack_alarm_(helper->CreateAlarm(new AckAlarm(this))), |
213 retransmission_alarm_(helper->CreateAlarm(new RetransmissionAlarm(this))), | 211 retransmission_alarm_(helper->CreateAlarm(new RetransmissionAlarm(this))), |
214 send_alarm_(helper->CreateAlarm(new SendAlarm(this))), | 212 send_alarm_(helper->CreateAlarm(new SendAlarm(this))), |
215 resume_writes_alarm_(helper->CreateAlarm(new SendAlarm(this))), | 213 resume_writes_alarm_(helper->CreateAlarm(new SendAlarm(this))), |
216 timeout_alarm_(helper->CreateAlarm(new TimeoutAlarm(this))), | 214 timeout_alarm_(helper->CreateAlarm(new TimeoutAlarm(this))), |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 SetNetworkTimeouts(QuicTime::Delta::Infinite(), | 262 SetNetworkTimeouts(QuicTime::Delta::Infinite(), |
265 config.IdleConnectionStateLifetime()); | 263 config.IdleConnectionStateLifetime()); |
266 } else { | 264 } else { |
267 SetNetworkTimeouts(config.max_time_before_crypto_handshake(), | 265 SetNetworkTimeouts(config.max_time_before_crypto_handshake(), |
268 config.max_idle_time_before_crypto_handshake()); | 266 config.max_idle_time_before_crypto_handshake()); |
269 } | 267 } |
270 } else { | 268 } else { |
271 SetIdleNetworkTimeout(config.IdleConnectionStateLifetime()); | 269 SetIdleNetworkTimeout(config.IdleConnectionStateLifetime()); |
272 } | 270 } |
273 sent_packet_manager_.SetFromConfig(config); | 271 sent_packet_manager_.SetFromConfig(config); |
| 272 max_undecryptable_packets_ = config.max_undecryptable_packets(); |
274 } | 273 } |
275 | 274 |
276 bool QuicConnection::SelectMutualVersion( | 275 bool QuicConnection::SelectMutualVersion( |
277 const QuicVersionVector& available_versions) { | 276 const QuicVersionVector& available_versions) { |
278 // Try to find the highest mutual version by iterating over supported | 277 // Try to find the highest mutual version by iterating over supported |
279 // versions, starting with the highest, and breaking out of the loop once we | 278 // versions, starting with the highest, and breaking out of the loop once we |
280 // find a matching version in the provided available_versions vector. | 279 // find a matching version in the provided available_versions vector. |
281 const QuicVersionVector& supported_versions = framer_.supported_versions(); | 280 const QuicVersionVector& supported_versions = framer_.supported_versions(); |
282 for (size_t i = 0; i < supported_versions.size(); ++i) { | 281 for (size_t i = 0; i < supported_versions.size(); ++i) { |
283 const QuicVersion& version = supported_versions[i]; | 282 const QuicVersion& version = supported_versions[i]; |
(...skipping 825 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1109 CheckForAddressMigration(self_address, peer_address); | 1108 CheckForAddressMigration(self_address, peer_address); |
1110 | 1109 |
1111 stats_.bytes_received += packet.length(); | 1110 stats_.bytes_received += packet.length(); |
1112 ++stats_.packets_received; | 1111 ++stats_.packets_received; |
1113 | 1112 |
1114 if (!framer_.ProcessPacket(packet)) { | 1113 if (!framer_.ProcessPacket(packet)) { |
1115 // If we are unable to decrypt this packet, it might be | 1114 // If we are unable to decrypt this packet, it might be |
1116 // because the CHLO or SHLO packet was lost. | 1115 // because the CHLO or SHLO packet was lost. |
1117 if (framer_.error() == QUIC_DECRYPTION_FAILURE) { | 1116 if (framer_.error() == QUIC_DECRYPTION_FAILURE) { |
1118 if (encryption_level_ != ENCRYPTION_FORWARD_SECURE && | 1117 if (encryption_level_ != ENCRYPTION_FORWARD_SECURE && |
1119 undecryptable_packets_.size() < kMaxUndecryptablePackets) { | 1118 undecryptable_packets_.size() < max_undecryptable_packets_) { |
1120 QueueUndecryptablePacket(packet); | 1119 QueueUndecryptablePacket(packet); |
1121 } else if (debug_visitor_.get() != nullptr) { | 1120 } else if (debug_visitor_.get() != nullptr) { |
1122 debug_visitor_->OnUndecryptablePacket(); | 1121 debug_visitor_->OnUndecryptablePacket(); |
1123 } | 1122 } |
1124 } | 1123 } |
1125 DVLOG(1) << ENDPOINT << "Unable to process packet. Last packet processed: " | 1124 DVLOG(1) << ENDPOINT << "Unable to process packet. Last packet processed: " |
1126 << last_header_.packet_sequence_number; | 1125 << last_header_.packet_sequence_number; |
1127 return; | 1126 return; |
1128 } | 1127 } |
1129 | 1128 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1169 WritePendingRetransmissions(); | 1168 WritePendingRetransmissions(); |
1170 | 1169 |
1171 // Sending queued packets may have caused the socket to become write blocked, | 1170 // Sending queued packets may have caused the socket to become write blocked, |
1172 // or the congestion manager to prohibit sending. If we've sent everything | 1171 // or the congestion manager to prohibit sending. If we've sent everything |
1173 // we had queued and we're still not blocked, let the visitor know it can | 1172 // we had queued and we're still not blocked, let the visitor know it can |
1174 // write more. | 1173 // write more. |
1175 if (!CanWrite(HAS_RETRANSMITTABLE_DATA)) { | 1174 if (!CanWrite(HAS_RETRANSMITTABLE_DATA)) { |
1176 return; | 1175 return; |
1177 } | 1176 } |
1178 | 1177 |
1179 { // Limit the scope of the bundler. | 1178 { // Limit the scope of the bundler. ACK inclusion happens elsewhere. |
1180 // Set |include_ack| to false in bundler; ack inclusion happens elsewhere. | |
1181 ScopedPacketBundler bundler(this, NO_ACK); | 1179 ScopedPacketBundler bundler(this, NO_ACK); |
1182 visitor_->OnCanWrite(); | 1180 visitor_->OnCanWrite(); |
1183 } | 1181 } |
1184 | 1182 |
1185 // After the visitor writes, it may have caused the socket to become write | 1183 // After the visitor writes, it may have caused the socket to become write |
1186 // blocked or the congestion manager to prohibit sending, so check again. | 1184 // blocked or the congestion manager to prohibit sending, so check again. |
1187 if (visitor_->WillingAndAbleToWrite() && | 1185 if (visitor_->WillingAndAbleToWrite() && |
1188 !resume_writes_alarm_->IsSet() && | 1186 !resume_writes_alarm_->IsSet() && |
1189 CanWrite(HAS_RETRANSMITTABLE_DATA)) { | 1187 CanWrite(HAS_RETRANSMITTABLE_DATA)) { |
1190 // We're not write blocked, but some stream didn't write out all of its | 1188 // We're not write blocked, but some stream didn't write out all of its |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1315 QuicTime::Delta delay = sent_packet_manager_.TimeUntilSend( | 1313 QuicTime::Delta delay = sent_packet_manager_.TimeUntilSend( |
1316 now, retransmittable); | 1314 now, retransmittable); |
1317 if (delay.IsInfinite()) { | 1315 if (delay.IsInfinite()) { |
1318 send_alarm_->Cancel(); | 1316 send_alarm_->Cancel(); |
1319 return false; | 1317 return false; |
1320 } | 1318 } |
1321 | 1319 |
1322 // If the scheduler requires a delay, then we can not send this packet now. | 1320 // If the scheduler requires a delay, then we can not send this packet now. |
1323 if (!delay.IsZero()) { | 1321 if (!delay.IsZero()) { |
1324 send_alarm_->Update(now.Add(delay), QuicTime::Delta::FromMilliseconds(1)); | 1322 send_alarm_->Update(now.Add(delay), QuicTime::Delta::FromMilliseconds(1)); |
1325 DVLOG(1) << "Delaying sending."; | 1323 DVLOG(1) << ENDPOINT << "Delaying sending " << delay.ToMilliseconds() |
| 1324 << "ms"; |
1326 return false; | 1325 return false; |
1327 } | 1326 } |
1328 send_alarm_->Cancel(); | 1327 send_alarm_->Cancel(); |
1329 return true; | 1328 return true; |
1330 } | 1329 } |
1331 | 1330 |
1332 bool QuicConnection::WritePacket(QueuedPacket* packet) { | 1331 bool QuicConnection::WritePacket(QueuedPacket* packet) { |
1333 if (!WritePacketInner(packet)) { | 1332 if (!WritePacketInner(packet)) { |
1334 return false; | 1333 return false; |
1335 } | 1334 } |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1401 << QuicUtils::StringToHexASCIIDump( | 1400 << QuicUtils::StringToHexASCIIDump( |
1402 packet->serialized_packet.packet->AsStringPiece()); | 1401 packet->serialized_packet.packet->AsStringPiece()); |
1403 | 1402 |
1404 WriteResult result = writer_->WritePacket(encrypted->data(), | 1403 WriteResult result = writer_->WritePacket(encrypted->data(), |
1405 encrypted->length(), | 1404 encrypted->length(), |
1406 self_address().address(), | 1405 self_address().address(), |
1407 peer_address()); | 1406 peer_address()); |
1408 if (result.error_code == ERR_IO_PENDING) { | 1407 if (result.error_code == ERR_IO_PENDING) { |
1409 DCHECK_EQ(WRITE_STATUS_BLOCKED, result.status); | 1408 DCHECK_EQ(WRITE_STATUS_BLOCKED, result.status); |
1410 } | 1409 } |
1411 if (debug_visitor_.get() != nullptr) { | |
1412 // Pass the write result to the visitor. | |
1413 debug_visitor_->OnPacketSent(sequence_number, | |
1414 packet->original_sequence_number, | |
1415 packet->encryption_level, | |
1416 packet->transmission_type, | |
1417 *encrypted, | |
1418 result); | |
1419 } | |
1420 | 1410 |
1421 if (result.status == WRITE_STATUS_BLOCKED) { | 1411 if (result.status == WRITE_STATUS_BLOCKED) { |
1422 visitor_->OnWriteBlocked(); | 1412 visitor_->OnWriteBlocked(); |
1423 // If the socket buffers the the data, then the packet should not | 1413 // If the socket buffers the the data, then the packet should not |
1424 // be queued and sent again, which would result in an unnecessary | 1414 // be queued and sent again, which would result in an unnecessary |
1425 // duplicate packet being sent. The helper must call OnCanWrite | 1415 // duplicate packet being sent. The helper must call OnCanWrite |
1426 // when the write completes, and OnWriteError if an error occurs. | 1416 // when the write completes, and OnWriteError if an error occurs. |
1427 if (!writer_->IsWriteBlockedDataBuffered()) { | 1417 if (!writer_->IsWriteBlockedDataBuffered()) { |
1428 return false; | 1418 return false; |
1429 } | 1419 } |
1430 } | 1420 } |
1431 QuicTime now = clock_->Now(); | 1421 QuicTime now = clock_->Now(); |
| 1422 if (result.status != WRITE_STATUS_ERROR && debug_visitor_.get() != nullptr) { |
| 1423 // Pass the write result to the visitor. |
| 1424 debug_visitor_->OnPacketSent(packet->serialized_packet, |
| 1425 packet->original_sequence_number, |
| 1426 packet->encryption_level, |
| 1427 packet->transmission_type, |
| 1428 *encrypted, |
| 1429 now); |
| 1430 } |
1432 if (packet->transmission_type == NOT_RETRANSMISSION) { | 1431 if (packet->transmission_type == NOT_RETRANSMISSION) { |
1433 time_of_last_sent_new_packet_ = now; | 1432 time_of_last_sent_new_packet_ = now; |
1434 } | 1433 } |
1435 SetPingAlarm(); | 1434 SetPingAlarm(); |
1436 DVLOG(1) << ENDPOINT << "time of last sent packet: " | 1435 DVLOG(1) << ENDPOINT << "time of last sent packet: " |
1437 << now.ToDebuggingValue(); | 1436 << now.ToDebuggingValue(); |
1438 | 1437 |
1439 // TODO(ianswett): Change the sequence number length and other packet creator | 1438 // TODO(ianswett): Change the sequence number length and other packet creator |
1440 // options by a more explicit API than setting a struct value directly, | 1439 // options by a more explicit API than setting a struct value directly, |
1441 // perhaps via the NetworkChangeVisitor. | 1440 // perhaps via the NetworkChangeVisitor. |
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1850 // we had queued and we're still not blocked, let the visitor know it can | 1849 // we had queued and we're still not blocked, let the visitor know it can |
1851 // write more. | 1850 // write more. |
1852 return ShouldGeneratePacket(NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, | 1851 return ShouldGeneratePacket(NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, |
1853 pending_handshake); | 1852 pending_handshake); |
1854 } | 1853 } |
1855 | 1854 |
1856 void QuicConnection::SetIdleNetworkTimeout(QuicTime::Delta timeout) { | 1855 void QuicConnection::SetIdleNetworkTimeout(QuicTime::Delta timeout) { |
1857 // Adjust the idle timeout on client and server to prevent clients from | 1856 // Adjust the idle timeout on client and server to prevent clients from |
1858 // sending requests to servers which have already closed the connection. | 1857 // sending requests to servers which have already closed the connection. |
1859 if (is_server_) { | 1858 if (is_server_) { |
1860 timeout = timeout.Add(QuicTime::Delta::FromSeconds(1)); | 1859 timeout = timeout.Add(QuicTime::Delta::FromSeconds(3)); |
1861 } else if (timeout > QuicTime::Delta::FromSeconds(1)) { | 1860 } else if (timeout > QuicTime::Delta::FromSeconds(1)) { |
1862 timeout = timeout.Subtract(QuicTime::Delta::FromSeconds(1)); | 1861 timeout = timeout.Subtract(QuicTime::Delta::FromSeconds(1)); |
1863 } | 1862 } |
1864 | 1863 |
1865 if (timeout < idle_network_timeout_) { | 1864 if (timeout < idle_network_timeout_) { |
1866 idle_network_timeout_ = timeout; | 1865 idle_network_timeout_ = timeout; |
1867 if (FLAGS_quic_timeouts_only_from_alarms) { | 1866 if (FLAGS_quic_timeouts_only_from_alarms) { |
1868 SetTimeoutAlarm(); | 1867 SetTimeoutAlarm(); |
1869 } else { | 1868 } else { |
1870 CheckForTimeout(); | 1869 CheckForTimeout(); |
(...skipping 17 matching lines...) Expand all Loading... |
1888 } | 1887 } |
1889 | 1888 |
1890 void QuicConnection::SetNetworkTimeouts(QuicTime::Delta overall_timeout, | 1889 void QuicConnection::SetNetworkTimeouts(QuicTime::Delta overall_timeout, |
1891 QuicTime::Delta idle_timeout) { | 1890 QuicTime::Delta idle_timeout) { |
1892 LOG_IF(DFATAL, idle_timeout > overall_timeout) | 1891 LOG_IF(DFATAL, idle_timeout > overall_timeout) |
1893 << "idle_timeout:" << idle_timeout.ToMilliseconds() | 1892 << "idle_timeout:" << idle_timeout.ToMilliseconds() |
1894 << " overall_timeout:" << overall_timeout.ToMilliseconds(); | 1893 << " overall_timeout:" << overall_timeout.ToMilliseconds(); |
1895 // Adjust the idle timeout on client and server to prevent clients from | 1894 // Adjust the idle timeout on client and server to prevent clients from |
1896 // sending requests to servers which have already closed the connection. | 1895 // sending requests to servers which have already closed the connection. |
1897 if (is_server_) { | 1896 if (is_server_) { |
1898 idle_timeout = idle_timeout.Add(QuicTime::Delta::FromSeconds(1)); | 1897 idle_timeout = idle_timeout.Add(QuicTime::Delta::FromSeconds(3)); |
1899 } else if (idle_timeout > QuicTime::Delta::FromSeconds(1)) { | 1898 } else if (idle_timeout > QuicTime::Delta::FromSeconds(1)) { |
1900 idle_timeout = idle_timeout.Subtract(QuicTime::Delta::FromSeconds(1)); | 1899 idle_timeout = idle_timeout.Subtract(QuicTime::Delta::FromSeconds(1)); |
1901 } | 1900 } |
1902 overall_connection_timeout_ = overall_timeout; | 1901 overall_connection_timeout_ = overall_timeout; |
1903 idle_network_timeout_ = idle_timeout; | 1902 idle_network_timeout_ = idle_timeout; |
1904 | 1903 |
1905 SetTimeoutAlarm(); | 1904 SetTimeoutAlarm(); |
1906 } | 1905 } |
1907 | 1906 |
1908 void QuicConnection::CheckForTimeout() { | 1907 void QuicConnection::CheckForTimeout() { |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2032 } | 2031 } |
2033 for (size_t i = 0; i < retransmittable_frames->frames().size(); ++i) { | 2032 for (size_t i = 0; i < retransmittable_frames->frames().size(); ++i) { |
2034 if (retransmittable_frames->frames()[i].type == CONNECTION_CLOSE_FRAME) { | 2033 if (retransmittable_frames->frames()[i].type == CONNECTION_CLOSE_FRAME) { |
2035 return true; | 2034 return true; |
2036 } | 2035 } |
2037 } | 2036 } |
2038 return false; | 2037 return false; |
2039 } | 2038 } |
2040 | 2039 |
2041 } // namespace net | 2040 } // namespace net |
OLD | NEW |