proxygen
proxygen::QPACKEncoder Class Reference

#include <QPACKEncoder.h>

Inheritance diagram for proxygen::QPACKEncoder:
proxygen::HPACKEncoderBase proxygen::QPACKContext

Classes

struct  EncodeResult
 
struct  OutstandingBlock
 

Public Types

using Buf = std::unique_ptr< folly::IOBuf >
 

Public Member Functions

 QPACKEncoder (bool huffman, uint32_t tableSize=HPACK::kTableSize)
 
EncodeResult encode (const std::vector< HPACKHeader > &headers, uint32_t headroom, uint64_t streamId)
 
HPACK::DecodeError decodeDecoderStream (std::unique_ptr< folly::IOBuf > buf)
 
HPACK::DecodeError onTableStateSync (uint32_t inserts)
 
HPACK::DecodeError onHeaderAck (uint64_t streamId, bool all)
 
void setHeaderTableSize (uint32_t size)
 
void setMaxVulnerable (uint32_t maxVulnerable)
 
- Public Member Functions inherited from proxygen::HPACKEncoderBase
 HPACKEncoderBase (bool huffman)
 
void setHeaderTableSize (HeaderTable &table, uint32_t size)
 
void setHeaderIndexingStrategy (const HeaderIndexingStrategy *indexingStrat)
 
const HeaderIndexingStrategygetHeaderIndexingStrategy () const
 
- Public Member Functions inherited from proxygen::QPACKContext
 QPACKContext (uint32_t tableSize, bool trackReferences)
 
 ~QPACKContext ()
 
const HPACKHeadergetHeader (bool isStatic, uint32_t index, uint32_t base, bool aboveBase)
 
const QPACKHeaderTablegetTable () const
 
uint32_t getTableSize () const
 
uint32_t getBytesStored () const
 
uint32_t getHeadersStored () const
 
void seedHeaderTable (std::vector< HPACKHeader > &headers)
 
void describe (std::ostream &os) const
 

Private Types

using BlockReferences = std::set< uint32_t >
 

Private Member Functions

bool allowVulnerable () const
 
bool shouldIndex (const HPACKHeader &header) const
 
void encodeControl (const HPACKHeader &header)
 
std::pair< bool, uint32_tmaybeDuplicate (uint32_t relativeIndex)
 
QPACKEncoder::EncodeResult encodeQ (const std::vector< HPACKHeader > &headers, uint64_t streamId)
 
std::tuple< bool, uint32_t, uint32_tgetNameIndexQ (const HPACKHeaderName &headerName)
 
void encodeStreamLiteralQ (const HPACKHeader &header, bool isStaticName, uint32_t nameIndex, uint32_t absoluteNameIndex, uint32_t baseIndex, uint32_t *largestReference)
 
void encodeHeaderQ (const HPACKHeader &header, uint32_t baseIndex, uint32_t *largestReference)
 
void encodeInsertQ (const HPACKHeader &header, bool isStaticName, uint32_t nameIndex)
 
void encodeLiteralQ (const HPACKHeader &header, bool isStaticName, bool postBase, uint32_t nameIndex, const HPACK::Instruction &idxInstr)
 
void encodeLiteralQHelper (HPACKEncodeBuffer &buffer, const HPACKHeader &header, bool isStaticName, uint32_t nameIndex, uint8_t staticFlag, const HPACK::Instruction &idxInstr, const HPACK::Instruction &litInstr)
 
void trackReference (uint32_t index, uint32_t *largestReference)
 
void encodeDuplicate (uint32_t index)
 
HPACK::DecodeError decodeHeaderAck (HPACKDecodeBuffer &dbuf, uint8_t prefixLength, bool all)
 

Private Attributes

HPACKEncodeBuffer controlBuffer_
 
std::unordered_map< uint64_t, std::list< OutstandingBlock > > outstanding_
 
OutstandingBlockcurOutstanding_ {nullptr}
 
uint32_t maxDepends_ {0}
 
uint32_t maxVulnerable_ {HPACK::kDefaultBlocking}
 
uint32_t numVulnerable_ {0}
 
folly::IOBufQueue decoderIngress_ {folly::IOBufQueue::cacheChainLength()}
 

Additional Inherited Members

- Static Public Attributes inherited from proxygen::HPACKEncoderBase
static const uint32_t kBufferGrowth = 4000
 
- Protected Member Functions inherited from proxygen::HPACKEncoderBase
void handlePendingContextUpdate (HPACKEncodeBuffer &buf, uint32_t tableCapacity)
 
- Protected Member Functions inherited from proxygen::QPACKContext
const StaticHeaderTablegetStaticTable () const
 
