Send knob frames for transport knobs
Summary: Adds routines to send transport knobs.
MODIFY
quic/api/QuicTransportBase.cpp
quic/api/QuicTransportBase.cpp
@@ -1621,8 +1621,13 @@ void QuicTransportBase::processCallbacksAfterWriteData() {
void QuicTransportBase::handleKnobCallbacks() {
for (auto& knobFrame : conn_->pendingEvents.knobs) {
+ if (knobFrame.knobSpace != kDefaultQuicTransportKnobSpace) {
connCallback_->onKnob(
knobFrame.knobSpace, knobFrame.id, std::move(knobFrame.blob));
+ } else {
+ // KnobId is ignored
+ onTransportKnobs(std::move(knobFrame.blob));
+ }
}
conn_->pendingEvents.knobs.clear();
}
@@ -3071,4 +3076,12 @@ const QuicTransportBase::ByteEventMap& QuicTransportBase::getByteEventMapConst(
folly::assume_unreachable();
}
+void QuicTransportBase::onTransportKnobs(Buf knobBlob) {
+ // Not yet implemented,
+ VLOG(4) << "Received transport knobs: "
+ << std::string(
+ reinterpret_cast<const char*>(knobBlob->data()),
+ knobBlob->length());
+}
+
} // namespace quic

MODIFY
quic/api/QuicTransportBase.h
quic/api/QuicTransportBase.h
@@ -726,6 +726,11 @@ class QuicTransportBase : public QuicSocket {
void scheduleD6DProbeTimeout();
void scheduleD6DTxTimeout();
+ /**
+ * Callback when we receive a transport knob
+ */
+ void onTransportKnobs(Buf knobBlob);
+
struct ByteEventDetail {
ByteEventDetail(uint64_t offsetIn, ByteEventCallback* callbackIn)
: offset(offsetIn), callback(callbackIn) {}

MODIFY
quic/client/QuicClientTransport.cpp
quic/client/QuicClientTransport.cpp
@@ -685,6 +685,8 @@ void QuicClientTransport::onReadData(
socket_->setErrMessageCallback(nullptr);
connCallback_->onReplaySafe();
}
+
+ maybeSendTransportKnobs();
}
void QuicClientTransport::writeData() {
@@ -1686,4 +1688,21 @@ void QuicClientTransport::trackDatagramReceived(size_t len) {
QUIC_STATS(statsCallback_, onRead, len);
}
+void QuicClientTransport::maybeSendTransportKnobs() {
+ if (!transportKnobsSent_ && hasWriteCipher()) {
+ for (const auto& knob : conn_->transportSettings.knobs) {
+ auto res =
+ setKnob(knob.space, knob.id, folly::IOBuf::copyBuffer(knob.blob));
+ if (res.hasError()) {
+ if (res.error() != LocalErrorCode::KNOB_FRAME_UNSUPPORTED) {
+ LOG(ERROR) << "Unexpected error while sending knob frames";
+ }
+ // No point in keep trying if transport does not support knob frame
+ break;
+ }
+ }
+ transportKnobsSent_ = true;
+ }
+}
+
} // namespace quic

MODIFY
quic/client/QuicClientTransport.h
quic/client/QuicClientTransport.h
@@ -213,6 +213,12 @@ class QuicClientTransport
void adjustGROBuffers();
void trackDatagramReceived(size_t len);
+ /**
+ * Send quic transport knobs defined by transportSettings.knobs to peer. This
+ * calls setKnobs() internally.
+ */
+ void maybeSendTransportKnobs();
+
bool replaySafeNotified_{false};
// Set it QuicClientTransport is in a self owning mode. This will be cleaned
// up when the caller invokes a terminal call to the transport.
@@ -227,5 +233,7 @@ class QuicClientTransport
// supports GRO. otherwise kDefaultNumGROBuffers
uint32_t numGROBuffers_{kDefaultNumGROBuffers};
RecvmmsgStorage recvmmsgStorage_;
+ // We will only send transport knobs once, this flag keeps track of it
+ bool transportKnobsSent_{false};
};
} // namespace quic

Send knob frames for transport knobs

Summary: Adds routines to send transport knobs.

Reviewed By: mjoras

Differential Revision: D23825714

fbshipit-source-id: a61b5650eacf0767054e18b59c731072e364c9b2