blob: 5ab88bd9d7e4e6c2073909a4683db69ae177016c [file] [log] [blame]
dschinazi996131b2019-12-13 11:36:16 -08001// Copyright 2019 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef QUICHE_QUIC_MASQUE_MASQUE_PROTOCOL_H_
6#define QUICHE_QUIC_MASQUE_MASQUE_PROTOCOL_H_
7
8#include "net/third_party/quiche/src/quic/core/quic_connection_id.h"
9#include "net/third_party/quiche/src/quic/core/quic_session.h"
10#include "net/third_party/quiche/src/quic/core/quic_types.h"
11#include "net/third_party/quiche/src/quic/platform/api/quic_containers.h"
12#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
13#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
dschinazi1c99fcf2019-12-13 11:54:22 -080014#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
dschinazi996131b2019-12-13 11:36:16 -080015
16namespace quic {
17
18// MASQUE compression engine used by client and servers.
19// This class allows converting QUIC packets into a compressed form suitable
20// for sending over QUIC DATAGRAM frames. It leverages a flow identifier at the
21// start of each datagram to indicate which compression context was used to
22// compress this packet, or to create new compression contexts.
23// Compression contexts contain client and server connection IDs and the
24// server's IP and port. This allows compressing that information in most
25// packets without requiring access to the cryptographic keys of the end-to-end
26// encapsulated session. When the flow identifier is 0, the DATAGRAM contains
27// all the contents of the compression context. When the flow identifier is
28// non-zero, those fields are removed so the encapsulated QUIC packet is
29// transmitted without connection IDs and reassembled by the peer on
30// decompression. This only needs to contain the HTTP server's IP address since
31// the client's IP address is not visible to the HTTP server.
32
33class QUIC_NO_EXPORT MasqueCompressionEngine {
34 public:
35 // Caller must ensure that |masque_session| has a lifetime longer than the
36 // newly constructed MasqueCompressionEngine.
37 explicit MasqueCompressionEngine(QuicSession* masque_session);
38
39 // Disallow copy and assign.
40 MasqueCompressionEngine(const MasqueCompressionEngine&) = delete;
41 MasqueCompressionEngine& operator=(const MasqueCompressionEngine&) = delete;
42
43 // Compresses packet and sends it in a DATAGRAM frame over a MASQUE session.
44 // When used from MASQUE client to MASQUE server, the MASQUE server will then
45 // send the packet to the provided |server_address|.
46 // When used from MASQUE server to MASQUE client, the MASQUE client will then
47 // hand off the uncompressed packet to an encapsulated session that will treat
48 // it as having come from the provided |server_address|.
49 // The connection IDs are the one used by the encapsulated |packet|.
dschinazi1c99fcf2019-12-13 11:54:22 -080050 void CompressAndSendPacket(quiche::QuicheStringPiece packet,
dschinazi996131b2019-12-13 11:36:16 -080051 QuicConnectionId client_connection_id,
52 QuicConnectionId server_connection_id,
53 const QuicSocketAddress& server_address);
54
55 // Decompresses received DATAGRAM frame contents from |datagram| and places
56 // them in |packet|. Reverses the transformation from CompressAndSendPacket.
57 // The connection IDs are the one used by the encapsulated |packet|.
58 // |server_address| will be filled with the |server_address| passed to
59 // CompressAndSendPacket. |version_present| will contain whether the
60 // encapsulated |packet| contains a Version field.
dschinazi1c99fcf2019-12-13 11:54:22 -080061 bool DecompressDatagram(quiche::QuicheStringPiece datagram,
dschinazi996131b2019-12-13 11:36:16 -080062 QuicConnectionId* client_connection_id,
63 QuicConnectionId* server_connection_id,
64 QuicSocketAddress* server_address,
dschinazie223d0e2019-12-18 10:59:15 -080065 std::vector<char>* packet,
dschinazi996131b2019-12-13 11:36:16 -080066 bool* version_present);
67
68 // Clears all entries referencing |client_connection_id| from the
69 // compression table.
70 void UnregisterClientConnectionId(QuicConnectionId client_connection_id);
71
72 private:
73 struct QUIC_NO_EXPORT MasqueCompressionContext {
74 QuicConnectionId client_connection_id;
75 QuicConnectionId server_connection_id;
76 QuicSocketAddress server_address;
77 bool validated = false;
78 };
79
80 // Generates a new datagram flow ID.
81 QuicDatagramFlowId GetNextFlowId();
82
83 // Finds or creates a new compression context to use during compression.
84 // |client_connection_id_present| and |server_connection_id_present| indicate
85 // whether the corresponding connection ID is present in the current packet.
86 // |validated| will contain whether the compression context that matches
87 // these arguments is currently validated or not.
88 QuicDatagramFlowId FindOrCreateCompressionContext(
89 QuicConnectionId client_connection_id,
90 QuicConnectionId server_connection_id,
91 const QuicSocketAddress& server_address,
92 bool client_connection_id_present,
93 bool server_connection_id_present,
94 bool* validated);
95
96 // Writes compressed packet to |slice| during compression.
97 bool WriteCompressedPacketToSlice(QuicConnectionId client_connection_id,
98 QuicConnectionId server_connection_id,
99 const QuicSocketAddress& server_address,
100 QuicConnectionId destination_connection_id,
101 QuicConnectionId source_connection_id,
102 QuicDatagramFlowId flow_id,
103 bool validated,
104 uint8_t first_byte,
105 bool long_header,
106 QuicDataReader* reader,
vasilvvff082a02019-12-24 22:07:51 -0800107 QuicDataWriter* writer);
dschinazi996131b2019-12-13 11:36:16 -0800108
109 // Parses compression context from flow ID 0 during decompression.
110 bool ParseCompressionContext(QuicDataReader* reader,
111 MasqueCompressionContext* context);
112
113 // Writes decompressed packet to |packet| during decompression.
114 bool WriteDecompressedPacket(QuicDataReader* reader,
115 const MasqueCompressionContext& context,
dschinazie223d0e2019-12-18 10:59:15 -0800116 std::vector<char>* packet,
dschinazi996131b2019-12-13 11:36:16 -0800117 bool* version_present);
118
119 QuicSession* masque_session_; // Unowned.
wub41db0762020-04-23 13:24:28 -0700120 QuicHashMap<QuicDatagramFlowId, MasqueCompressionContext> contexts_;
dschinazi996131b2019-12-13 11:36:16 -0800121 QuicDatagramFlowId next_flow_id_;
122};
123
124} // namespace quic
125
126#endif // QUICHE_QUIC_MASQUE_MASQUE_PROTOCOL_H_