- Protected Attributes inherited from proxygen::HPACKEncoderBase
const HeaderIndexingStrategyindexingStrat_
 
HPACKEncodeBuffer streamBuffer_
 
bool pendingContextUpdate_ {false}
 
- Protected Attributes inherited from proxygen::QPACKContext
QPACKHeaderTable table_
 

Detailed Description

Definition at line 25 of file QPACKEncoder.h.

Member Typedef Documentation

Definition at line 116 of file QPACKEncoder.h.

using proxygen::QPACKEncoder::Buf = std::unique_ptr<folly::IOBuf>

Encode the given headers.

Definition at line 35 of file QPACKEncoder.h.

Constructor & Destructor Documentation

proxygen::QPACKEncoder::QPACKEncoder ( bool  huffman,
uint32_t  tableSize = HPACK::kTableSize 
)
explicit

Definition at line 17 of file QPACKEncoder.cpp.

References proxygen::HeaderIndexingStrategy::getDefaultInstance(), and proxygen::HPACKEncoderBase::setHeaderIndexingStrategy().

17  :
18  // We only need the 'QPACK' table if we are using base index
19  HPACKEncoderBase(huffman),
20  QPACKContext(tableSize, true),
21  controlBuffer_(kBufferGrowth, huffman) {
22  // Default the encoder indexing strategy; it can be updated later as well
24 }
HPACKEncodeBuffer controlBuffer_
Definition: QPACKEncoder.h:115
void setHeaderIndexingStrategy(const HeaderIndexingStrategy *indexingStrat)
QPACKContext(uint32_t tableSize, bool trackReferences)
static const uint32_t kBufferGrowth
static const HeaderIndexingStrategy * getDefaultInstance()

Member Function Documentation

HPACK::DecodeError proxygen::QPACKEncoder::decodeDecoderStream ( std::unique_ptr< folly::IOBuf buf)

Definition at line 277 of file QPACKEncoder.cpp.

References folly::IOBufQueue::append(), proxygen::HPACK::BUFFER_UNDERFLOW, folly::IOBufQueue::chainLength(), decodeHeaderAck(), decoderIngress_, proxygen::ERROR, folly::IOBufQueue::front(), folly::gen::move, proxygen::HPACK::NONE, onTableStateSync(), proxygen::HPACK::Q_CANCEL_STREAM, proxygen::HPACK::Q_HEADER_ACK, proxygen::HPACK::Q_TABLE_STATE_SYNC, folly::IOBufQueue::trimStart(), uint32_t, and uint64_t.

Referenced by proxygen::hpack::encodeDecode(), and TEST().

278  {
281  HPACKDecodeBuffer dbuf(cursor, decoderIngress_.chainLength(), 0);
283  uint32_t consumed = 0;
284  while (err == HPACK::DecodeError::NONE && !dbuf.empty()) {
285  consumed = dbuf.consumedBytes();
286  auto byte = dbuf.peek();
287  if (byte & HPACK::Q_HEADER_ACK.code) {
288  err = decodeHeaderAck(dbuf, HPACK::Q_HEADER_ACK.prefixLength, false);
289  } else if (byte & HPACK::Q_CANCEL_STREAM.code) {
290  err = decodeHeaderAck(dbuf, HPACK::Q_CANCEL_STREAM.prefixLength, true);
291  } else { // TABLE_STATE_SYNC
292  uint64_t inserts = 0;
293  err = dbuf.decodeInteger(HPACK::Q_TABLE_STATE_SYNC.prefixLength, inserts);
294  if (err == HPACK::DecodeError::NONE) {
295  err = onTableStateSync(inserts);
296  } else if (err != HPACK::DecodeError::BUFFER_UNDERFLOW) {
297  LOG(ERROR) << "Failed to decode num inserts, err=" << err;
298  }
299  }
300  } // while
303  decoderIngress_.trimStart(consumed);
304  } else {
305  decoderIngress_.trimStart(dbuf.consumedBytes());
306  }
307  return err;
308 }
const Instruction Q_TABLE_STATE_SYNC
const folly::IOBuf * front() const
Definition: IOBufQueue.h:476
void append(std::unique_ptr< folly::IOBuf > &&buf, bool pack=false)
Definition: IOBufQueue.cpp:143
size_t chainLength() const
Definition: IOBufQueue.h:492
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
const Instruction Q_HEADER_ACK
HPACK::DecodeError decodeHeaderAck(HPACKDecodeBuffer &dbuf, uint8_t prefixLength, bool all)
folly::IOBufQueue decoderIngress_
Definition: QPACKEncoder.h:127
HPACK::DecodeError onTableStateSync(uint32_t inserts)
void trimStart(size_t amount)
Definition: IOBufQueue.cpp:255
const Instruction Q_CANCEL_STREAM
HPACK::DecodeError proxygen::QPACKEncoder::decodeHeaderAck ( HPACKDecodeBuffer dbuf,
uint8_t  prefixLength,
bool  all 
)
private

