The QuicWriteBlockedList needs to register outgoing QUIC streams so that when the QuicTransportChannel becomes unwritable and QUIC streams have buffered data, they can send data once the QuicTransportChannel becomes writable. Otherwise the QUIC streams will remain write blocked after the QuicTransportChannel is writable. BUG= Review-Url: https://codereview.webrtc.org/1888903002 Cr-Commit-Position: refs/heads/master@{#12573}
127 lines
4.3 KiB
C++
127 lines
4.3 KiB
C++
/*
|
|
* Copyright 2016 The WebRTC Project Authors. All rights reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
#include "webrtc/p2p/quic/quicsession.h"
|
|
|
|
#include <string>
|
|
#include <utility>
|
|
|
|
#include "webrtc/base/checks.h"
|
|
#include "webrtc/base/logging.h"
|
|
#include "webrtc/base/messagehandler.h"
|
|
#include "webrtc/base/messagequeue.h"
|
|
|
|
namespace cricket {
|
|
|
|
// Default priority for incoming QUIC streams.
|
|
// TODO(mikescarlett): Determine if this value is correct.
|
|
static const net::SpdyPriority kDefaultPriority = 3;
|
|
|
|
QuicSession::QuicSession(std::unique_ptr<net::QuicConnection> connection,
|
|
const net::QuicConfig& config)
|
|
: net::QuicSession(connection.release(), config) {}
|
|
|
|
QuicSession::~QuicSession() {}
|
|
|
|
void QuicSession::StartClientHandshake(
|
|
net::QuicCryptoClientStream* crypto_stream) {
|
|
SetCryptoStream(crypto_stream);
|
|
net::QuicSession::Initialize();
|
|
crypto_stream->CryptoConnect();
|
|
}
|
|
|
|
void QuicSession::StartServerHandshake(
|
|
net::QuicCryptoServerStream* crypto_stream) {
|
|
SetCryptoStream(crypto_stream);
|
|
net::QuicSession::Initialize();
|
|
}
|
|
|
|
void QuicSession::SetCryptoStream(net::QuicCryptoStream* crypto_stream) {
|
|
crypto_stream_.reset(crypto_stream);
|
|
}
|
|
|
|
bool QuicSession::ExportKeyingMaterial(base::StringPiece label,
|
|
base::StringPiece context,
|
|
size_t result_len,
|
|
std::string* result) {
|
|
return crypto_stream_->ExportKeyingMaterial(label, context, result_len,
|
|
result);
|
|
}
|
|
|
|
void QuicSession::OnCryptoHandshakeEvent(CryptoHandshakeEvent event) {
|
|
net::QuicSession::OnCryptoHandshakeEvent(event);
|
|
if (event == HANDSHAKE_CONFIRMED) {
|
|
LOG(LS_INFO) << "QuicSession handshake complete";
|
|
RTC_DCHECK(IsEncryptionEstablished());
|
|
RTC_DCHECK(IsCryptoHandshakeConfirmed());
|
|
|
|
SignalHandshakeComplete();
|
|
}
|
|
}
|
|
|
|
void QuicSession::CloseStream(net::QuicStreamId stream_id) {
|
|
if (IsClosedStream(stream_id)) {
|
|
// When CloseStream has been called recursively (via
|
|
// ReliableQuicStream::OnClose), the stream is already closed so return.
|
|
return;
|
|
}
|
|
write_blocked_streams()->UnregisterStream(stream_id);
|
|
net::QuicSession::CloseStream(stream_id);
|
|
}
|
|
|
|
ReliableQuicStream* QuicSession::CreateIncomingDynamicStream(
|
|
net::QuicStreamId id) {
|
|
ReliableQuicStream* stream = CreateDataStream(id, kDefaultPriority);
|
|
if (stream) {
|
|
SignalIncomingStream(stream);
|
|
}
|
|
return stream;
|
|
}
|
|
|
|
ReliableQuicStream* QuicSession::CreateOutgoingDynamicStream(
|
|
net::SpdyPriority priority) {
|
|
return CreateDataStream(GetNextOutgoingStreamId(), priority);
|
|
}
|
|
|
|
ReliableQuicStream* QuicSession::CreateDataStream(net::QuicStreamId id,
|
|
net::SpdyPriority priority) {
|
|
if (crypto_stream_ == nullptr || !crypto_stream_->encryption_established()) {
|
|
// Encryption not active so no stream created
|
|
return nullptr;
|
|
}
|
|
ReliableQuicStream* stream = new ReliableQuicStream(id, this);
|
|
if (stream) {
|
|
// Make QuicSession take ownership of the stream.
|
|
ActivateStream(stream);
|
|
// Register the stream to the QuicWriteBlockedList. |priority| is clamped
|
|
// between 0 and 7, with 0 being the highest priority and 7 the lowest
|
|
// priority.
|
|
write_blocked_streams()->RegisterStream(stream->id(), priority);
|
|
}
|
|
return stream;
|
|
}
|
|
|
|
void QuicSession::OnConnectionClosed(net::QuicErrorCode error,
|
|
const std::string& error_details,
|
|
net::ConnectionCloseSource source) {
|
|
net::QuicSession::OnConnectionClosed(error, error_details, source);
|
|
SignalConnectionClosed(error,
|
|
source == net::ConnectionCloseSource::FROM_PEER);
|
|
}
|
|
|
|
bool QuicSession::OnReadPacket(const char* data, size_t data_len) {
|
|
net::QuicReceivedPacket packet(data, data_len, clock_.Now());
|
|
ProcessUdpPacket(connection()->self_address(), connection()->peer_address(),
|
|
packet);
|
|
return true;
|
|
}
|
|
|
|
} // namespace cricket
|