Commit 84500e35 authored by Seth Hampson's avatar Seth Hampson Committed by Commit Bot

QUIC core library shim for streams.

This includes subclassing the QuicStream to be used by the RTCQuicStream
web API. It is a very basic implementation for the stream, and does not
include the functionality that will be needed for reaading and writing.

Bug: 874296
Change-Id: I25b69c06986cd68728b966ec28b67684ace5a87b
Reviewed-on: https://chromium-review.googlesource.com/1199765
Commit-Queue: Seth Hampson <shampson@chromium.org>
Reviewed-by: default avatarHenrik Boström <hbos@chromium.org>
Reviewed-by: default avatarHarald Alvestrand <hta@chromium.org>
Cr-Commit-Position: refs/heads/master@{#594894}
parent a25e93a7
...@@ -15,6 +15,9 @@ blink_modules_sources("peerconnection") { ...@@ -15,6 +15,9 @@ blink_modules_sources("peerconnection") {
"adapters/ice_transport_proxy.cc", "adapters/ice_transport_proxy.cc",
"adapters/ice_transport_proxy.h", "adapters/ice_transport_proxy.h",
"adapters/p2p_quic_packet_transport.h", "adapters/p2p_quic_packet_transport.h",
"adapters/p2p_quic_stream.h",
"adapters/p2p_quic_stream_impl.cc",
"adapters/p2p_quic_stream_impl.h",
"adapters/p2p_quic_transport.h", "adapters/p2p_quic_transport.h",
"adapters/p2p_quic_transport_factory.h", "adapters/p2p_quic_transport_factory.h",
"adapters/p2p_quic_transport_factory_impl.cc", "adapters/p2p_quic_transport_factory_impl.cc",
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_P2P_QUIC_STREAM_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_P2P_QUIC_STREAM_H_
namespace blink {
// The bidirectional QUIC stream object to be used by the RTCQuicStream Web
// API. See: https://w3c.github.io/webrtc-quic/#quicstream*
//
// Lifetime: The P2PQuicStream is owned by the P2PQuicTransport, and can be
// deleted after the stream is closed for reading and writing. This can happen
// in 3 ways: 1) OnRemoteReset has been fired. 2) Calling Reset(). 3) Both
// Finish() has been called and OnRemoteFinish has been fired.
class P2PQuicStream {
public:
// Receives callbacks for receiving RST_STREAM frames or a STREAM_FRAME with
// the FIN bit set. The Delegate should be subclassed by an object that can
// post the task to the main JS thread. The delegate's lifetime should outlive
// this P2PQuicStream.
class Delegate {
public:
virtual ~Delegate() {}
// Called when the stream receives a RST_STREAM frame from the remote side.
// This means the stream is closed and can no longer read or write, and is
// deleted by the quic::QuicSession.
virtual void OnRemoteReset() {}
// Called when the P2PQuicStream has consumed all incoming data from the
// remote side up to the FIN bit. Consuming means that the data is marked
// as consumed by quic::QuicStreamSequencer, but the data has not
// necessarily been read by the application. If the stream has already
// finished writing, then upon consuming the FIN bit the stream can no
// longer read or write and is deleted by the quic::QuicSession.
virtual void OnRemoteFinish() {}
};
// Sends a RST_STREAM frame to the remote side. This closes the P2PQuicStream
// for reading & writing and it will be deleted by the quic::QuicSession. When
// the remote side receives the RST_STREAM frame it will close the stream for
// reading and writing and send a RST_STREAM frame back. Calling Reset() will
// not trigger OnRemoteReset to be called locally when the RST_STREAM frame is
// received from the remote side, because the local stream is already closed.
virtual void Reset() = 0;
// Sends a stream frame with the FIN bit set, which notifies the remote side
// that this stream is done writing. The stream can no longer write after
// calling this function. If the stream has already received a FIN bit, this
// will close the stream for reading & writing and it will be deleted by the
// quic::QuicSession.
virtual void Finish() = 0;
// Sets the delegate object, which must outlive the P2PQuicStream.
virtual void SetDelegate(Delegate* delegate) = 0;
// TODO:(https://crbug.com/874296): Create functions for reading and writing,
// specifically for waitForReadable/waitForWriteable.
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_P2P_QUIC_STREAM_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_stream_impl.h"
#include "net/third_party/quic/core/quic_error_codes.h"
namespace blink {
P2PQuicStreamImpl::P2PQuicStreamImpl(quic::QuicStreamId id,
quic::QuicSession* session)
: quic::QuicStream(id, session, /*is_static=*/false) {}
P2PQuicStreamImpl::~P2PQuicStreamImpl() {}
void P2PQuicStreamImpl::OnDataAvailable() {
// We just drop the data by marking all data as immediately consumed.
sequencer()->MarkConsumed(sequencer()->ReadableBytes());
if (sequencer()->IsClosed()) {
// This means all data has been consumed up to the FIN bit.
OnFinRead();
}
}
void P2PQuicStreamImpl::Reset() {
if (rst_sent()) {
// No need to reset twice. This could have already been sent as consequence
// of receiving a RST_STREAM frame.
return;
}
quic::QuicStream::Reset(quic::QuicRstStreamErrorCode::QUIC_STREAM_CANCELLED);
}
void P2PQuicStreamImpl::Finish() {
// Should never call Finish twice.
DCHECK(!fin_sent());
quic::QuicStream::WriteOrBufferData("", /*fin=*/true, nullptr);
}
void P2PQuicStreamImpl::SetDelegate(P2PQuicStream::Delegate* delegate) {
delegate_ = delegate;
}
void P2PQuicStreamImpl::OnStreamReset(const quic::QuicRstStreamFrame& frame) {
// TODO(https://crbug.com/874296): If we get an incoming stream we need to
// make sure that the delegate is set before we have incoming data.
DCHECK(delegate_);
// Calling this on the QuicStream will ensure that the stream is closed
// for reading and writing and we send a RST frame to the remote side if
// we have not already.
quic::QuicStream::OnStreamReset(frame);
delegate_->OnRemoteReset();
}
void P2PQuicStreamImpl::OnFinRead() {
// TODO(https://crbug.com/874296): If we get an incoming stream we need to
// make sure that the delegate is set before we have incoming data.
DCHECK(delegate_);
// Calling this on the QuicStream ensures that the stream is closed
// for reading.
quic::QuicStream::OnFinRead();
delegate_->OnRemoteFinish();
}
} // namespace blink
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_P2P_QUIC_STREAM_IMPL_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_P2P_QUIC_STREAM_IMPL_H_
#include "net/third_party/quic/core/quic_session.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_stream.h"
namespace blink {
class MODULES_EXPORT P2PQuicStreamImpl final : public P2PQuicStream,
public quic::QuicStream {
public:
P2PQuicStreamImpl(quic::QuicStreamId id, quic::QuicSession* session);
~P2PQuicStreamImpl() override;
// QuicStream overrides.
//
// Right now this marks the data as consumed and drops it.
// TODO(https://crbug.com/874296): We need to update this function for
// reading and consuming data properly while the main JavaScript thread is
// busy. See:
// https://w3c.github.io/webrtc-quic/#dom-rtcquicstream-waitforreadable
void OnDataAvailable() override;
// P2PQuicStream overrides
void SetDelegate(P2PQuicStream::Delegate* delegate) override;
void Reset() override;
void Finish() override;
// quic::QuicStream overrides
//
// Called by the quic::QuicSession when receiving a RST_STREAM frame from the
// remote side. This closes the stream for reading & writing (if not already
// closed), and sends a RST_STREAM frame if one has not been sent yet.
void OnStreamReset(const quic::QuicRstStreamFrame& frame) override;
// Called when the stream has finished consumed data up to the FIN bit from
// the quic::QuicStreamSequencer. This will close the underlying QuicStream
// for reading. This can be called either by the P2PQuicStreamImpl when
// reading data, or by the quic::QuicStreamSequencer if we're done reading &
// receive a stream frame with the FIN bit.
void OnFinRead() override;
private:
using quic::QuicStream::Reset;
Delegate* delegate_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_P2P_QUIC_STREAM_IMPL_H_
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
namespace blink { namespace blink {
class P2PQuicStream;
// Used by the RTCQuicTransport Web API. This transport creates and manages // Used by the RTCQuicTransport Web API. This transport creates and manages
// streams, handles negotiation, state changes and errors. Every // streams, handles negotiation, state changes and errors. Every
// P2PQuicTransport function maps directly to a method in the RTCQuicTransport // P2PQuicTransport function maps directly to a method in the RTCQuicTransport
...@@ -35,8 +37,14 @@ class P2PQuicTransport { ...@@ -35,8 +37,14 @@ class P2PQuicTransport {
// Called when the crypto handshake has completed and fingerprints have been // Called when the crypto handshake has completed and fingerprints have been
// verified. // verified.
virtual void OnConnected() {} virtual void OnConnected() {}
// TODO(https://crbug.com/874296): Add OnStream once streams are
// implemented. // Called when an incoming stream is received from the remote side. This
// stream is owned by the P2PQuicTransport. Its lifetime is managed by the
// P2PQuicTransport, and can be deleted when:
// - The P2PQuicStream becomes closed for reading and writing.
// - Stop() is called.
// - The P2PQuicTransport is deleted.
virtual void OnStream(P2PQuicStream* stream) {}
}; };
virtual ~P2PQuicTransport() = default; virtual ~P2PQuicTransport() = default;
...@@ -53,10 +61,16 @@ class P2PQuicTransport { ...@@ -53,10 +61,16 @@ class P2PQuicTransport {
virtual void Start(std::vector<std::unique_ptr<rtc::SSLFingerprint>> virtual void Start(std::vector<std::unique_ptr<rtc::SSLFingerprint>>
remote_fingerprints) = 0; remote_fingerprints) = 0;
// Creates a new outgoing stream. This stream is owned by the
// P2PQuicTransport. Its lifetime is managed by the P2PQuicTransport,
// and can be deleted when:
// - The P2PQuicStream becomes closed for reading and writing.
// - Stop() is called.
// - The P2PQuicTransport is deleted.
virtual P2PQuicStream* CreateStream() = 0;
// TODO(https://crbug.com/874296): Consider adding a getter for the // TODO(https://crbug.com/874296): Consider adding a getter for the
// local fingerprints of the certificate(s) set in the constructor. // local fingerprints of the certificate(s) set in the constructor.
// TODO(https://crbug.com/874296): Add CreateStream once streams are
// implemented.
}; };
} // namespace blink } // namespace blink
......
...@@ -9,7 +9,9 @@ ...@@ -9,7 +9,9 @@
#include "third_party/webrtc/rtc_base/rtccertificate.h" #include "third_party/webrtc/rtc_base/rtccertificate.h"
namespace blink { namespace blink {
namespace { namespace {
// The P2PQuicPacketWriter is a private helper class that implements the // The P2PQuicPacketWriter is a private helper class that implements the
// QuicPacketWriter using a P2PQuicPacketTransport. This allows us to // QuicPacketWriter using a P2PQuicPacketTransport. This allows us to
// connect our own packet transport for writing into the QuicConnection. // connect our own packet transport for writing into the QuicConnection.
......
// Copyright 2018 The Chromium Authors. All rights reserved. // Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_impl.h" #include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_impl.h"
#include "net/quic/quic_chromium_connection_helper.h" #include "net/quic/quic_chromium_connection_helper.h"
...@@ -221,15 +220,34 @@ const quic::QuicCryptoStream* P2PQuicTransportImpl::GetCryptoStream() const { ...@@ -221,15 +220,34 @@ const quic::QuicCryptoStream* P2PQuicTransportImpl::GetCryptoStream() const {
return crypto_stream_.get(); return crypto_stream_.get();
} }
quic::QuicStream* P2PQuicTransportImpl::CreateOutgoingDynamicStream() { P2PQuicStreamImpl* P2PQuicTransportImpl::CreateStream() {
NOTIMPLEMENTED(); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
return nullptr; return CreateOutgoingDynamicStream();
}
P2PQuicStreamImpl* P2PQuicTransportImpl::CreateOutgoingDynamicStream() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
P2PQuicStreamImpl* stream = CreateStreamInternal(GetNextOutgoingStreamId());
ActivateStream(std::unique_ptr<P2PQuicStreamImpl>(stream));
return stream;
}
P2PQuicStreamImpl* P2PQuicTransportImpl::CreateIncomingDynamicStream(
quic::QuicStreamId id) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
P2PQuicStreamImpl* stream = CreateStreamInternal(id);
ActivateStream(std::unique_ptr<P2PQuicStreamImpl>(stream));
delegate_->OnStream(stream);
return stream;
} }
quic::QuicStream* P2PQuicTransportImpl::CreateIncomingDynamicStream( P2PQuicStreamImpl* P2PQuicTransportImpl::CreateStreamInternal(
quic::QuicStreamId id) { quic::QuicStreamId id) {
NOTIMPLEMENTED(); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
return nullptr; DCHECK(crypto_stream_);
DCHECK(IsEncryptionEstablished());
DCHECK(!IsClosed());
return new P2PQuicStreamImpl(id, this);
} }
void P2PQuicTransportImpl::InitializeCryptoStream() { void P2PQuicTransportImpl::InitializeCryptoStream() {
......
...@@ -16,11 +16,13 @@ ...@@ -16,11 +16,13 @@
#include "net/third_party/quic/tools/quic_simple_crypto_server_stream_helper.h" #include "net/third_party/quic/tools/quic_simple_crypto_server_stream_helper.h"
#include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_packet_transport.h" #include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_packet_transport.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_stream_impl.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport.h" #include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport.h"
#include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_factory.h" #include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_factory.h"
#include "third_party/webrtc/rtc_base/rtccertificate.h" #include "third_party/webrtc/rtc_base/rtccertificate.h"
namespace blink { namespace blink {
// The P2PQuicTransportImpl subclasses the quic::QuicSession in order to expose // The P2PQuicTransportImpl subclasses the quic::QuicSession in order to expose
// QUIC as a P2P transport. This specific subclass implements the crypto // QUIC as a P2P transport. This specific subclass implements the crypto
// handshake for a peer to peer connection, which requires verifying the remote // handshake for a peer to peer connection, which requires verifying the remote
...@@ -71,6 +73,9 @@ class MODULES_EXPORT P2PQuicTransportImpl final ...@@ -71,6 +73,9 @@ class MODULES_EXPORT P2PQuicTransportImpl final
void Start(std::vector<std::unique_ptr<rtc::SSLFingerprint>> void Start(std::vector<std::unique_ptr<rtc::SSLFingerprint>>
remote_fingerprints) override; remote_fingerprints) override;
// Creates an outgoing stream that is owned by the quic::QuicSession.
P2PQuicStreamImpl* CreateStream() override;
// P2PQuicPacketTransport::Delegate override. // P2PQuicPacketTransport::Delegate override.
void OnPacketDataReceived(const char* data, size_t data_len) override; void OnPacketDataReceived(const char* data, size_t data_len) override;
...@@ -81,6 +86,7 @@ class MODULES_EXPORT P2PQuicTransportImpl final ...@@ -81,6 +86,7 @@ class MODULES_EXPORT P2PQuicTransportImpl final
// for 0 RTT handshakes, which isn't relevant for our P2P handshake. // for 0 RTT handshakes, which isn't relevant for our P2P handshake.
void OnProofValid( void OnProofValid(
const quic::QuicCryptoClientConfig::CachedState& cached) override{}; const quic::QuicCryptoClientConfig::CachedState& cached) override{};
// Called when proof verification become available. // Called when proof verification become available.
void OnProofVerifyDetailsAvailable( void OnProofVerifyDetailsAvailable(
const quic::ProofVerifyDetails& verify_details) override{}; const quic::ProofVerifyDetails& verify_details) override{};
...@@ -98,12 +104,13 @@ class MODULES_EXPORT P2PQuicTransportImpl final ...@@ -98,12 +104,13 @@ class MODULES_EXPORT P2PQuicTransportImpl final
// Creates a new stream initiated from the remote side. The caller does not // Creates a new stream initiated from the remote side. The caller does not
// own the stream, so the stream is activated and ownership is moved to the // own the stream, so the stream is activated and ownership is moved to the
// quic::QuicSession. // quic::QuicSession.
quic::QuicStream* CreateIncomingDynamicStream(quic::QuicStreamId id) override; P2PQuicStreamImpl* CreateIncomingDynamicStream(
quic::QuicStreamId id) override;
// Creates a new outgoing stream. The caller does not own the // Creates a new outgoing stream. The caller does not own the
// stream, so the stream is activated and ownership is moved to the // stream, so the stream is activated and ownership is moved to the
// quic::QuicSession. // quic::QuicSession.
quic::QuicStream* CreateOutgoingDynamicStream() override; P2PQuicStreamImpl* CreateOutgoingDynamicStream() override;
void OnCryptoHandshakeEvent(CryptoHandshakeEvent event) override; void OnCryptoHandshakeEvent(CryptoHandshakeEvent event) override;
...@@ -130,6 +137,10 @@ class MODULES_EXPORT P2PQuicTransportImpl final ...@@ -130,6 +137,10 @@ class MODULES_EXPORT P2PQuicTransportImpl final
// both sides before communicating between endpoints (Start, Close, etc.). // both sides before communicating between endpoints (Start, Close, etc.).
void InitializeCryptoStream(); void InitializeCryptoStream();
// Creates a new stream. This helper function is used when we need to create
// a new incoming stream or outgoing stream.
P2PQuicStreamImpl* CreateStreamInternal(quic::QuicStreamId id);
// The server_config and client_config are used for setting up the crypto // The server_config and client_config are used for setting up the crypto
// connection. The ownership of these objects or the objects they own // connection. The ownership of these objects or the objects they own
// (quic::ProofSource, quic::ProofVerifier, etc.), are not passed on to the // (quic::ProofSource, quic::ProofVerifier, etc.), are not passed on to the
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment