reliable_quic_stream.cc revision d0247b1b59f9c528cb6df88b4f2b9afaf80d181e
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/quic/reliable_quic_stream.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/quic/quic_session.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/quic/quic_spdy_decompressor.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/write_blocked_list.h" 107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::StringPiece; 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::min; 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is somewhat arbitrary. It's possible, but unlikely, we will either fail 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to set a priority client-side, or cancel a stream before stripping the 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// priority from the wire server-side. In either case, start out with a 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// priority in the middle. 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)QuicPriority kDefaultPriority = 3; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Appends bytes from data into partial_data_buffer. Once partial_data_buffer 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// reaches 4 bytes, copies the data into 'result' and clears 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// partial_data_buffer. 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the number of bytes consumed. 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint32 StripUint32(const char* data, uint32 data_len, 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string* partial_data_buffer, 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32* result) { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GT(4u, partial_data_buffer->length()); 327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch size_t missing_size = 4 - partial_data_buffer->length(); 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data_len < missing_size) { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringPiece(data, data_len).AppendToString(partial_data_buffer); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return data_len; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringPiece(data, missing_size).AppendToString(partial_data_buffer); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(4u, partial_data_buffer->length()); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(result, partial_data_buffer->data(), 4); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) partial_data_buffer->clear(); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return missing_size; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ReliableQuicStream::ReliableQuicStream(QuicStreamId id, 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuicSession* session) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : sequencer_(this), 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id_(id), 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_(session), 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) visitor_(NULL), 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stream_bytes_read_(0), 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stream_bytes_written_(0), 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) headers_decompressed_(false), 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) priority_(kDefaultPriority), 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) headers_id_(0), 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decompression_failed_(false), 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stream_error_(QUIC_STREAM_NO_ERROR), 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_error_(QUIC_NO_ERROR), 604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) read_side_closed_(false), 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_side_closed_(false), 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) priority_parsed_(false), 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fin_buffered_(false), 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fin_sent_(false) { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ReliableQuicStream::~ReliableQuicStream() { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ReliableQuicStream::WillAcceptStreamFrame( 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const QuicStreamFrame& frame) const { 724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (read_side_closed_) { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (frame.stream_id != id_) { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Error!"; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sequencer_.WillAcceptStreamFrame(frame); 804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ReliableQuicStream::OnStreamFrame(const QuicStreamFrame& frame) { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(frame.stream_id, id_); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (read_side_closed_) { 854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DLOG(INFO) << "Ignoring frame " << frame.stream_id; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't want to be reading: blackhole the data. 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: This count include duplicate data received. 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stream_bytes_read_ += frame.data.length(); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool accepted = sequencer_.OnStreamFrame(frame); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return accepted; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ReliableQuicStream::OnStreamReset(QuicRstStreamErrorCode error) { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stream_error_ = error; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TerminateFromPeer(false); // Full close. 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ReliableQuicStream::ConnectionClose(QuicErrorCode error, bool from_peer) { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (read_side_closed_ && write_side_closed_) { 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error != QUIC_NO_ERROR) { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stream_error_ = QUIC_STREAM_CONNECTION_ERROR; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_error_ = error; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (from_peer) { 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TerminateFromPeer(false); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseWriteSide(); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseReadSide(); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ReliableQuicStream::TerminateFromPeer(bool half_close) { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!half_close) { 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseWriteSide(); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseReadSide(); 124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ReliableQuicStream::Close(QuicRstStreamErrorCode error) { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stream_error_ = error; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error != QUIC_STREAM_NO_ERROR) { 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sending a RstStream results in calling CloseStream. 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session()->SendRstStream(id(), error); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_->CloseStream(id()); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t ReliableQuicStream::Readv(const struct iovec* iov, size_t iov_len) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (headers_decompressed_ && decompressed_headers_.empty()) { 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sequencer_.Readv(iov, iov_len); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t bytes_consumed = 0; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t iov_index = 0; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (iov_index < iov_len && 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decompressed_headers_.length() > bytes_consumed) { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t bytes_to_read = min(iov[iov_index].iov_len, 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decompressed_headers_.length() - bytes_consumed); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* iov_ptr = static_cast<char*>(iov[iov_index].iov_base); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(iov_ptr, 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decompressed_headers_.data() + bytes_consumed, bytes_to_read); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_consumed += bytes_to_read; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++iov_index; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decompressed_headers_.erase(0, bytes_consumed); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bytes_consumed; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ReliableQuicStream::GetReadableRegions(iovec* iov, size_t iov_len) { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (headers_decompressed_ && decompressed_headers_.empty()) { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sequencer_.GetReadableRegions(iov, iov_len); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (iov_len == 0) { 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iov[0].iov_base = static_cast<void*>( 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const_cast<char*>(decompressed_headers_.data())); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iov[0].iov_len = decompressed_headers_.length(); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ReliableQuicStream::IsHalfClosed() const { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!headers_decompressed_ || !decompressed_headers_.empty()) { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sequencer_.IsHalfClosed(); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ReliableQuicStream::HasBytesToRead() const { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !decompressed_headers_.empty() || sequencer_.HasBytesToRead(); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const IPEndPoint& ReliableQuicStream::GetPeerAddress() const { 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return session_->peer_address(); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)QuicSpdyCompressor* ReliableQuicStream::compressor() { 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return session_->compressor(); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ReliableQuicStream::GetSSLInfo(SSLInfo* ssl_info) { 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return session_->GetSSLInfo(ssl_info); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)QuicConsumedData ReliableQuicStream::WriteData(StringPiece data, bool fin) { 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(data.size() > 0 || fin); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WriteOrBuffer(data, fin); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ReliableQuicStream::set_priority(QuicPriority priority) { 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(0u, stream_bytes_written_); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) priority_ = priority; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)QuicConsumedData ReliableQuicStream::WriteOrBuffer(StringPiece data, bool fin) { 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!fin_buffered_); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuicConsumedData consumed_data(0, false); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fin_buffered_ = fin; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (queued_data_.empty()) { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) consumed_data = WriteDataInternal(string(data.data(), data.length()), fin); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LE(consumed_data.bytes_consumed, data.length()); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If there's unconsumed data or an unconsumed fin, queue it. 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (consumed_data.bytes_consumed < data.length() || 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (fin && !consumed_data.fin_consumed)) { 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) queued_data_.push_back( 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string(data.data() + consumed_data.bytes_consumed, 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.length() - consumed_data.bytes_consumed)); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return QuicConsumedData(data.size(), true); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ReliableQuicStream::OnCanWrite() { 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool fin = false; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!queued_data_.empty()) { 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& data = queued_data_.front(); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (queued_data_.size() == 1 && fin_buffered_) { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fin = true; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuicConsumedData consumed_data = WriteDataInternal(data, fin); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (consumed_data.bytes_consumed == data.size() && 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fin == consumed_data.fin_consumed) { 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) queued_data_.pop_front(); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) queued_data_.front().erase(0, consumed_data.bytes_consumed); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)QuicConsumedData ReliableQuicStream::WriteDataInternal( 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringPiece data, bool fin) { 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct iovec iov = {const_cast<char*>(data.data()), 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<size_t>(data.size())}; 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WritevDataInternal(&iov, 1, fin); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 250eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochQuicConsumedData ReliableQuicStream::WritevDataInternal(const struct iovec* iov, 251eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int iov_count, 252eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool fin) { 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (write_side_closed_) { 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG(ERROR) << "Attempt to write when the write side is closed"; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return QuicConsumedData(0, false); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t write_length = 0u; 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < iov_count; ++i) { 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_length += iov[i].iov_len; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuicConsumedData consumed_data = 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session()->WritevData(id(), iov, iov_count, stream_bytes_written_, fin); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stream_bytes_written_ += consumed_data.bytes_consumed; 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (consumed_data.bytes_consumed == write_length) { 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (fin && consumed_data.fin_consumed) { 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fin_sent_ = true; 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseWriteSide(); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (fin && !consumed_data.fin_consumed) { 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_->MarkWriteBlocked(id(), EffectivePriority()); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_->MarkWriteBlocked(id(), EffectivePriority()); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return consumed_data; 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)QuicPriority ReliableQuicStream::EffectivePriority() const { 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return priority(); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ReliableQuicStream::CloseReadSide() { 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (read_side_closed_) { 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DLOG(INFO) << "Done reading from stream " << id(); 287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) read_side_closed_ = true; 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (write_side_closed_) { 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG(INFO) << "Closing stream: " << id(); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_->CloseStream(id()); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint32 ReliableQuicStream::ProcessRawData(const char* data, uint32 data_len) { 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(0u, data_len); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (id() == kCryptoStreamId) { 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The crypto stream does not use compression. 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ProcessData(data, data_len); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 total_bytes_consumed = 0; 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (headers_id_ == 0u) { 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_bytes_consumed += StripPriorityAndHeaderId(data, data_len); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data += total_bytes_consumed; 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_len -= total_bytes_consumed; 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data_len == 0 || !session_->connection()->connected()) { 308eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return total_bytes_consumed; 309eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 310eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(0u, headers_id_); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Once the headers are finished, we simply pass the data through. 31490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (headers_decompressed_) { 31590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Some buffered header data remains. 31690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!decompressed_headers_.empty()) { 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProcessHeaderData(); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (decompressed_headers_.empty()) { 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Delegating procesing to ProcessData"; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_bytes_consumed += ProcessData(data, data_len); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return total_bytes_consumed; 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuicHeaderId current_header_id = 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_->decompressor()->current_header_id(); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that this header id looks sane. 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (headers_id_ < current_header_id || 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) headers_id_ > kMaxHeaderIdDelta + current_header_id) { 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Invalid headers for stream: " << id() 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " header_id: " << headers_id_ 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " current_header_id: " << current_header_id; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_->connection()->SendConnectionClose(QUIC_INVALID_HEADER_ID); 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return total_bytes_consumed; 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we are head-of-line blocked on decompression, then back up. 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (current_header_id != headers_id_) { 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_->MarkDecompressionBlocked(headers_id_, id()); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Unable to decompress header data for stream: " << id() 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " header_id: " << headers_id_; 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return total_bytes_consumed; 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Decompressed data will be delivered to decompressed_headers_. 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t bytes_consumed = session_->decompressor()->DecompressData( 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringPiece(data, data_len), this); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(0u, bytes_consumed); 3507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (bytes_consumed > data_len) { 3517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(false) << "DecompressData returned illegal value"; 3527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch OnDecompressionError(); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return total_bytes_consumed; 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_bytes_consumed += bytes_consumed; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data += bytes_consumed; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_len -= bytes_consumed; 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (decompression_failed_) { 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The session will have been closed in OnDecompressionError. 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return total_bytes_consumed; 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Headers are complete if the decompressor has moved on to the 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // next stream. 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) headers_decompressed_ = 367eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch session_->decompressor()->current_header_id() != headers_id_; 368eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!headers_decompressed_) { 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(0u, data_len); 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProcessHeaderData(); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!headers_decompressed_ || !decompressed_headers_.empty()) { 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return total_bytes_consumed; 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We have processed all of the decompressed data but we might 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // have some more raw data to process. 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data_len > 0) { 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_bytes_consumed += ProcessData(data, data_len); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The sequencer will push any additional buffered frames if this data 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // has been completely consumed. 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return total_bytes_consumed; 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint32 ReliableQuicStream::ProcessHeaderData() { 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (decompressed_headers_.empty()) { 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t bytes_processed = ProcessData(decompressed_headers_.data(), 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decompressed_headers_.length()); 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bytes_processed == decompressed_headers_.length()) { 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decompressed_headers_.clear(); 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decompressed_headers_ = decompressed_headers_.erase(0, bytes_processed); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bytes_processed; 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ReliableQuicStream::OnDecompressorAvailable() { 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(headers_id_, 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_->decompressor()->current_header_id()); 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!headers_decompressed_); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!decompression_failed_); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(0u, decompressed_headers_.length()); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!headers_decompressed_) { 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct iovec iovec; 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sequencer_.GetReadableRegions(&iovec, 1) == 0) { 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t bytes_consumed = session_->decompressor()->DecompressData( 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringPiece(static_cast<char*>(iovec.iov_base), 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iovec.iov_len), 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LE(bytes_consumed, iovec.iov_len); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (decompression_failed_) { 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sequencer_.MarkConsumed(bytes_consumed); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) headers_decompressed_ = 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_->decompressor()->current_header_id() != headers_id_; 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Either the headers are complete, or the all data as been consumed. 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProcessHeaderData(); // Unprocessed headers remain in decompressed_headers_. 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsHalfClosed()) { 4347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch TerminateFromPeer(true); 4357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } else if (headers_decompressed_ && decompressed_headers_.empty()) { 4367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sequencer_.FlushBufferedFrames(); 4378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ReliableQuicStream::OnDecompressedData(StringPiece data) { 4417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch data.AppendToString(&decompressed_headers_); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ReliableQuicStream::OnDecompressionError() { 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!decompression_failed_); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decompression_failed_ = true; 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_->connection()->SendConnectionClose(QUIC_DECOMPRESSION_FAILURE); 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ReliableQuicStream::CloseWriteSide() { 4533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (write_side_closed_) { 4543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG(INFO) << "Done writing to stream " << id(); 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_side_closed_ = true; 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (read_side_closed_) { 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG(INFO) << "Closing stream: " << id(); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_->CloseStream(id()); 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ReliableQuicStream::HasBufferedData() { 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !queued_data_.empty(); 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ReliableQuicStream::OnClose() { 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseReadSide(); 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseWriteSide(); 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (visitor_) { 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Visitor* visitor = visitor_; 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Calling Visitor::OnClose() may result the destruction of the visitor, 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so we need to ensure we don't call it again. 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) visitor_ = NULL; 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) visitor->OnClose(this); 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint32 ReliableQuicStream::StripPriorityAndHeaderId( 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* data, uint32 data_len) { 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 total_bytes_parsed = 0; 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!priority_parsed_ && 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_->connection()->version() >= QUIC_VERSION_9 && 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_->connection()->is_server()) { 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QuicPriority temporary_priority = priority_; 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_bytes_parsed = StripUint32( 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data, data_len, &headers_id_and_priority_buffer_, &temporary_priority); 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (total_bytes_parsed > 0 && headers_id_and_priority_buffer_.size() == 0) { 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) priority_parsed_ = true; 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Spdy priorities are inverted, so the highest numerical value is the 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // lowest legal priority. 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (temporary_priority > static_cast<QuicPriority>(kLowestPriority)) { 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_->connection()->SendConnectionClose(QUIC_INVALID_PRIORITY); 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) priority_ = temporary_priority; 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data += total_bytes_parsed; 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_len -= total_bytes_parsed; 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data_len > 0 && headers_id_ == 0u) { 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The headers ID has not yet been read. Strip it from the beginning of 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the data stream. 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) total_bytes_parsed += StripUint32( 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data, data_len, &headers_id_and_priority_buffer_, &headers_id_); 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return total_bytes_parsed; 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)