Definition at line 310 of file QPACKEncoder.cpp.

References proxygen::HPACK::BUFFER_UNDERFLOW, proxygen::HPACKDecodeBuffer::decodeInteger(), proxygen::ERROR, proxygen::HPACK::NONE, onHeaderAck(), and uint64_t.

Referenced by allowVulnerable(), and decodeDecoderStream().

312  {
313  uint64_t streamId = 0;
314  auto err = dbuf.decodeInteger(prefixLength, streamId);
315  if (err == HPACK::DecodeError::NONE) {
316  err = onHeaderAck(streamId, all);
317  } else if (err != HPACK::DecodeError::BUFFER_UNDERFLOW) {
318  LOG(ERROR) << "Failed to decode streamId, err=" << err;
319  }
320  return err;
321 }
HPACK::DecodeError onHeaderAck(uint64_t streamId, bool all)
Composed all(Predicate pred=Predicate())
Definition: Base.h:786
QPACKEncoder::EncodeResult proxygen::QPACKEncoder::encode ( const std::vector< HPACKHeader > &  headers,
uint32_t  headroom,
uint64_t  streamId 
)

Definition at line 27 of file QPACKEncoder.cpp.

References proxygen::HPACKEncodeBuffer::addHeadroom(), proxygen::HeaderTable::capacity(), controlBuffer_, encodeQ(), proxygen::HPACKEncoderBase::handlePendingContextUpdate(), proxygen::HPACKEncoderBase::streamBuffer_, and proxygen::QPACKContext::table_.

Referenced by proxygen::QPACKCodec::encode(), proxygen::hpack::encodeDecode(), and TEST().

29  {
30  if (headroom) {
31  streamBuffer_.addHeadroom(headroom);
32  }
34  return encodeQ(headers, streamId);
35 }
QPACKHeaderTable table_
Definition: QPACKContext.h:54
uint32_t capacity() const
Definition: HeaderTable.h:86
HPACKEncodeBuffer controlBuffer_
Definition: QPACKEncoder.h:115
HPACKEncodeBuffer streamBuffer_
void addHeadroom(uint32_t bytes)
void handlePendingContextUpdate(HPACKEncodeBuffer &buf, uint32_t tableCapacity)
QPACKEncoder::EncodeResult encodeQ(const std::vector< HPACKHeader > &headers, uint64_t streamId)
void proxygen::QPACKEncoder::encodeControl ( const HPACKHeader header)
private

Referenced by allowVulnerable().

void proxygen::QPACKEncoder::encodeDuplicate ( uint32_t  index)
private

Definition at line 224 of file QPACKEncoder.cpp.

References controlBuffer_, proxygen::HPACKEncodeBuffer::encodeInteger(), and proxygen::HPACK::Q_DUPLICATE.

Referenced by allowVulnerable(), and maybeDuplicate().

224  {
225  DCHECK_GT(index, 0);
227 }
HPACKEncodeBuffer controlBuffer_
Definition: QPACKEncoder.h:115
const Instruction Q_DUPLICATE
uint32_t encodeInteger(uint64_t value, uint8_t instruction, uint8_t nbit)
void proxygen::QPACKEncoder::encodeHeaderQ ( const HPACKHeader header,
uint32_t  baseIndex,
uint32_t largestReference 
)
private

Definition at line 76 of file QPACKEncoder.cpp.

References proxygen::QPACKHeaderTable::absoluteToRelative(), proxygen::QPACKHeaderTable::add(), allowVulnerable(), proxygen::QPACKHeaderTable::canIndex(), proxygen::HPACKHeader::copy(), encodeInsertQ(), proxygen::HPACKEncodeBuffer::encodeInteger(), encodeStreamLiteralQ(), proxygen::QPACKHeaderTable::getBaseIndex(), proxygen::HeaderTable::getIndex(), proxygen::QPACKHeaderTable::getIndex(), getNameIndexQ(), proxygen::QPACKContext::getStaticTable(), proxygen::QPACKHeaderTable::isValid(), maybeDuplicate(), proxygen::HPACKHeader::name, proxygen::HPACK::Q_INDEXED, proxygen::HPACK::Q_INDEXED_POST, proxygen::HPACK::Q_INDEXED_STATIC, shouldIndex(), proxygen::HPACKEncoderBase::streamBuffer_, proxygen::QPACKContext::table_, trackReference(), uint32_t, and proxygen::QPACKHeaderTable::UNACKED.

