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 |