Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(349)

Unified Diff: net/quic/quartc/quartc_session.cc

Issue 2324833004: Define Stable API for WebRTC/Quartc (Closed)
Patch Set: Fix the memory leak. Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/quic/quartc/quartc_session.cc
diff --git a/net/quic/quartc/quartc_session.cc b/net/quic/quartc/quartc_session.cc
new file mode 100644
index 0000000000000000000000000000000000000000..518bb72cff8bd55290664974bc2d5e9c71927bea
--- /dev/null
+++ b/net/quic/quartc/quartc_session.cc
@@ -0,0 +1,291 @@
+// Copyright (c) 2016 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 "net/quic/quartc/quartc_session.h"
+
+#include "base/rand_util.h"
+
+namespace {
+
+// Default priority for incoming QUIC streams.
+// TODO(zhihuang): Determine if this value is correct.
+static const net::SpdyPriority kDefaultPriority = 3;
+
+// Arbitrary server port number for net::QuicCryptoClientConfig.
+const int kQuicServerPort = 0;
+
+// Length of HKDF input keying material, equal to its number of bytes.
+// https://tools.ietf.org/html/rfc5869#section-2.2.
+// TODO(zhihuang): Verify that input keying material length is correct.
+const size_t kInputKeyingMaterialLength = 32;
+
+// Used by QuicCryptoServerConfig to provide dummy proof credentials.
+// TODO(zhihuang): Remove when secure P2P QUIC handshake is possible.
+class DummyProofSource : public net::ProofSource {
+ public:
+ DummyProofSource() {}
+ ~DummyProofSource() override {}
+
+ // ProofSource override.
+ bool GetProof(const net::IPAddress& server_ip,
+ const std::string& hostname,
+ const std::string& server_config,
+ net::QuicVersion quic_version,
+ base::StringPiece chlo_hash,
+ scoped_refptr<net::ProofSource::Chain>* out_chain,
+ std::string* out_signature,
+ std::string* out_leaf_cert_sct) override {
+ std::vector<std::string> certs;
+ certs.push_back("Dummy cert");
+ *out_chain = new ProofSource::Chain(certs);
+ *out_signature = "Dummy signature";
+ *out_leaf_cert_sct = "Dummy timestamp";
+ return true;
+ }
+
+ void GetProof(const net::IPAddress& server_ip,
+ const std::string& hostname,
+ const std::string& server_config,
+ net::QuicVersion quic_version,
+ base::StringPiece chlo_hash,
+ std::unique_ptr<Callback> callback) override {}
+};
+
+// Used by QuicCryptoClientConfig to ignore the peer's credentials
+// and establish an insecure QUIC connection.
+// TODO(zhihuang): Remove when secure P2P QUIC handshake is possible.
+class InsecureProofVerifier : public net::ProofVerifier {
+ public:
+ InsecureProofVerifier() {}
+ ~InsecureProofVerifier() override {}
+
+ // ProofVerifier override.
+ net::QuicAsyncStatus VerifyProof(
+ const std::string& hostname,
+ const uint16_t port,
+ const std::string& server_config,
+ net::QuicVersion quic_version,
+ base::StringPiece chlo_hash,
+ const std::vector<std::string>& certs,
+ const std::string& cert_sct,
+ const std::string& signature,
+ const net::ProofVerifyContext* context,
+ std::string* error_details,
+ std::unique_ptr<net::ProofVerifyDetails>* verify_details,
+ std::unique_ptr<net::ProofVerifierCallback> callback) override {
+ return net::QUIC_SUCCESS;
+ }
+
+ net::QuicAsyncStatus VerifyCertChain(
+ const std::string& hostname,
+ const std::vector<std::string>& certs,
+ const net::ProofVerifyContext* context,
+ std::string* error_details,
+ std::unique_ptr<net::ProofVerifyDetails>* details,
+ std::unique_ptr<net::ProofVerifierCallback> callback) override {
+ return net::QUIC_SUCCESS;
+ }
+};
+}
+
+namespace net {
+
+QuicConnectionId QuartcCryptoServerStreamHelper::GenerateConnectionIdForReject(
+ QuicConnectionId connection_id) const {
+ return 0;
+}
+
+bool QuartcCryptoServerStreamHelper::CanAcceptClientHello(
+ const CryptoHandshakeMessage& message,
+ const IPEndPoint& self_address,
+ std::string* error_details) const {
+ return true;
+}
+
+QuartcSession::QuartcSession(std::unique_ptr<QuicConnection> connection,
+ const QuicConfig& config,
+ const std::string& unique_remote_server_id,
+ Perspective perspective,
+ QuicConnectionHelperInterface* helper)
+ : QuicSession(connection.get(), config),
+ unique_remote_server_id_(unique_remote_server_id),
+ perspective_(perspective),
+ connection_(std::move(connection)),
+ helper_(helper) {
+ // Initialization with default crypto configuration.
+ if (perspective_ == Perspective::IS_CLIENT) {
+ std::unique_ptr<ProofVerifier> proof_verifier(new InsecureProofVerifier);
+ quic_crypto_client_config_.reset(
+ new QuicCryptoClientConfig(std::move(proof_verifier)));
+ } else {
+ std::unique_ptr<ProofSource> proof_source(new DummyProofSource);
+ std::string source_address_token_secret =
+ base::RandBytesAsString(kInputKeyingMaterialLength);
+ quic_crypto_server_config_.reset(new QuicCryptoServerConfig(
+ source_address_token_secret, helper_->GetRandomGenerator(),
+ std::move(proof_source)));
+ // Provide server with serialized config string to prove ownership.
+ QuicCryptoServerConfig::ConfigOptions options;
+ // The |message| is used to handle the return value of AddDefaultConfig
+ // which is raw pointer of the CryptoHandshakeMessage.
+ std::unique_ptr<CryptoHandshakeMessage> message(
+ quic_crypto_server_config_->AddDefaultConfig(
+ helper_->GetRandomGenerator(), helper_->GetClock(), options));
+ }
+}
+
+QuartcSession::~QuartcSession() {}
+
+QuicCryptoStream* QuartcSession::GetCryptoStream() {
+ return crypto_stream_.get();
+}
+
+QuartcStream* QuartcSession::CreateOutgoingDynamicStream(
+ SpdyPriority priority) {
+ return CreateDataStream(GetNextOutgoingStreamId(), priority);
+}
+
+void QuartcSession::OnCryptoHandshakeEvent(CryptoHandshakeEvent event) {
+ QuicSession::OnCryptoHandshakeEvent(event);
+ if (event == HANDSHAKE_CONFIRMED) {
+ DCHECK(IsEncryptionEstablished());
+ DCHECK(IsCryptoHandshakeConfirmed());
+
+ DCHECK(session_delegate_);
+ session_delegate_->OnCryptoHandshakeComplete();
+ }
+}
+
+void QuartcSession::CloseStream(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);
+ QuicSession::CloseStream(stream_id);
+}
+
+void QuartcSession::OnConnectionClosed(QuicErrorCode error,
+ const std::string& error_details,
+ ConnectionCloseSource source) {
+ QuicSession::OnConnectionClosed(error, error_details, source);
+ DCHECK(session_delegate_);
+ session_delegate_->OnConnectionClosed(
+ error, source == ConnectionCloseSource::FROM_PEER);
+}
+
+void QuartcSession::StartCryptoHandshake() {
+ if (perspective_ == Perspective::IS_CLIENT) {
+ QuicServerId server_id(unique_remote_server_id_, kQuicServerPort);
+ QuicCryptoClientStream* crypto_stream =
+ new QuicCryptoClientStream(server_id, this, new ProofVerifyContext(),
+ quic_crypto_client_config_.get(), this);
+ crypto_stream_.reset(crypto_stream);
+ QuicSession::Initialize();
+ crypto_stream->CryptoConnect();
+ } else {
+ quic_compressed_certs_cache_.reset(new QuicCompressedCertsCache(
+ QuicCompressedCertsCache::kQuicCompressedCertsCacheSize));
+ bool use_stateless_rejects_if_peer_supported = false;
+ QuicCryptoServerStream* crypto_stream = new QuicCryptoServerStream(
+ quic_crypto_server_config_.get(), quic_compressed_certs_cache_.get(),
+ use_stateless_rejects_if_peer_supported, this, &stream_helper_);
+ crypto_stream_.reset(crypto_stream);
+ QuicSession::Initialize();
+ }
+}
+
+bool QuartcSession::ExportKeyingMaterial(const std::string& label,
+ const uint8_t* context,
+ size_t context_len,
+ bool used_context,
+ uint8_t* result,
+ size_t result_len) {
+ std::string quic_context(reinterpret_cast<const char*>(context), context_len);
+ std::string quic_result;
+ bool success = crypto_stream_->ExportKeyingMaterial(label, quic_context,
+ result_len, &quic_result);
+ quic_result.copy(reinterpret_cast<char*>(result), result_len);
+ DCHECK(quic_result.length() == result_len);
+ return success;
+}
+
+QuartcStreamInterface* QuartcSession::CreateOutgoingStream(
+ const OutgoingStreamParameters& param) {
+ // The |param| is for forward-compatibility. Not used for now.
+ return CreateOutgoingDynamicStream(kDefaultPriority);
+}
+
+void QuartcSession::SetDelegate(
+ QuartcSessionInterface::Delegate* session_delegate) {
+ if (session_delegate_) {
+ LOG(WARNING) << "The delegate for the session has already been set.";
+ }
+ session_delegate_ = session_delegate;
+ DCHECK(session_delegate_);
+}
+
+void QuartcSession::OnTransportCanWrite() {
+ if (HasDataToWrite()) {
+ connection()->OnCanWrite();
+ }
+}
+
+bool QuartcSession::OnTransportReceived(const char* data, size_t data_len) {
+ QuicReceivedPacket packet(data, data_len, clock_.Now());
+ ProcessUdpPacket(connection()->self_address(), connection()->peer_address(),
+ packet);
+ return true;
+}
+
+void QuartcSession::OnProofValid(
+ const QuicCryptoClientConfig::CachedState& cached) {
+ // TODO(zhihuang): Handle the proof verification.
+}
+
+void QuartcSession::OnProofVerifyDetailsAvailable(
+ const ProofVerifyDetails& verify_details) {
+ // TODO(zhihuang): Handle the proof verification.
+}
+
+void QuartcSession::SetClientCryptoConfig(
+ QuicCryptoClientConfig* client_config) {
+ quic_crypto_client_config_.reset(client_config);
+}
+
+void QuartcSession::SetServerCryptoConfig(
+ QuicCryptoServerConfig* server_config) {
+ quic_crypto_server_config_.reset(server_config);
+}
+
+ReliableQuicStream* QuartcSession::CreateIncomingDynamicStream(
+ QuicStreamId id) {
+ QuartcStream* stream = CreateDataStream(id, kDefaultPriority);
+ if (stream) {
+ DCHECK(session_delegate_);
+ session_delegate_->OnIncomingStream(stream);
+ }
+ return stream;
+}
+
+QuartcStream* QuartcSession::CreateDataStream(QuicStreamId id,
+ SpdyPriority priority) {
+ if (crypto_stream_ == nullptr || !crypto_stream_->encryption_established()) {
+ // Encryption not active so no stream created
+ return nullptr;
+ }
+ QuartcStream* stream = new QuartcStream(id, this);
+ if (stream) {
+ // Make QuicSession take ownership of the stream.
+ ActivateStream(std::unique_ptr<ReliableQuicStream>(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;
+}
+
+} // namespace net

Powered by Google App Engine
This is Rietveld 408576698