Referenced by allowVulnerable(), and encodeQ().

77  {
78  uint32_t index = getStaticTable().getIndex(header);
79  if (index > 0) {
80  // static reference
83  HPACK::Q_INDEXED.prefixLength);
84  return;
85  }
86 
87  bool indexable = shouldIndex(header);
88  if (indexable) {
89  index = table_.getIndex(header, allowVulnerable());
90  if (index == QPACKHeaderTable::UNACKED) {
91  index = 0;
92  indexable = false;
93  }
94  }
95  if (index != 0) {
96  // dynamic reference
97  bool duplicated = false;
98  std::tie(duplicated, index) = maybeDuplicate(index);
99  // index is now 0 or absolute
100  indexable &= (duplicated && index == 0);
101  }
102  if (index == 0) {
103  // No valid entry matching header, see if there's a matching name
104  uint32_t nameIndex = 0;
105  uint32_t absoluteNameIndex = 0;
106  bool isStaticName = false;
107  std::tie(isStaticName, nameIndex, absoluteNameIndex) =
108  getNameIndexQ(header.name);
109 
110  // Now check if we should emit an insertion on the control stream
111  if (indexable && table_.canIndex(header)) {
112  encodeInsertQ(header, isStaticName, nameIndex);
113  CHECK(table_.add(header.copy()));
114  if (allowVulnerable()) {
115  index = table_.getBaseIndex();
116  } else {
117  index = 0;
118  if (!table_.isValid(table_.absoluteToRelative(absoluteNameIndex))) {
119  // The insert may have invalidated the name index.
120  isStaticName = true;
121  nameIndex = 0;
122  absoluteNameIndex = 0;
123  }
124  }
125  }
126 
127  if (index == 0) {
128  // Couldn't insert it: table full, not indexable, or table contains
129  // vulnerable reference. Encode a literal on the request stream.
130  encodeStreamLiteralQ(header, isStaticName, nameIndex, absoluteNameIndex,
131  baseIndex, largestReference);
132  return;
133  }
134  }
135 
136  // Encoding a dynamic index reference
137  DCHECK_NE(index, 0);
138  trackReference(index, largestReference);
139  if (index > baseIndex) {
140  streamBuffer_.encodeInteger(index - baseIndex - 1, HPACK::Q_INDEXED_POST);
141  } else {
142  streamBuffer_.encodeInteger(baseIndex - index, HPACK::Q_INDEXED);
143  }
144 }
QPACKHeaderTable table_
Definition: QPACKContext.h:54
void encodeInsertQ(const HPACKHeader &header, bool isStaticName, uint32_t nameIndex)
std::pair< bool, uint32_t > maybeDuplicate(uint32_t relativeIndex)
bool shouldIndex(const HPACKHeader &header) const
const Instruction Q_INDEXED_POST
HPACKEncodeBuffer streamBuffer_
uint32_t getBaseIndex() const
void encodeStreamLiteralQ(const HPACKHeader &header, bool isStaticName, uint32_t nameIndex, uint32_t absoluteNameIndex, uint32_t baseIndex, uint32_t *largestReference)
void trackReference(uint32_t index, uint32_t *largestReference)
bool add(HPACKHeader header) override
bool allowVulnerable() const
Definition: QPACKEncoder.h:66
uint32_t absoluteToRelative(uint32_t absIndex) const
bool canIndex(const HPACKHeader &header)
uint32_t encodeInteger(uint64_t value, uint8_t instruction, uint8_t nbit)
bool isValid(uint32_t index, uint32_t base=0) const
const StaticHeaderTable & getStaticTable() const
Definition: QPACKContext.h:50
const uint8_t Q_INDEXED_STATIC
uint32_t getIndex(const HPACKHeader &header, bool allowVulnerable=true) const
uint32_t getIndex(const HPACKHeader &header) const
Definition: HeaderTable.cpp:63
std::tuple< bool, uint32_t, uint32_t > getNameIndexQ(const HPACKHeaderName &headerName)
const Instruction Q_INDEXED
void proxygen::QPACKEncoder::encodeInsertQ ( const HPACKHeader header,
bool  isStaticName,
uint32_t  nameIndex 
)
private

Definition at line 229 of file QPACKEncoder.cpp.

References controlBuffer_, encodeLiteralQHelper(), proxygen::HPACK::Q_INSERT_NAME_REF, proxygen::HPACK::Q_INSERT_NAME_REF_STATIC, and proxygen::HPACK::Q_INSERT_NO_NAME_REF.

Referenced by allowVulnerable(), and encodeHeaderQ().

