Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 // | 4 // |
| 5 // A toy client, which connects to a specified port and sends QUIC | 5 // A toy client, which connects to a specified port and sends QUIC |
| 6 // request to that endpoint. | 6 // request to that endpoint. |
| 7 | 7 |
| 8 #ifndef NET_TOOLS_QUIC_QUIC_CLIENT_H_ | 8 #ifndef NET_TOOLS_QUIC_QUIC_CLIENT_H_ |
| 9 #define NET_TOOLS_QUIC_QUIC_CLIENT_H_ | 9 #define NET_TOOLS_QUIC_QUIC_CLIENT_H_ |
| 10 | 10 |
| 11 #include <cstdint> | 11 #include <cstdint> |
| 12 #include <memory> | 12 #include <memory> |
| 13 #include <string> | 13 #include <string> |
| 14 | 14 |
| 15 #include "base/command_line.h" | 15 #include "base/command_line.h" |
| 16 #include "base/macros.h" | 16 #include "base/macros.h" |
| 17 #include "base/strings/string_piece.h" | 17 #include "base/strings/string_piece.h" |
| 18 #include "net/base/ip_address.h" | 18 #include "net/base/ip_address.h" |
| 19 #include "net/base/ip_endpoint.h" | 19 #include "net/base/ip_endpoint.h" |
| 20 #include "net/quic/core/quic_client_push_promise_index.h" | 20 #include "net/quic/core/quic_client_push_promise_index.h" |
| 21 #include "net/quic/core/quic_config.h" | 21 #include "net/quic/core/quic_config.h" |
| 22 #include "net/quic/core/quic_spdy_stream.h" | 22 #include "net/quic/core/quic_spdy_stream.h" |
| 23 #include "net/tools/balsa/balsa_headers.h" | |
|
Zhongyi Shi
2016/09/26 21:12:55
nit: could you also help remove https://cs.chromiu
Ryan Hamilton
2016/09/26 21:52:56
Working on it, but not there yet, alas.
| |
| 24 #include "net/tools/epoll_server/epoll_server.h" | 23 #include "net/tools/epoll_server/epoll_server.h" |
| 25 #include "net/tools/quic/quic_client_base.h" | 24 #include "net/tools/quic/quic_client_base.h" |
| 26 #include "net/tools/quic/quic_client_session.h" | 25 #include "net/tools/quic/quic_client_session.h" |
| 27 #include "net/tools/quic/quic_packet_reader.h" | 26 #include "net/tools/quic/quic_packet_reader.h" |
| 28 #include "net/tools/quic/quic_process_packet_interface.h" | 27 #include "net/tools/quic/quic_process_packet_interface.h" |
| 29 | 28 |
| 30 namespace net { | 29 namespace net { |
| 31 | 30 |
| 32 class QuicServerId; | 31 class QuicServerId; |
| 33 | 32 |
| 34 class QuicEpollConnectionHelper; | 33 class QuicEpollConnectionHelper; |
| 35 | 34 |
| 36 namespace test { | 35 namespace test { |
| 37 class QuicClientPeer; | 36 class QuicClientPeer; |
| 38 } // namespace test | 37 } // namespace test |
| 39 | 38 |
| 40 class QuicClient : public QuicClientBase, | 39 class QuicClient : public QuicClientBase, |
| 41 public EpollCallbackInterface, | 40 public EpollCallbackInterface, |
| 42 public QuicSpdyStream::Visitor, | 41 public QuicSpdyStream::Visitor, |
| 43 public ProcessPacketInterface, | 42 public ProcessPacketInterface, |
| 44 public QuicClientPushPromiseIndex::Delegate { | 43 public QuicClientPushPromiseIndex::Delegate { |
| 45 public: | 44 public: |
| 46 class ResponseListener { | 45 class ResponseListener { |
| 47 public: | 46 public: |
| 48 ResponseListener() {} | 47 ResponseListener() {} |
| 49 virtual ~ResponseListener() {} | 48 virtual ~ResponseListener() {} |
| 50 virtual void OnCompleteResponse(QuicStreamId id, | 49 virtual void OnCompleteResponse(QuicStreamId id, |
| 51 const BalsaHeaders& response_headers, | 50 const SpdyHeaderBlock& response_headers, |
| 52 const std::string& response_body) = 0; | 51 const std::string& response_body) = 0; |
| 53 }; | 52 }; |
| 54 | 53 |
| 55 // The client uses these objects to keep track of any data to resend upon | |
| 56 // receipt of a stateless reject. Recall that the client API allows callers | |
| 57 // to optimistically send data to the server prior to handshake-confirmation. | |
| 58 // If the client subsequently receives a stateless reject, it must tear down | |
| 59 // its existing session, create a new session, and resend all previously sent | |
| 60 // data. It uses these objects to keep track of all the sent data, and to | |
| 61 // resend the data upon a subsequent connection. | |
| 62 class QuicDataToResend { | |
| 63 public: | |
| 64 // Takes ownership of |headers|. |headers| may be null, since it's possible | |
| 65 // to send data without headers. | |
| 66 QuicDataToResend(BalsaHeaders* headers, base::StringPiece body, bool fin); | |
| 67 | |
| 68 virtual ~QuicDataToResend(); | |
| 69 | |
| 70 // Must be overridden by specific classes with the actual method for | |
| 71 // re-sending data. | |
| 72 virtual void Resend() = 0; | |
| 73 | |
| 74 protected: | |
| 75 BalsaHeaders* headers_; | |
| 76 base::StringPiece body_; | |
| 77 bool fin_; | |
| 78 | |
| 79 private: | |
| 80 DISALLOW_COPY_AND_ASSIGN(QuicDataToResend); | |
| 81 }; | |
| 82 | |
| 83 // Create a quic client, which will have events managed by an externally owned | 54 // Create a quic client, which will have events managed by an externally owned |
| 84 // EpollServer. | 55 // EpollServer. |
| 85 QuicClient(IPEndPoint server_address, | 56 QuicClient(IPEndPoint server_address, |
| 86 const QuicServerId& server_id, | 57 const QuicServerId& server_id, |
| 87 const QuicVersionVector& supported_versions, | 58 const QuicVersionVector& supported_versions, |
| 88 EpollServer* epoll_server, | 59 EpollServer* epoll_server, |
| 89 std::unique_ptr<ProofVerifier> proof_verifier); | 60 std::unique_ptr<ProofVerifier> proof_verifier); |
| 90 QuicClient(IPEndPoint server_address, | 61 QuicClient(IPEndPoint server_address, |
| 91 const QuicServerId& server_id, | 62 const QuicServerId& server_id, |
| 92 const QuicVersionVector& supported_versions, | 63 const QuicVersionVector& supported_versions, |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 107 | 78 |
| 108 // Start the crypto handshake. This can be done in place of the synchronous | 79 // Start the crypto handshake. This can be done in place of the synchronous |
| 109 // Connect(), but callers are responsible for making sure the crypto handshake | 80 // Connect(), but callers are responsible for making sure the crypto handshake |
| 110 // completes. | 81 // completes. |
| 111 void StartConnect(); | 82 void StartConnect(); |
| 112 | 83 |
| 113 // Disconnects from the QUIC server. | 84 // Disconnects from the QUIC server. |
| 114 void Disconnect(); | 85 void Disconnect(); |
| 115 | 86 |
| 116 // Sends an HTTP request and does not wait for response before returning. | 87 // Sends an HTTP request and does not wait for response before returning. |
| 117 void SendRequest(const BalsaHeaders& headers, | 88 void SendRequest(const SpdyHeaderBlock& headers, |
| 118 base::StringPiece body, | 89 base::StringPiece body, |
| 119 bool fin); | 90 bool fin); |
| 120 | 91 |
| 121 // Sends an HTTP request and waits for response before returning. | 92 // Sends an HTTP request and waits for response before returning. |
| 122 void SendRequestAndWaitForResponse(const BalsaHeaders& headers, | 93 void SendRequestAndWaitForResponse(const SpdyHeaderBlock& headers, |
| 123 base::StringPiece body, | 94 base::StringPiece body, |
| 124 bool fin); | 95 bool fin); |
| 125 | 96 |
| 126 // Sends a request simple GET for each URL in |url_list|, and then waits for | 97 // Sends a request simple GET for each URL in |url_list|, and then waits for |
| 127 // each to complete. | 98 // each to complete. |
| 128 void SendRequestsAndWaitForResponse(const std::vector<std::string>& url_list); | 99 void SendRequestsAndWaitForResponse(const std::vector<std::string>& url_list); |
| 129 | 100 |
| 130 // Migrate to a new socket during an active connection. | 101 // Migrate to a new socket during an active connection. |
| 131 bool MigrateSocket(const IPAddress& new_host); | 102 bool MigrateSocket(const IPAddress& new_host); |
| 132 | 103 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 178 | 149 |
| 179 // Takes ownership of the std::listener. | 150 // Takes ownership of the std::listener. |
| 180 void set_response_listener(ResponseListener* listener) { | 151 void set_response_listener(ResponseListener* listener) { |
| 181 response_listener_.reset(listener); | 152 response_listener_.reset(listener); |
| 182 } | 153 } |
| 183 | 154 |
| 184 void set_store_response(bool val) { store_response_ = val; } | 155 void set_store_response(bool val) { store_response_ = val; } |
| 185 | 156 |
| 186 size_t latest_response_code() const; | 157 size_t latest_response_code() const; |
| 187 const std::string& latest_response_headers() const; | 158 const std::string& latest_response_headers() const; |
| 159 const SpdyHeaderBlock& latest_response_header_block() const; | |
| 188 const std::string& latest_response_body() const; | 160 const std::string& latest_response_body() const; |
| 189 const std::string& latest_response_trailers() const; | 161 const std::string& latest_response_trailers() const; |
| 190 | 162 |
| 191 protected: | 163 protected: |
| 192 // Implements ProcessPacketInterface. This will be called for each received | 164 // Implements ProcessPacketInterface. This will be called for each received |
| 193 // packet. | 165 // packet. |
| 194 void ProcessPacket(const IPEndPoint& self_address, | 166 void ProcessPacket(const IPEndPoint& self_address, |
| 195 const IPEndPoint& peer_address, | 167 const IPEndPoint& peer_address, |
| 196 const QuicReceivedPacket& packet) override; | 168 const QuicReceivedPacket& packet) override; |
| 197 | 169 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 209 const linked_hash_map<int, IPEndPoint>& fd_address_map() const { | 181 const linked_hash_map<int, IPEndPoint>& fd_address_map() const { |
| 210 return fd_address_map_; | 182 return fd_address_map_; |
| 211 } | 183 } |
| 212 | 184 |
| 213 private: | 185 private: |
| 214 friend class net::test::QuicClientPeer; | 186 friend class net::test::QuicClientPeer; |
| 215 | 187 |
| 216 // Specific QuicClient class for storing data to resend. | 188 // Specific QuicClient class for storing data to resend. |
| 217 class ClientQuicDataToResend : public QuicDataToResend { | 189 class ClientQuicDataToResend : public QuicDataToResend { |
| 218 public: | 190 public: |
| 219 // Takes ownership of |headers|. | 191 ClientQuicDataToResend(std::unique_ptr<SpdyHeaderBlock> headers, |
| 220 ClientQuicDataToResend(BalsaHeaders* headers, | |
| 221 base::StringPiece body, | 192 base::StringPiece body, |
| 222 bool fin, | 193 bool fin, |
| 223 QuicClient* client) | 194 QuicClient* client) |
| 224 : QuicDataToResend(headers, body, fin), client_(client) { | 195 : QuicDataToResend(std::move(headers), body, fin), client_(client) { |
| 225 DCHECK(headers); | 196 DCHECK(headers_); |
| 226 DCHECK(client); | 197 DCHECK(client); |
| 227 } | 198 } |
| 228 | 199 |
| 229 ~ClientQuicDataToResend() override {} | 200 ~ClientQuicDataToResend() override {} |
| 230 | 201 |
| 231 void Resend() override; | 202 void Resend() override; |
| 232 | 203 |
| 233 private: | 204 private: |
| 234 QuicClient* client_; | 205 QuicClient* client_; |
| 235 | 206 |
| 236 DISALLOW_COPY_AND_ASSIGN(ClientQuicDataToResend); | 207 DISALLOW_COPY_AND_ASSIGN(ClientQuicDataToResend); |
| 237 }; | 208 }; |
| 238 | 209 |
| 239 // Used during initialization: creates the UDP socket FD, sets socket options, | 210 // Used during initialization: creates the UDP socket FD, sets socket options, |
| 240 // and binds the socket to our address. | 211 // and binds the socket to our address. |
| 241 bool CreateUDPSocketAndBind(); | 212 bool CreateUDPSocketAndBind(); |
| 242 | 213 |
| 243 // Actually clean up |fd|. | 214 // Actually clean up |fd|. |
| 244 void CleanUpUDPSocketImpl(int fd); | 215 void CleanUpUDPSocketImpl(int fd); |
| 245 | 216 |
| 246 // If the request URL matches a push promise, bypass sending the | |
| 247 // request. | |
| 248 bool MaybeHandlePromised(const BalsaHeaders& headers, | |
| 249 const SpdyHeaderBlock& spdy_headers, | |
| 250 base::StringPiece body, | |
| 251 bool fin); | |
| 252 | |
| 253 // Address of the server. | 217 // Address of the server. |
| 254 IPEndPoint server_address_; | 218 IPEndPoint server_address_; |
| 255 | 219 |
| 256 // If initialized, the address to bind to. | 220 // If initialized, the address to bind to. |
| 257 IPAddress bind_to_address_; | 221 IPAddress bind_to_address_; |
| 258 | 222 |
| 259 // Local port to bind to. Initialize to 0. | 223 // Local port to bind to. Initialize to 0. |
| 260 int local_port_; | 224 int local_port_; |
| 261 | 225 |
| 262 // Listens for events on the client socket. | 226 // Listens for events on the client socket. |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 276 // during the lifetime of the server. | 240 // during the lifetime of the server. |
| 277 QuicPacketCount packets_dropped_; | 241 QuicPacketCount packets_dropped_; |
| 278 | 242 |
| 279 // True if the kernel supports SO_RXQ_OVFL, the number of packets dropped | 243 // True if the kernel supports SO_RXQ_OVFL, the number of packets dropped |
| 280 // because the socket would otherwise overflow. | 244 // because the socket would otherwise overflow. |
| 281 bool overflow_supported_; | 245 bool overflow_supported_; |
| 282 | 246 |
| 283 // If true, store the latest response code, headers, and body. | 247 // If true, store the latest response code, headers, and body. |
| 284 bool store_response_; | 248 bool store_response_; |
| 285 // HTTP response code from most recent response. | 249 // HTTP response code from most recent response. |
| 286 size_t latest_response_code_; | 250 int latest_response_code_; |
| 287 // HTTP/2 headers from most recent response. | 251 // HTTP/2 headers from most recent response. |
| 288 std::string latest_response_headers_; | 252 std::string latest_response_headers_; |
| 253 // HTTP/2 header black from most recent response. | |
| 254 SpdyHeaderBlock latest_response_header_block_; | |
| 289 // Body of most recent response. | 255 // Body of most recent response. |
| 290 std::string latest_response_body_; | 256 std::string latest_response_body_; |
| 291 // HTTP/2 trailers from most recent response. | 257 // HTTP/2 trailers from most recent response. |
| 292 std::string latest_response_trailers_; | 258 std::string latest_response_trailers_; |
| 293 | 259 |
| 294 // Keeps track of any data that must be resent upon a subsequent successful | 260 // Keeps track of any data that must be resent upon a subsequent successful |
| 295 // connection, in case the client receives a stateless reject. | 261 // connection, in case the client receives a stateless reject. |
| 296 std::vector<std::unique_ptr<QuicDataToResend>> data_to_resend_on_connect_; | 262 std::vector<std::unique_ptr<QuicDataToResend>> data_to_resend_on_connect_; |
| 297 | 263 |
| 298 // Point to a QuicPacketReader object on the heap. The reader allocates more | 264 // Point to a QuicPacketReader object on the heap. The reader allocates more |
| 299 // space than allowed on the stack. | 265 // space than allowed on the stack. |
| 300 // | 266 // |
| 301 // TODO(rtenneti): Chromium code doesn't use |packet_reader_|. Add support for | 267 // TODO(rtenneti): Chromium code doesn't use |packet_reader_|. Add support for |
| 302 // QuicPacketReader | 268 // QuicPacketReader |
| 303 std::unique_ptr<QuicPacketReader> packet_reader_; | 269 std::unique_ptr<QuicPacketReader> packet_reader_; |
| 304 | 270 |
| 305 std::unique_ptr<ClientQuicDataToResend> push_promise_data_to_resend_; | 271 std::unique_ptr<ClientQuicDataToResend> push_promise_data_to_resend_; |
| 306 | 272 |
| 307 DISALLOW_COPY_AND_ASSIGN(QuicClient); | 273 DISALLOW_COPY_AND_ASSIGN(QuicClient); |
| 308 }; | 274 }; |
| 309 | 275 |
| 310 } // namespace net | 276 } // namespace net |
| 311 | 277 |
| 312 #endif // NET_TOOLS_QUIC_QUIC_CLIENT_H_ | 278 #endif // NET_TOOLS_QUIC_QUIC_CLIENT_H_ |
| OLD | NEW |