From 990e28bae960924d7d84849519d5004a2691ebe8 Mon Sep 17 00:00:00 2001 From: klzgrad Date: Wed, 12 Dec 2018 23:22:18 -0500 Subject: [PATCH] QUIC WIP 1 --- net/BUILD.gn | 9 ++- .../quic/tools/quic_naive_server_stream.cc | 40 +++++------ .../quic/tools/quic_naive_server_stream.h | 8 +-- .../quic/tools/quic_simple_server_backend.h | 9 +-- .../quic/tools/quic_simple_server_session.cc | 1 + net/tools/naive/naive_proxy_bin.cc | 66 +++++++++++-------- net/tools/naive/quic_proxy_backend.cc | 66 +++++++++++++++++++ net/tools/naive/quic_proxy_backend.h | 59 +++++++++++++++++ 8 files changed, 194 insertions(+), 64 deletions(-) create mode 100644 net/tools/naive/quic_proxy_backend.cc create mode 100644 net/tools/naive/quic_proxy_backend.h diff --git a/net/BUILD.gn b/net/BUILD.gn index 5a7e7fb42e..25a31859f6 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn @@ -2821,13 +2821,15 @@ if (!is_ios && !is_android) { executable("naive") { testonly = true sources = [ + "tools/naive/http_proxy_socket.cc", + "tools/naive/http_proxy_socket.h", "tools/naive/naive_connection.cc", "tools/naive/naive_connection.h", "tools/naive/naive_proxy.cc", "tools/naive/naive_proxy.h", "tools/naive/naive_proxy_bin.cc", - "tools/naive/http_proxy_socket.cc", - "tools/naive/http_proxy_socket.h", + "tools/naive/quic_proxy_backend.cc", + "tools/naive/quic_proxy_backend.h", "tools/naive/socks5_server_socket.cc", "tools/naive/socks5_server_socket.h", ] @@ -2836,6 +2838,7 @@ if (!is_ios && !is_android) { configs += [ "//build/config/compiler:no_size_t_to_int_warning" ] deps = [ ":net", + ":simple_quic_tools", "//base", "//build/win:default_exe_manifest", "//components/version_info:version_info", @@ -3251,6 +3254,8 @@ source_set("simple_quic_tools") { "third_party/quic/tools/quic_client_base.h", "third_party/quic/tools/quic_memory_cache_backend.cc", "third_party/quic/tools/quic_memory_cache_backend.h", + "third_party/quic/tools/quic_naive_server_stream.cc", + "third_party/quic/tools/quic_naive_server_stream.h", "third_party/quic/tools/quic_simple_client_session.cc", "third_party/quic/tools/quic_simple_client_session.h", "third_party/quic/tools/quic_simple_client_stream.cc", diff --git a/net/third_party/quic/tools/quic_naive_server_stream.cc b/net/third_party/quic/tools/quic_naive_server_stream.cc index 82c540db24..ed32004de4 100644 --- a/net/third_party/quic/tools/quic_naive_server_stream.cc +++ b/net/third_party/quic/tools/quic_naive_server_stream.cc @@ -8,37 +8,26 @@ #include #include "net/third_party/quic/core/http/quic_spdy_stream.h" -#include "net/third_party/quic/core/http/spdy_utils.h" -#include "net/third_party/quic/platform/api/quic_bug_tracker.h" -#include "net/third_party/quic/platform/api/quic_flags.h" #include "net/third_party/quic/platform/api/quic_logging.h" -#include "net/third_party/quic/platform/api/quic_map_util.h" -#include "net/third_party/quic/platform/api/quic_text_utils.h" #include "net/third_party/quic/tools/quic_simple_server_session.h" -#include "net/third_party/spdy/core/spdy_protocol.h" namespace quic { -QuicNaiveServerStream::QuicNaiveServerStream( - QuicStreamId id, - QuicSpdySession* session, - QuicSimpleServerBackend* backend) - : QuicSpdyServerStreamBase(id, session), - backend_(backend) {} +QuicNaiveServerStream::QuicNaiveServerStream(QuicStreamId id, + QuicSpdySession* session, + QuicSimpleServerBackend* backend) + : QuicSpdyServerStreamBase(id, session), backend_(backend) {} QuicNaiveServerStream::~QuicNaiveServerStream() { - backend_->OnCloseStream(this); + backend_->OnDeleteStream(this); } -void QuicNaiveServerStream::SendErrorResponse(int resp_code) { - QUIC_DVLOG(1) << "Stream " << id() << " sending error response."; - spdy::SpdyHeaderBlock headers; - if (resp_code <= 0) { - headers[":status"] = "500"; - } else { - headers[":status"] = QuicTextUtils::Uint64ToString(resp_code); - } - WriteHeaders(std::move(headers), /*fin=*/true, nullptr); +void QuicNaiveServerStream::set_naive_id(unsigned int id) { + naive_id_ = id; +} + +unsigned int QuicNaiveServerStream::naive_id() { + return naive_id_; } void QuicNaiveServerStream::OnInitialHeadersComplete( @@ -55,7 +44,9 @@ void QuicNaiveServerStream::OnTrailingHeadersComplete( size_t frame_len, const QuicHeaderList& header_list) { QUIC_BUG << "Server does not support receiving Trailers."; - SendErrorResponse(0); + spdy::SpdyHeaderBlock headers; + headers[":status"] = "500"; + WriteHeaders(std::move(headers), /*fin=*/true, nullptr); } void QuicNaiveServerStream::OnDataAvailable() { @@ -93,7 +84,6 @@ QuicString QuicNaiveServerStream::peer_host() const { void QuicNaiveServerStream::OnResponseBackendComplete( const QuicBackendResponse* response, - std::list resources) { -} + std::list resources) {} } // namespace quic diff --git a/net/third_party/quic/tools/quic_naive_server_stream.h b/net/third_party/quic/tools/quic_naive_server_stream.h index 5d82d0f397..f0b5a6a481 100644 --- a/net/third_party/quic/tools/quic_naive_server_stream.h +++ b/net/third_party/quic/tools/quic_naive_server_stream.h @@ -7,18 +7,16 @@ #include "base/macros.h" #include "net/third_party/quic/core/http/quic_spdy_server_stream_base.h" -#include "net/third_party/quic/core/quic_packets.h" #include "net/third_party/quic/platform/api/quic_string_piece.h" #include "net/third_party/quic/tools/quic_backend_response.h" #include "net/third_party/quic/tools/quic_simple_server_backend.h" -#include "net/third_party/spdy/core/spdy_framer.h" namespace quic { // All this does right now is aggregate data, and on fin, send an HTTP // response. class QuicNaiveServerStream : public QuicSpdyServerStreamBase, - public QuicSimpleServerBackend::RequestHandler { + public QuicSimpleServerBackend::RequestHandler { public: QuicNaiveServerStream(QuicStreamId id, QuicSpdySession* session, @@ -27,7 +25,8 @@ class QuicNaiveServerStream : public QuicSpdyServerStreamBase, QuicNaiveServerStream& operator=(const QuicNaiveServerStream&) = delete; ~QuicNaiveServerStream() override; - void SendErrorResponse(int resp_code); + void set_naive_id(unsigned int value); + unsigned int naive_id() const; // QuicSpdyStream void OnInitialHeadersComplete(bool fin, @@ -53,6 +52,7 @@ class QuicNaiveServerStream : public QuicSpdyServerStreamBase, private: QuicSimpleServerBackend* backend_; // Not owned. + unsigned int naive_id_; }; } // namespace quic diff --git a/net/third_party/quic/tools/quic_simple_server_backend.h b/net/third_party/quic/tools/quic_simple_server_backend.h index b7168f0c10..a6f7fb8f4e 100644 --- a/net/third_party/quic/tools/quic_simple_server_backend.h +++ b/net/third_party/quic/tools/quic_simple_server_backend.h @@ -11,7 +11,7 @@ namespace spdy { class SpdyHeaderBlock; } // namespace spdy namespace quic { -class QuicSpdyStream; +class QuicNaiveServerStream; // This interface implements the functionality to fetch a response // from the backend (such as cache, http-proxy etc) to serve @@ -54,9 +54,10 @@ class QuicSimpleServerBackend { // Clears the state of the backend instance virtual void CloseBackendResponseStream(RequestHandler* request_handler) = 0; - virtual void OnReadHeaders(QuicSpdyStream* stream, const QuicHeaderList& header_list) {}; - virtual void OnReadData(QuicSpdyStream* stream, void* data, size_t len) {}; - virtual void OnCloseStream(QuicSpdyStream* stream) {}; + virtual void OnReadHeaders(QuicNaiveServerStream* stream, + const QuicHeaderList& header_list) {} + virtual void OnReadData(QuicNaiveServerStream* stream) {} + virtual void OnDeleteStream(QuicNaiveServerStream* stream) {} }; } // namespace quic diff --git a/net/third_party/quic/tools/quic_simple_server_session.cc b/net/third_party/quic/tools/quic_simple_server_session.cc index 18a600d2ea..1320da034e 100644 --- a/net/third_party/quic/tools/quic_simple_server_session.cc +++ b/net/third_party/quic/tools/quic_simple_server_session.cc @@ -10,6 +10,7 @@ #include "net/third_party/quic/platform/api/quic_flags.h" #include "net/third_party/quic/platform/api/quic_logging.h" #include "net/third_party/quic/platform/api/quic_ptr_util.h" +#include "net/third_party/quic/tools/quic_naive_server_stream.h" #include "net/third_party/quic/tools/quic_simple_server_stream.h" #include "net/third_party/quic/tools/quic_naive_server_stream.h" diff --git a/net/tools/naive/naive_proxy_bin.cc b/net/tools/naive/naive_proxy_bin.cc index 898ce98eb8..5b92be7663 100644 --- a/net/tools/naive/naive_proxy_bin.cc +++ b/net/tools/naive/naive_proxy_bin.cc @@ -16,7 +16,9 @@ #include "base/macros.h" #include "base/message_loop/message_loop.h" #include "base/run_loop.h" +#include "base/strings/strcat.h" #include "base/strings/string_number_conversions.h" +#include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/sys_info.h" @@ -25,6 +27,8 @@ #include "build/build_config.h" #include "components/version_info/version_info.h" #include "net/base/auth.h" +#include "net/base/ip_address.h" +#include "net/base/ip_endpoint.h" #include "net/dns/host_resolver.h" #include "net/dns/mapped_host_resolver.h" #include "net/http/http_auth.h" @@ -41,18 +45,21 @@ #include "net/proxy_resolution/proxy_config_service_fixed.h" #include "net/proxy_resolution/proxy_config_with_annotation.h" #include "net/proxy_resolution/proxy_resolution_service.h" +#include "net/quic/crypto/proof_source_chromium.h" #include "net/socket/client_socket_pool_manager.h" #include "net/socket/ssl_client_socket.h" #include "net/socket/tcp_server_socket.h" #include "net/ssl/ssl_key_logger_impl.h" +#include "net/third_party/quic/core/crypto/quic_crypto_server_config.h" +#include "net/third_party/quic/core/quic_config.h" #include "net/tools/naive/naive_proxy.h" +#include "net/tools/naive/quic_proxy_backend.h" +#include "net/tools/quic/quic_simple_server.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_builder.h" #include "url/gurl.h" #include "url/scheme_host_port.h" -#include "base/strings/strcat.h" -#include "base/strings/string_util.h" #if defined(OS_MACOSX) #include "base/mac/scoped_nsautorelease_pool.h" @@ -121,7 +128,8 @@ std::unique_ptr BuildURLRequestContext( if (params.use_proxy) { std::string proxy_url = params.proxy_url; if (params.is_quic_proxy) { - proxy_url = base::StrCat({"quic://", proxy_url.substr(sizeof("https://") - 1)}); + proxy_url = + base::StrCat({"quic://", proxy_url.substr(sizeof("https://") - 1)}); } proxy_config.proxy_rules().ParseFromString(proxy_url); } @@ -141,7 +149,8 @@ std::unique_ptr BuildURLRequestContext( auto context = builder.Build(); - if (params.use_proxy && !params.proxy_user.empty() && !params.proxy_pass.empty()) { + if (params.use_proxy && !params.proxy_user.empty() && + !params.proxy_pass.empty()) { net::HttpNetworkSession* session = context->http_transaction_factory()->GetSession(); net::HttpAuthCache* auth_cache = session->http_auth_cache(); @@ -228,7 +237,8 @@ bool ParseCommandLineFlags(Params* params) { params->is_quic_proxy = false; std::string proxy_str = line.GetSwitchValueASCII("proxy"); if (base::StartsWith(proxy_str, "quic://", base::CompareCase::SENSITIVE)) { - proxy_str = base::StrCat({"https://", proxy_str.substr(sizeof("quic://") - 1)}); + proxy_str = + base::StrCat({"https://", proxy_str.substr(sizeof("quic://") - 1)}); params->is_quic_proxy = true; } GURL url(proxy_str); @@ -395,15 +405,16 @@ int main(int argc, char* argv[]) { auto context = BuildURLRequestContext(params, &net_log); auto* session = context->http_transaction_factory()->GetSession(); - if (params->is_quic) { - auto backend = std::make_unique(session); + if (params.is_quic) { + auto backend = + std::make_unique(session, kTrafficAnnotation); quic::QuicConfig config; auto proof_source = std::make_unique(); - CHECK(proof_source->Initialize(params.certificate_file, params.key_file, base::FilePath())); - net::QuicSimpleServer server( - std::move(proof_source), - config, quic::QuicCryptoServerConfig::ConfigOptions(), - quic::AllSupportedVersions(), backend.get()); + CHECK(proof_source->Initialize(params.certificate_file, params.key_file, + base::FilePath())); + net::QuicSimpleServer server(std::move(proof_source), config, + quic::QuicCryptoServerConfig::ConfigOptions(), + quic::AllSupportedVersions(), backend.get()); net::IPAddress ip; int result = net::ERR_ADDRESS_INVALID; @@ -416,25 +427,22 @@ int main(int argc, char* argv[]) { } base::RunLoop().Run(); + } else { + auto listen_socket = + std::make_unique(&net_log, net::NetLogSource()); - return EXIT_SUCCESS; + int result = listen_socket->ListenWithAddressAndPort( + params.listen_addr, params.listen_port, kListenBackLog); + if (result != net::OK) { + LOG(ERROR) << "Failed to listen: " << result; + return EXIT_FAILURE; + } + + net::NaiveProxy naive_proxy(std::move(listen_socket), params.protocol, + params.use_proxy, session, kTrafficAnnotation); + + base::RunLoop().Run(); } - auto listen_socket = - std::make_unique(&net_log, net::NetLogSource()); - - int result = listen_socket->ListenWithAddressAndPort( - params.listen_addr, params.listen_port, kListenBackLog); - if (result != net::OK) { - LOG(ERROR) << "Failed to listen: " << result; - return EXIT_FAILURE; - } - - net::NaiveProxy naive_proxy( - std::move(listen_socket), params.protocol, params.use_proxy, - session, kTrafficAnnotation); - - base::RunLoop().Run(); - return EXIT_SUCCESS; } diff --git a/net/tools/naive/quic_proxy_backend.cc b/net/tools/naive/quic_proxy_backend.cc new file mode 100644 index 0000000000..d5bbabdd7e --- /dev/null +++ b/net/tools/naive/quic_proxy_backend.cc @@ -0,0 +1,66 @@ +// 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 + +#include "base/logging.h" +#include "net/third_party/quic/core/http/quic_header_list.h" +#include "net/third_party/quic/core/http/quic_spdy_stream.h" +#include "net/third_party/spdy/core/spdy_header_block.h" +#include "net/tools/naive/quic_proxy_backend.h" + +namespace net { + +QuicProxyBackend::QuicProxyBackend( + HttpNetworkSession* session, + const NetworkTrafficAnnotationTag& traffic_annotation) + : session_(session), traffic_annotation_(traffic_annotation) {} + +QuicProxyBackend::~QuicProxyBackend() {} + +bool QuicProxyBackend::InitializeBackend(const std::string& backend_url) { + return true; +} + +bool QuicProxyBackend::IsBackendInitialized() const { + return true; +} + +void QuicProxyBackend::FetchResponseFromBackend( + const spdy::SpdyHeaderBlock& request_headers, + const std::string& incoming_body, + QuicSimpleServerBackend::RequestHandler* quic_stream) {} + +void QuicProxyBackend::CloseBackendResponseStream( + QuicSimpleServerBackend::RequestHandler* quic_stream) {} + +void QuicProxyBackend::OnReadHeaders(quic::QuicSpdyStream* stream, + const quic::QuicHeaderList& header_list) { + for (const auto& p : header_list) { + const auto& name = p.first; + const auto& value = p.second; + if (name == ":method" && value != "CONNECT") { + spdy::SpdyHeaderBlock headers; + headers[":status"] = "405"; + stream->WriteHeaders(std::move(headers), /*fin=*/true, nullptr); + return; + } + if (name == ":authority") { + } + } + + LOG(INFO) << "OnReadHeaders " << stream; +} + +void QuicProxyBackend::OnReadData(quic::QuicSpdyStream* stream, + void* data, + size_t len) { + LOG(INFO) << "OnReadData " << stream; +} + +void QuicProxyBackend::OnCloseStream(quic::QuicSpdyStream* stream) { + LOG(INFO) << "OnCloseStream " << stream; +} + +} // namespace net diff --git a/net/tools/naive/quic_proxy_backend.h b/net/tools/naive/quic_proxy_backend.h new file mode 100644 index 0000000000..f7bba00f72 --- /dev/null +++ b/net/tools/naive/quic_proxy_backend.h @@ -0,0 +1,59 @@ +// 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 NET_TOOLS_NAIVE_QUIC_PROXY_BACKEND_H_ +#define NET_TOOLS_NAIVE_QUIC_PROXY_BACKEND_H_ + +#include +#include + +#include "base/callback.h" +#include "base/macros.h" +#include "net/third_party/quic/tools/quic_simple_server_backend.h" + +namespace spdy { +class SpdyHeaderBlock; +} // namespace spdy + +namespace quic { +class QuicSpdyStream; +class QuicHeaderList; +} // namespace quic + +namespace net { +class HttpNetworkSession; +struct NetworkTrafficAnnotationTag; + +class QuicProxyBackend : public quic::QuicSimpleServerBackend { + public: + QuicProxyBackend(HttpNetworkSession* session, + const NetworkTrafficAnnotationTag& traffic_annotation); + ~QuicProxyBackend() override; + + // Implements quic::QuicSimpleServerBackend + bool InitializeBackend(const std::string& backend_url) override; + bool IsBackendInitialized() const override; + void FetchResponseFromBackend( + const spdy::SpdyHeaderBlock& request_headers, + const std::string& incoming_body, + quic::QuicSimpleServerBackend::RequestHandler* quic_stream) override; + void CloseBackendResponseStream( + quic::QuicSimpleServerBackend::RequestHandler* quic_stream) override; + + void OnReadHeaders(quic::QuicSpdyStream* stream, + const quic::QuicHeaderList& header_list) override; + void OnReadData(quic::QuicSpdyStream* stream, + void* data, + size_t len) override; + void OnCloseStream(quic::QuicSpdyStream* stream) override; + + private: + HttpNetworkSession* session_; + const NetworkTrafficAnnotationTag& traffic_annotation_; + + DISALLOW_COPY_AND_ASSIGN(QuicProxyBackend); +}; +} // namespace net + +#endif // NET_TOOLS_NAIVE_QUIC_PROXY_BACKEND_H_