231  {
233  controlBuffer_, header, isStaticName, nameIndex,
236 }
const Instruction Q_INSERT_NO_NAME_REF
HPACKEncodeBuffer controlBuffer_
Definition: QPACKEncoder.h:115
void encodeLiteralQHelper(HPACKEncodeBuffer &buffer, const HPACKHeader &header, bool isStaticName, uint32_t nameIndex, uint8_t staticFlag, const HPACK::Instruction &idxInstr, const HPACK::Instruction &litInstr)
const uint8_t Q_INSERT_NAME_REF_STATIC
const Instruction Q_INSERT_NAME_REF
void proxygen::QPACKEncoder::encodeLiteralQ ( const HPACKHeader header,
bool  isStaticName,
bool  postBase,
uint32_t  nameIndex,
const HPACK::Instruction idxInstr 
)
private

Definition at line 238 of file QPACKEncoder.cpp.

References encodeLiteralQHelper(), proxygen::HPACK::Q_LITERAL, proxygen::HPACK::Q_LITERAL_STATIC, and proxygen::HPACKEncoderBase::streamBuffer_.

Referenced by allowVulnerable(), and encodeStreamLiteralQ().

242  {
243  DCHECK(!isStaticName || !postBase);
245  streamBuffer_, header, isStaticName, nameIndex,
246  HPACK::Q_LITERAL_STATIC, idxInstr,
248 }
void encodeLiteralQHelper(HPACKEncodeBuffer &buffer, const HPACKHeader &header, bool isStaticName, uint32_t nameIndex, uint8_t staticFlag, const HPACK::Instruction &idxInstr, const HPACK::Instruction &litInstr)
HPACKEncodeBuffer streamBuffer_
const Instruction Q_LITERAL
const uint8_t Q_LITERAL_STATIC
void proxygen::QPACKEncoder::encodeLiteralQHelper ( HPACKEncodeBuffer buffer,
const HPACKHeader header,
bool  isStaticName,
uint32_t  nameIndex,
uint8_t  staticFlag,
const HPACK::Instruction idxInstr,
const HPACK::Instruction litInstr 
)
private

Definition at line 250 of file QPACKEncoder.cpp.

References proxygen::HPACK::Instruction::code, proxygen::HPACKEncodeBuffer::encodeInteger(), proxygen::HPACKEncodeBuffer::encodeLiteral(), proxygen::HPACKHeaderName::get(), proxygen::HPACKHeader::name, proxygen::HPACK::Instruction::prefixLength, uint8_t, proxygen::QPACKHeaderTable::UNACKED, and proxygen::HPACKHeader::value.

Referenced by allowVulnerable(), encodeInsertQ(), and encodeLiteralQ().

256  {
257  // name
258  if (nameIndex) {
259  VLOG(10) << "encoding name index=" << nameIndex;
260  DCHECK_NE(nameIndex, QPACKHeaderTable::UNACKED);
261  uint8_t byte = idxInstr.code;
262  if (isStaticName) {
263  byte |= staticFlag;
264  } else {
265  DCHECK_GE(nameIndex, 1);
266  nameIndex -= 1;
267  }
268  buffer.encodeInteger(nameIndex, byte, idxInstr.prefixLength);
269  } else {
270  buffer.encodeLiteral(litInstr.code, litInstr.prefixLength,
271  header.name.get());
272  }
273  // value
274  buffer.encodeLiteral(header.value);
275 }
std::vector< uint8_t > buffer(kBufferSize+16)
QPACKEncoder::EncodeResult proxygen::QPACKEncoder::encodeQ ( const std::vector< HPACKHeader > &  headers,
uint64_t  streamId 
)
private

Definition at line 38 of file QPACKEncoder.cpp.

References allowVulnerable(), controlBuffer_, curOutstanding_, encodeHeaderQ(), proxygen::HPACKEncodeBuffer::encodeInteger(), proxygen::QPACKHeaderTable::getBaseIndex(), folly::gen::move, numVulnerable_, outstanding_, proxygen::HPACK::Q_DELTA_BASE, proxygen::HPACK::Q_DELTA_BASE_NEG, proxygen::HPACK::Q_DELTA_BASE_POS, proxygen::HPACKEncodeBuffer::release(), proxygen::HPACKEncoderBase::streamBuffer_, proxygen::QPACKContext::table_, uint32_t, and proxygen::QPACKEncoder::OutstandingBlock::vulnerable.

Referenced by allowVulnerable(), and encode().

