blob: c7860ef0607358f82f575e35b5fda40455a371d2 [file] [log] [blame]
/*
* 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/rtc_base/checks.h"
#include "webrtc/rtc_base/logging.h"
#include "webrtc/rtc_base/messagehandler.h"
#include "webrtc/rtc_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