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 #include <algorithm> | 9 #include <algorithm> |
10 #include <iterator> | 10 #include <iterator> |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
197 uint32 max_flow_control_receive_window_bytes) | 197 uint32 max_flow_control_receive_window_bytes) |
198 : framer_(supported_versions, helper->GetClock()->ApproximateNow(), | 198 : framer_(supported_versions, helper->GetClock()->ApproximateNow(), |
199 is_server), | 199 is_server), |
200 helper_(helper), | 200 helper_(helper), |
201 writer_(writer), | 201 writer_(writer), |
202 encryption_level_(ENCRYPTION_NONE), | 202 encryption_level_(ENCRYPTION_NONE), |
203 clock_(helper->GetClock()), | 203 clock_(helper->GetClock()), |
204 random_generator_(helper->GetRandomGenerator()), | 204 random_generator_(helper->GetRandomGenerator()), |
205 connection_id_(connection_id), | 205 connection_id_(connection_id), |
206 peer_address_(address), | 206 peer_address_(address), |
207 migrating_peer_port_(0), | |
207 last_packet_revived_(false), | 208 last_packet_revived_(false), |
208 last_size_(0), | 209 last_size_(0), |
209 last_decrypted_packet_level_(ENCRYPTION_NONE), | 210 last_decrypted_packet_level_(ENCRYPTION_NONE), |
210 largest_seen_packet_with_ack_(0), | 211 largest_seen_packet_with_ack_(0), |
211 largest_seen_packet_with_stop_waiting_(0), | 212 largest_seen_packet_with_stop_waiting_(0), |
212 pending_version_negotiation_packet_(false), | 213 pending_version_negotiation_packet_(false), |
213 received_packet_manager_(kTCP, &stats_), | 214 received_packet_manager_(kTCP, &stats_), |
214 ack_queued_(false), | 215 ack_queued_(false), |
215 stop_waiting_count_(0), | 216 stop_waiting_count_(0), |
216 ack_alarm_(helper->CreateAlarm(new AckAlarm(this))), | 217 ack_alarm_(helper->CreateAlarm(new AckAlarm(this))), |
(...skipping 10 matching lines...) Expand all Loading... | |
227 overall_connection_timeout_(QuicTime::Delta::Infinite()), | 228 overall_connection_timeout_(QuicTime::Delta::Infinite()), |
228 time_of_last_received_packet_(clock_->ApproximateNow()), | 229 time_of_last_received_packet_(clock_->ApproximateNow()), |
229 time_of_last_sent_new_packet_(clock_->ApproximateNow()), | 230 time_of_last_sent_new_packet_(clock_->ApproximateNow()), |
230 sequence_number_of_last_sent_packet_(0), | 231 sequence_number_of_last_sent_packet_(0), |
231 sent_packet_manager_( | 232 sent_packet_manager_( |
232 is_server, clock_, &stats_, kTCP, | 233 is_server, clock_, &stats_, kTCP, |
233 FLAGS_quic_use_time_loss_detection ? kTime : kNack), | 234 FLAGS_quic_use_time_loss_detection ? kTime : kNack), |
234 version_negotiation_state_(START_NEGOTIATION), | 235 version_negotiation_state_(START_NEGOTIATION), |
235 is_server_(is_server), | 236 is_server_(is_server), |
236 connected_(true), | 237 connected_(true), |
237 address_migrating_(false), | 238 peer_ip_changed_(false), |
239 peer_port_changed_(false), | |
240 self_ip_changed_(false), | |
241 self_port_changed_(false), | |
238 max_flow_control_receive_window_bytes_( | 242 max_flow_control_receive_window_bytes_( |
239 max_flow_control_receive_window_bytes) { | 243 max_flow_control_receive_window_bytes) { |
240 if (max_flow_control_receive_window_bytes_ < kDefaultFlowControlSendWindow) { | 244 if (max_flow_control_receive_window_bytes_ < kDefaultFlowControlSendWindow) { |
241 DLOG(ERROR) << "Initial receive window (" | 245 DLOG(ERROR) << "Initial receive window (" |
242 << max_flow_control_receive_window_bytes_ | 246 << max_flow_control_receive_window_bytes_ |
243 << ") cannot be set lower than default (" | 247 << ") cannot be set lower than default (" |
244 << kDefaultFlowControlSendWindow << ")."; | 248 << kDefaultFlowControlSendWindow << ")."; |
245 max_flow_control_receive_window_bytes_ = kDefaultFlowControlSendWindow; | 249 max_flow_control_receive_window_bytes_ = kDefaultFlowControlSendWindow; |
246 } | 250 } |
247 | 251 |
(...skipping 850 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1098 const QuicEncryptedPacket& packet) { | 1102 const QuicEncryptedPacket& packet) { |
1099 if (!connected_) { | 1103 if (!connected_) { |
1100 return; | 1104 return; |
1101 } | 1105 } |
1102 if (debug_visitor_) { | 1106 if (debug_visitor_) { |
1103 debug_visitor_->OnPacketReceived(self_address, peer_address, packet); | 1107 debug_visitor_->OnPacketReceived(self_address, peer_address, packet); |
1104 } | 1108 } |
1105 last_packet_revived_ = false; | 1109 last_packet_revived_ = false; |
1106 last_size_ = packet.length(); | 1110 last_size_ = packet.length(); |
1107 | 1111 |
1108 address_migrating_ = false; | 1112 CheckForAddressMigration(self_address, peer_address); |
1109 | |
1110 if (peer_address_.address().empty()) { | |
1111 peer_address_ = peer_address; | |
1112 } | |
1113 if (self_address_.address().empty()) { | |
1114 self_address_ = self_address; | |
1115 } | |
1116 | |
1117 if (!(peer_address == peer_address_ && self_address == self_address_)) { | |
1118 address_migrating_ = true; | |
1119 } | |
1120 | 1113 |
1121 stats_.bytes_received += packet.length(); | 1114 stats_.bytes_received += packet.length(); |
1122 ++stats_.packets_received; | 1115 ++stats_.packets_received; |
1123 | 1116 |
1124 if (!framer_.ProcessPacket(packet)) { | 1117 if (!framer_.ProcessPacket(packet)) { |
1125 // If we are unable to decrypt this packet, it might be | 1118 // If we are unable to decrypt this packet, it might be |
1126 // because the CHLO or SHLO packet was lost. | 1119 // because the CHLO or SHLO packet was lost. |
1127 if (encryption_level_ != ENCRYPTION_FORWARD_SECURE && | 1120 if (encryption_level_ != ENCRYPTION_FORWARD_SECURE && |
1128 framer_.error() == QUIC_DECRYPTION_FAILURE && | 1121 framer_.error() == QUIC_DECRYPTION_FAILURE && |
1129 undecryptable_packets_.size() < kMaxUndecryptablePackets) { | 1122 undecryptable_packets_.size() < kMaxUndecryptablePackets) { |
1130 QueueUndecryptablePacket(packet); | 1123 QueueUndecryptablePacket(packet); |
1131 } | 1124 } |
1132 DVLOG(1) << ENDPOINT << "Unable to process packet. Last packet processed: " | 1125 DVLOG(1) << ENDPOINT << "Unable to process packet. Last packet processed: " |
1133 << last_header_.packet_sequence_number; | 1126 << last_header_.packet_sequence_number; |
1134 return; | 1127 return; |
1135 } | 1128 } |
1136 | 1129 |
1137 ++stats_.packets_processed; | 1130 ++stats_.packets_processed; |
1138 MaybeProcessUndecryptablePackets(); | 1131 MaybeProcessUndecryptablePackets(); |
1139 MaybeProcessRevivedPacket(); | 1132 MaybeProcessRevivedPacket(); |
1140 MaybeSendInResponseToPacket(); | 1133 MaybeSendInResponseToPacket(); |
1141 SetPingAlarm(); | 1134 SetPingAlarm(); |
1142 } | 1135 } |
1143 | 1136 |
1137 void QuicConnection::CheckForAddressMigration( | |
1138 const IPEndPoint& self_address, const IPEndPoint& peer_address) { | |
1139 peer_ip_changed_ = false; | |
1140 peer_port_changed_ = false; | |
1141 self_ip_changed_ = false; | |
1142 self_port_changed_ = false; | |
1143 | |
1144 if (peer_address_.address().empty()) { | |
1145 peer_address_ = peer_address; | |
1146 } | |
1147 if (self_address_.address().empty()) { | |
1148 self_address_ = self_address; | |
1149 } | |
1150 | |
1151 if (!peer_address.address().empty() && !peer_address_.address().empty()) { | |
1152 peer_ip_changed_ = (peer_address.address() != peer_address_.address()); | |
1153 peer_port_changed_ = (peer_address.port() != peer_address_.port()); | |
1154 | |
1155 // Store in case we want to migrate connection in ProcessValidatedPacket. | |
1156 migrating_peer_port_ = peer_address.port(); | |
1157 } | |
1158 | |
1159 if (!self_address.address().empty() && !self_address_.address().empty()) { | |
1160 self_ip_changed_ = (self_address.address() != self_address_.address()); | |
1161 self_port_changed_ = (self_address.port() != self_address_.port()); | |
1162 } | |
1163 } | |
1164 | |
1144 void QuicConnection::OnCanWrite() { | 1165 void QuicConnection::OnCanWrite() { |
1145 DCHECK(!writer_->IsWriteBlocked()); | 1166 DCHECK(!writer_->IsWriteBlocked()); |
1146 | 1167 |
1147 WriteQueuedPackets(); | 1168 WriteQueuedPackets(); |
1148 WritePendingRetransmissions(); | 1169 WritePendingRetransmissions(); |
1149 | 1170 |
1150 IsHandshake pending_handshake = visitor_->HasPendingHandshake() ? | 1171 IsHandshake pending_handshake = visitor_->HasPendingHandshake() ? |
1151 IS_HANDSHAKE : NOT_HANDSHAKE; | 1172 IS_HANDSHAKE : NOT_HANDSHAKE; |
1152 // Sending queued packets may have caused the socket to become write blocked, | 1173 // Sending queued packets may have caused the socket to become write blocked, |
1153 // or the congestion manager to prohibit sending. If we've sent everything | 1174 // or the congestion manager to prohibit sending. If we've sent everything |
(...skipping 24 matching lines...) Expand all Loading... | |
1178 } | 1199 } |
1179 } | 1200 } |
1180 | 1201 |
1181 void QuicConnection::WriteIfNotBlocked() { | 1202 void QuicConnection::WriteIfNotBlocked() { |
1182 if (!writer_->IsWriteBlocked()) { | 1203 if (!writer_->IsWriteBlocked()) { |
1183 OnCanWrite(); | 1204 OnCanWrite(); |
1184 } | 1205 } |
1185 } | 1206 } |
1186 | 1207 |
1187 bool QuicConnection::ProcessValidatedPacket() { | 1208 bool QuicConnection::ProcessValidatedPacket() { |
1188 if (address_migrating_) { | 1209 if ((!FLAGS_quic_allow_port_migration && peer_port_changed_) || |
1210 peer_ip_changed_ || self_ip_changed_ || self_port_changed_) { | |
1189 SendConnectionCloseWithDetails( | 1211 SendConnectionCloseWithDetails( |
1190 QUIC_ERROR_MIGRATING_ADDRESS, | 1212 QUIC_ERROR_MIGRATING_ADDRESS, |
1191 "Address migration is not yet a supported feature"); | 1213 "IP or port migration is not yet a supported feature"); |
wtc
2014/05/13 16:37:15
I think this error message is wrong. At least, it
Robbie Shade
2014/05/13 21:31:21
How about:
"Neither IP address migration, nor ser
wtc
2014/05/13 23:20:41
This sounds good. Did you mean "server port" or "s
Robbie Shade
2014/05/13 23:30:11
Yep "self port" is correct, although in practice "
ramant (doing other things)
2014/05/14 05:30:23
Done.
ramant (doing other things)
2014/05/14 05:30:23
Made this change in https://codereview.chromium.or
| |
1192 return false; | 1214 return false; |
1193 } | 1215 } |
1216 | |
1217 // Port migration is supported, do it now if port has changed. | |
1218 if (FLAGS_quic_allow_port_migration && | |
1219 peer_port_changed_) { | |
1220 DVLOG(1) << ENDPOINT << "Peer's port changed from " | |
1221 << peer_address_.port() << " to " << migrating_peer_port_ | |
1222 << ", migrating connection."; | |
1223 peer_address_ = IPEndPoint(peer_address_.address(), migrating_peer_port_); | |
1224 } | |
1225 | |
1194 time_of_last_received_packet_ = clock_->Now(); | 1226 time_of_last_received_packet_ = clock_->Now(); |
1195 DVLOG(1) << ENDPOINT << "time of last received packet: " | 1227 DVLOG(1) << ENDPOINT << "time of last received packet: " |
1196 << time_of_last_received_packet_.ToDebuggingValue(); | 1228 << time_of_last_received_packet_.ToDebuggingValue(); |
1197 | 1229 |
1198 if (is_server_ && encryption_level_ == ENCRYPTION_NONE && | 1230 if (is_server_ && encryption_level_ == ENCRYPTION_NONE && |
1199 last_size_ > options()->max_packet_length) { | 1231 last_size_ > options()->max_packet_length) { |
1200 options()->max_packet_length = last_size_; | 1232 options()->max_packet_length = last_size_; |
1201 } | 1233 } |
1202 return true; | 1234 return true; |
1203 } | 1235 } |
(...skipping 762 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1966 // If we changed the generator's batch state, restore original batch state. | 1998 // If we changed the generator's batch state, restore original batch state. |
1967 if (!already_in_batch_mode_) { | 1999 if (!already_in_batch_mode_) { |
1968 DVLOG(1) << "Leaving Batch Mode."; | 2000 DVLOG(1) << "Leaving Batch Mode."; |
1969 connection_->packet_generator_.FinishBatchOperations(); | 2001 connection_->packet_generator_.FinishBatchOperations(); |
1970 } | 2002 } |
1971 DCHECK_EQ(already_in_batch_mode_, | 2003 DCHECK_EQ(already_in_batch_mode_, |
1972 connection_->packet_generator_.InBatchMode()); | 2004 connection_->packet_generator_.InBatchMode()); |
1973 } | 2005 } |
1974 | 2006 |
1975 } // namespace net | 2007 } // namespace net |
OLD | NEW |