38  {
39  auto& outstandingBlocks = outstanding_[streamId];
40  outstandingBlocks.emplace_back();
41  curOutstanding_ = &outstandingBlocks.back();
42  auto baseIndex = table_.getBaseIndex();
43 
44  uint32_t largestReference = 0;
45  for (const auto& header: headers) {
46  encodeHeaderQ(header, baseIndex, &largestReference);
47  }
48 
49  auto streamBlock = streamBuffer_.release();
50 
51  // encode the prefix
52  streamBuffer_.encodeInteger(largestReference);
53  if (largestReference > baseIndex) {
54  streamBuffer_.encodeInteger(largestReference - baseIndex,
56  HPACK::Q_DELTA_BASE.prefixLength);
57  } else {
58  streamBuffer_.encodeInteger(baseIndex - largestReference,
60  HPACK::Q_DELTA_BASE.prefixLength);
61  }
62  auto streamBuffer = streamBuffer_.release();
63  streamBuffer->prependChain(std::move(streamBlock));
64 
65  auto controlBuf = controlBuffer_.release();
66  // curOutstanding_.references could be empty, if the block encodes only static
67  // headers and/or literals
69  DCHECK(allowVulnerable());
71  }
72 
73  return { std::move(controlBuf), std::move(streamBuffer) };
74 }
QPACKHeaderTable table_
Definition: QPACKContext.h:54
std::unique_ptr< folly::IOBuf > release()
const uint8_t Q_DELTA_BASE_POS
HPACKEncodeBuffer controlBuffer_
Definition: QPACKEncoder.h:115
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
HPACKEncodeBuffer streamBuffer_
uint32_t getBaseIndex() const
OutstandingBlock * curOutstanding_
Definition: QPACKEncoder.h:123
void encodeHeaderQ(const HPACKHeader &header, uint32_t baseIndex, uint32_t *largestReference)
bool allowVulnerable() const
Definition: QPACKEncoder.h:66
uint32_t encodeInteger(uint64_t value, uint8_t instruction, uint8_t nbit)
const Instruction Q_DELTA_BASE
const uint8_t Q_DELTA_BASE_NEG
std::unordered_map< uint64_t, std::list< OutstandingBlock > > outstanding_
Definition: QPACKEncoder.h:122
void proxygen::QPACKEncoder::encodeStreamLiteralQ ( const HPACKHeader header,
bool  isStaticName,
uint32_t  nameIndex,
uint32_t  absoluteNameIndex,
uint32_t  baseIndex,
uint32_t largestReference 
)
private

Definition at line 184 of file QPACKEncoder.cpp.

References allowVulnerable(), encodeLiteralQ(), proxygen::HPACK::Q_LITERAL_NAME_REF, proxygen::HPACK::Q_LITERAL_NAME_REF_POST, and trackReference().

Referenced by allowVulnerable(), and encodeHeaderQ().

