| 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 749 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 760 if (delay.IsZero()) { | 760 if (delay.IsZero()) { |
| 761 send_alarm_->Cancel(); | 761 send_alarm_->Cancel(); |
| 762 WriteIfNotBlocked(); | 762 WriteIfNotBlocked(); |
| 763 } else if (!delay.IsInfinite()) { | 763 } else if (!delay.IsInfinite()) { |
| 764 send_alarm_->Cancel(); | 764 send_alarm_->Cancel(); |
| 765 send_alarm_->Set(time_of_last_received_packet_.Add(delay)); | 765 send_alarm_->Set(time_of_last_received_packet_.Add(delay)); |
| 766 } | 766 } |
| 767 } | 767 } |
| 768 | 768 |
| 769 void QuicConnection::SendVersionNegotiationPacket() { | 769 void QuicConnection::SendVersionNegotiationPacket() { |
| 770 // TODO(alyssar): implement zero server state negotiation. |
| 771 pending_version_negotiation_packet_ = true; |
| 772 if (writer_->IsWriteBlocked()) { |
| 773 visitor_->OnWriteBlocked(); |
| 774 return; |
| 775 } |
| 770 scoped_ptr<QuicEncryptedPacket> version_packet( | 776 scoped_ptr<QuicEncryptedPacket> version_packet( |
| 771 packet_creator_.SerializeVersionNegotiationPacket( | 777 packet_creator_.SerializeVersionNegotiationPacket( |
| 772 framer_.supported_versions())); | 778 framer_.supported_versions())); |
| 773 // TODO(satyamshekhar): implement zero server state negotiation. | 779 WriteResult result = writer_->WritePacket( |
| 774 WriteResult result = | 780 version_packet->data(), version_packet->length(), |
| 775 writer_->WritePacket(version_packet->data(), version_packet->length(), | 781 self_address().address(), peer_address(), this); |
| 776 self_address().address(), peer_address(), this); | 782 |
| 777 if (result.status == WRITE_STATUS_OK || | |
| 778 (result.status == WRITE_STATUS_BLOCKED && | |
| 779 writer_->IsWriteBlockedDataBuffered())) { | |
| 780 pending_version_negotiation_packet_ = false; | |
| 781 return; | |
| 782 } | |
| 783 if (result.status == WRITE_STATUS_ERROR) { | 783 if (result.status == WRITE_STATUS_ERROR) { |
| 784 // We can't send an error as the socket is presumably borked. | 784 // We can't send an error as the socket is presumably borked. |
| 785 CloseConnection(QUIC_PACKET_WRITE_ERROR, false); | 785 CloseConnection(QUIC_PACKET_WRITE_ERROR, false); |
| 786 return; |
| 786 } | 787 } |
| 787 pending_version_negotiation_packet_ = true; | 788 if (result.status == WRITE_STATUS_BLOCKED) { |
| 789 visitor_->OnWriteBlocked(); |
| 790 if (writer_->IsWriteBlockedDataBuffered()) { |
| 791 pending_version_negotiation_packet_ = false; |
| 792 } |
| 793 return; |
| 794 } |
| 795 |
| 796 pending_version_negotiation_packet_ = false; |
| 788 } | 797 } |
| 789 | 798 |
| 790 QuicConsumedData QuicConnection::SendStreamData( | 799 QuicConsumedData QuicConnection::SendStreamData( |
| 791 QuicStreamId id, | 800 QuicStreamId id, |
| 792 const IOVector& data, | 801 const IOVector& data, |
| 793 QuicStreamOffset offset, | 802 QuicStreamOffset offset, |
| 794 bool fin, | 803 bool fin, |
| 795 QuicAckNotifier::DelegateInterface* delegate) { | 804 QuicAckNotifier::DelegateInterface* delegate) { |
| 796 if (!fin && data.Empty()) { | 805 if (!fin && data.Empty()) { |
| 797 LOG(DFATAL) << "Attempt to send empty stream frame"; | 806 LOG(DFATAL) << "Attempt to send empty stream frame"; |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1024 return true; | 1033 return true; |
| 1025 } | 1034 } |
| 1026 | 1035 |
| 1027 return CanWrite(transmission_type, retransmittable, handshake); | 1036 return CanWrite(transmission_type, retransmittable, handshake); |
| 1028 } | 1037 } |
| 1029 | 1038 |
| 1030 bool QuicConnection::CanWrite(TransmissionType transmission_type, | 1039 bool QuicConnection::CanWrite(TransmissionType transmission_type, |
| 1031 HasRetransmittableData retransmittable, | 1040 HasRetransmittableData retransmittable, |
| 1032 IsHandshake handshake) { | 1041 IsHandshake handshake) { |
| 1033 if (writer_->IsWriteBlocked()) { | 1042 if (writer_->IsWriteBlocked()) { |
| 1043 visitor_->OnWriteBlocked(); |
| 1034 return false; | 1044 return false; |
| 1035 } | 1045 } |
| 1036 | 1046 |
| 1037 // TODO(rch): consider removing this check so that if an ACK comes in | 1047 // TODO(rch): consider removing this check so that if an ACK comes in |
| 1038 // before the alarm goes it, we might be able send out a packet. | 1048 // before the alarm goes it, we might be able send out a packet. |
| 1039 // This check assumes that if the send alarm is set, it applies equally to all | 1049 // This check assumes that if the send alarm is set, it applies equally to all |
| 1040 // types of transmissions. | 1050 // types of transmissions. |
| 1041 if (send_alarm_->IsSet()) { | 1051 if (send_alarm_->IsSet()) { |
| 1042 DVLOG(1) << "Send alarm set. Not sending."; | 1052 DVLOG(1) << "Send alarm set. Not sending."; |
| 1043 return false; | 1053 return false; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1104 // deleted at the end of this call. | 1114 // deleted at the end of this call. |
| 1105 scoped_ptr<QuicEncryptedPacket> encrypted_deleter; | 1115 scoped_ptr<QuicEncryptedPacket> encrypted_deleter; |
| 1106 if (forced == NO_FORCE) { | 1116 if (forced == NO_FORCE) { |
| 1107 encrypted_deleter.reset(encrypted); | 1117 encrypted_deleter.reset(encrypted); |
| 1108 } else { // forced == FORCE | 1118 } else { // forced == FORCE |
| 1109 DCHECK(connection_close_packet_.get() == NULL); | 1119 DCHECK(connection_close_packet_.get() == NULL); |
| 1110 connection_close_packet_.reset(encrypted); | 1120 connection_close_packet_.reset(encrypted); |
| 1111 // This assures we won't try to write *forced* packets when blocked. | 1121 // This assures we won't try to write *forced* packets when blocked. |
| 1112 // Return true to stop processing. | 1122 // Return true to stop processing. |
| 1113 if (writer_->IsWriteBlocked()) { | 1123 if (writer_->IsWriteBlocked()) { |
| 1124 visitor_->OnWriteBlocked(); |
| 1114 return true; | 1125 return true; |
| 1115 } | 1126 } |
| 1116 } | 1127 } |
| 1117 | 1128 |
| 1118 if (encrypted->length() > options()->max_packet_length) { | 1129 if (encrypted->length() > options()->max_packet_length) { |
| 1119 LOG(DFATAL) << "Writing an encrypted packet larger than max_packet_length:" | 1130 LOG(DFATAL) << "Writing an encrypted packet larger than max_packet_length:" |
| 1120 << options()->max_packet_length << " encrypted length: " | 1131 << options()->max_packet_length << " encrypted length: " |
| 1121 << encrypted->length(); | 1132 << encrypted->length(); |
| 1122 } | 1133 } |
| 1123 DVLOG(1) << ENDPOINT << "Sending packet number " << sequence_number | 1134 DVLOG(1) << ENDPOINT << "Sending packet number " << sequence_number |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1147 writer_->WritePacket(encrypted->data(), encrypted->length(), | 1158 writer_->WritePacket(encrypted->data(), encrypted->length(), |
| 1148 self_address().address(), peer_address(), this); | 1159 self_address().address(), peer_address(), this); |
| 1149 if (result.error_code == ERR_IO_PENDING) { | 1160 if (result.error_code == ERR_IO_PENDING) { |
| 1150 DCHECK_EQ(WRITE_STATUS_BLOCKED, result.status); | 1161 DCHECK_EQ(WRITE_STATUS_BLOCKED, result.status); |
| 1151 } | 1162 } |
| 1152 if (debug_visitor_) { | 1163 if (debug_visitor_) { |
| 1153 // Pass the write result to the visitor. | 1164 // Pass the write result to the visitor. |
| 1154 debug_visitor_->OnPacketSent(sequence_number, level, *encrypted, result); | 1165 debug_visitor_->OnPacketSent(sequence_number, level, *encrypted, result); |
| 1155 } | 1166 } |
| 1156 if (result.status == WRITE_STATUS_BLOCKED) { | 1167 if (result.status == WRITE_STATUS_BLOCKED) { |
| 1168 visitor_->OnWriteBlocked(); |
| 1157 // If the socket buffers the the data, then the packet should not | 1169 // If the socket buffers the the data, then the packet should not |
| 1158 // be queued and sent again, which would result in an unnecessary | 1170 // be queued and sent again, which would result in an unnecessary |
| 1159 // duplicate packet being sent. The helper must call OnPacketSent | 1171 // duplicate packet being sent. The helper must call OnPacketSent |
| 1160 // when the packet is actually sent. | 1172 // when the packet is actually sent. |
| 1161 if (writer_->IsWriteBlockedDataBuffered()) { | 1173 if (writer_->IsWriteBlockedDataBuffered()) { |
| 1162 return true; | 1174 return true; |
| 1163 } | 1175 } |
| 1164 pending_write_.reset(); | 1176 pending_write_.reset(); |
| 1165 return false; | 1177 return false; |
| 1166 } | 1178 } |
| (...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1665 // If we changed the generator's batch state, restore original batch state. | 1677 // If we changed the generator's batch state, restore original batch state. |
| 1666 if (!already_in_batch_mode_) { | 1678 if (!already_in_batch_mode_) { |
| 1667 DVLOG(1) << "Leaving Batch Mode."; | 1679 DVLOG(1) << "Leaving Batch Mode."; |
| 1668 connection_->packet_generator_.FinishBatchOperations(); | 1680 connection_->packet_generator_.FinishBatchOperations(); |
| 1669 } | 1681 } |
| 1670 DCHECK_EQ(already_in_batch_mode_, | 1682 DCHECK_EQ(already_in_batch_mode_, |
| 1671 connection_->packet_generator_.InBatchMode()); | 1683 connection_->packet_generator_.InBatchMode()); |
| 1672 } | 1684 } |
| 1673 | 1685 |
| 1674 } // namespace net | 1686 } // namespace net |
| OLD | NEW |