186  {
187  if (absoluteNameIndex > 0) {
188  // Dynamic name reference, vulnerability checks already done
189  CHECK(absoluteNameIndex <= baseIndex || allowVulnerable());
190  trackReference(absoluteNameIndex, largestReference);
191  }
192  if (absoluteNameIndex > baseIndex) {
193  encodeLiteralQ(header,
194  false, /* not static */
195  true, /* post base */
196  absoluteNameIndex - baseIndex,
198  } else {
199  encodeLiteralQ(header,
200  isStaticName,
201  false, /* not post base */
202  isStaticName ? nameIndex : baseIndex - absoluteNameIndex + 1,
204  }
205 }
const Instruction Q_LITERAL_NAME_REF_POST
void trackReference(uint32_t index, uint32_t *largestReference)
bool allowVulnerable() const
Definition: QPACKEncoder.h:66
void encodeLiteralQ(const HPACKHeader &header, bool isStaticName, bool postBase, uint32_t nameIndex, const HPACK::Instruction &idxInstr)
const Instruction Q_LITERAL_NAME_REF
std::tuple< bool, uint32_t, uint32_t > proxygen::QPACKEncoder::getNameIndexQ ( const HPACKHeaderName headerName)
private

Definition at line 161 of file QPACKEncoder.cpp.

References proxygen::QPACKHeaderTable::absoluteToRelative(), allowVulnerable(), proxygen::QPACKContext::getStaticTable(), maybeDuplicate(), proxygen::HeaderTable::nameIndex(), proxygen::QPACKHeaderTable::nameIndex(), proxygen::QPACKContext::table_, and uint32_t.

Referenced by allowVulnerable(), and encodeHeaderQ().

162  {
163  uint32_t absoluteNameIndex = 0;
164  uint32_t nameIndex = getStaticTable().nameIndex(headerName);
165  bool isStatic = true;
166  if (nameIndex == 0) {
167  // check dynamic table
168  nameIndex = table_.nameIndex(headerName, allowVulnerable());
169  if (nameIndex != 0) {
170  absoluteNameIndex = maybeDuplicate(nameIndex).second;
171  if (absoluteNameIndex) {
172  isStatic = false;
173  nameIndex = table_.absoluteToRelative(absoluteNameIndex);
174  } else {
175  nameIndex = 0;
176  absoluteNameIndex = 0;
177  }
178  }
179  }
180  return std::tuple<bool, uint32_t, uint32_t>(
181  isStatic, nameIndex, absoluteNameIndex);
182 }
QPACKHeaderTable table_
Definition: QPACKContext.h:54
std::pair< bool, uint32_t > maybeDuplicate(uint32_t relativeIndex)
bool allowVulnerable() const
Definition: QPACKEncoder.h:66
uint32_t absoluteToRelative(uint32_t absIndex) const
uint32_t nameIndex(const HPACKHeaderName &headerName) const
Definition: HeaderTable.cpp:88
const StaticHeaderTable & getStaticTable() const
Definition: QPACKContext.h:50
uint32_t nameIndex(const HPACKHeaderName &headerName, bool allowVulnerable=true) const
std::pair< bool, uint32_t > proxygen::QPACKEncoder::maybeDuplicate ( uint32_t  relativeIndex)
private

Definition at line 151 of file QPACKEncoder.cpp.

References allowVulnerable(), encodeDuplicate(), proxygen::QPACKHeaderTable::maybeDuplicate(), and proxygen::QPACKContext::table_.

Referenced by allowVulnerable(), encodeHeaderQ(), and getNameIndexQ().

152  {
153  auto res = table_.maybeDuplicate(relativeIndex, allowVulnerable());
154  if (res.first) {
155  VLOG(4) << "Encoded duplicate index=" << relativeIndex;
156  encodeDuplicate(relativeIndex);
157  }
158  return res;
159 }
QPACKHeaderTable table_
Definition: QPACKContext.h:54
void encodeDuplicate(uint32_t index)
bool allowVulnerable() const
Definition: QPACKEncoder.h:66
std::pair< bool, uint32_t > maybeDuplicate(uint32_t relativeIndex, bool allowVulnerable)
HPACK::DecodeError proxygen::QPACKEncoder::onHeaderAck ( uint64_t  streamId,
bool  all 
)

Definition at line 330 of file QPACKEncoder.cpp.

References folly::gen::all(), proxygen::ERROR, i, proxygen::HPACK::INVALID_ACK, folly::gen::move, proxygen::HPACK::NONE, numVulnerable_, outstanding_, proxygen::QPACKHeaderTable::setMaxAcked(), proxygen::QPACKHeaderTable::subRef(), and proxygen::QPACKContext::table_.

Referenced by decodeHeaderAck(), and TEST().

330  {
331  auto it = outstanding_.find(streamId);
332  if (it == outstanding_.end()) {
333  if (!all) {
334  LOG(ERROR) << "Received an ack with no outstanding header blocks stream="
335  << streamId;
337  } else {
338  // all implies a reset, meaning it's not an error if there are no
339  // outstanding blocks
341  }
342  }
343  VLOG(5) << ((all) ? "onCancelStream" : "onHeaderAck") << " streamId="
344  << streamId;
345  if (all) {
346  // Happens when a stream is reset
347  for (auto& block: it->second) {
348  for (auto i: block.references) {
349  table_.subRef(i);
350  }
351  if (block.vulnerable) {
352  numVulnerable_--;
353  }
354  }
355  it->second.clear();
356  } else {
357  auto block = std::move(it->second.front());
358  it->second.pop_front();
359  // a different stream, sub all the references
360  for (auto i: block.references) {
361  VLOG(5) << "Decrementing refcount for absoluteIndex=" << i;
362  table_.subRef(i);
363  }
364  if (block.vulnerable) {
365  numVulnerable_--;
366  }
367  // largest reference is implicitly acknowledged
368  if (!block.references.empty()) {
369  auto largestReference = *block.references.rbegin();
370  VLOG(5) << "Implicitly acknowledging absoluteIndex=" << largestReference;
371  table_.setMaxAcked(largestReference);
372  }
373  }
374  if (it->second.empty()) {
375  outstanding_.erase(it);
376  }
378 }
QPACKHeaderTable table_
Definition: QPACKContext.h:54
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
void setMaxAcked(uint32_t maxAcked)
void subRef(uint32_t absIndex)
std::unordered_map< uint64_t, std::list< OutstandingBlock > > outstanding_
Definition: QPACKEncoder.h:122
Composed all(Predicate pred=Predicate())
Definition: Base.h:786
void proxygen::QPACKEncoder::setHeaderTableSize ( uint32_t  size)
inline

Definition at line 57 of file QPACKEncoder.h.

References proxygen::HPACKEncoderBase::setHeaderTableSize(), and proxygen::QPACKContext::table_.

Referenced by TEST().

57  {
59  }
QPACKHeaderTable table_
Definition: QPACKContext.h:54
constexpr auto size(C const &c) -> decltype(c.size())
Definition: Access.h:45
void setHeaderTableSize(HeaderTable &table, uint32_t size)
void proxygen::QPACKEncoder::setMaxVulnerable ( uint32_t  maxVulnerable)
inline

Definition at line 61 of file QPACKEncoder.h.

References maxVulnerable_.

Referenced by TEST().

61  {
62  maxVulnerable_ = maxVulnerable;
63  }
bool proxygen::QPACKEncoder::shouldIndex ( const HPACKHeader header) const
private

Definition at line 146 of file QPACKEncoder.cpp.

References proxygen::HPACKHeader::bytes(), proxygen::HeaderTable::capacity(), proxygen::HeaderIndexingStrategy::indexHeader(), proxygen::HPACKEncoderBase::indexingStrat_, and proxygen::QPACKContext::table_.

Referenced by allowVulnerable(), and encodeHeaderQ().

146  {
147  return (header.bytes() <= table_.capacity()) &&
149 }
QPACKHeaderTable table_
Definition: QPACKContext.h:54
uint32_t capacity() const
Definition: HeaderTable.h:86
virtual bool indexHeader(const HPACKHeader &header) const
const HeaderIndexingStrategy * indexingStrat_
void proxygen::QPACKEncoder::trackReference ( uint32_t  index,
uint32_t largestReference 
)
private

Definition at line 207 of file QPACKEncoder.cpp.

References proxygen::QPACKHeaderTable::addRef(), curOutstanding_, proxygen::QPACKHeaderTable::isVulnerable(), proxygen::QPACKEncoder::OutstandingBlock::references, proxygen::QPACKContext::table_, and proxygen::QPACKEncoder::OutstandingBlock::vulnerable.

Referenced by allowVulnerable(), encodeHeaderQ(), and encodeStreamLiteralQ().

208  {
209  CHECK_NE(absoluteIndex, 0);
210  CHECK(curOutstanding_);
211  if (absoluteIndex > *largestReference) {
212  *largestReference = absoluteIndex;
213  if (table_.isVulnerable(absoluteIndex)) {
214  curOutstanding_->vulnerable = true;
215  }
216  }
217  auto res = curOutstanding_->references.insert(absoluteIndex);
218  if (res.second) {
219  VLOG(5) << "Bumping refcount for absoluteIndex=" << absoluteIndex;
220  table_.addRef(absoluteIndex);
221  }
222 }
QPACKHeaderTable table_
Definition: QPACKContext.h:54
OutstandingBlock * curOutstanding_
Definition: QPACKEncoder.h:123
bool isVulnerable(uint32_t absIndex) const
void addRef(uint32_t absIndex)

Member Data Documentation

HPACKEncodeBuffer proxygen::QPACKEncoder::controlBuffer_
private

Definition at line 115 of file QPACKEncoder.h.

Referenced by encode(), encodeDuplicate(), encodeInsertQ(), and encodeQ().

OutstandingBlock* proxygen::QPACKEncoder::curOutstanding_ {nullptr}
private

Definition at line 123 of file QPACKEncoder.h.

Referenced by encodeQ(), and trackReference().

folly::IOBufQueue proxygen::QPACKEncoder::decoderIngress_ {folly::IOBufQueue::cacheChainLength()}
private

Definition at line 127 of file QPACKEncoder.h.

Referenced by decodeDecoderStream().

uint32_t proxygen::QPACKEncoder::maxDepends_ {0}
private

Definition at line 124 of file QPACKEncoder.h.

uint32_t proxygen::QPACKEncoder::maxVulnerable_ {HPACK::kDefaultBlocking}
private

Definition at line 125 of file QPACKEncoder.h.

Referenced by allowVulnerable(), and setMaxVulnerable().

uint32_t proxygen::QPACKEncoder::numVulnerable_ {0}
private

Definition at line 126 of file QPACKEncoder.h.

Referenced by allowVulnerable(), encodeQ(), and onHeaderAck().

std::unordered_map<uint64_t, std::list<OutstandingBlock> > proxygen::QPACKEncoder::outstanding_
private

Definition at line 122 of file QPACKEncoder.h.

Referenced by encodeQ(), and onHeaderAck().


The documentation for this class was generated from the following files: