Summary:
Due to high number of RTT samples I refactored the OutstandingPacket to
split the packet data and packet metrics. We know have access to metrics
without the need of saving the packet data.
Pull Request resolved: https://github.com/facebookincubator/mvfst/pull/178
Reviewed By: mjoras
Differential Revision: D23711641
Pulled By: bschlinker
fbshipit-source-id: 53791f1f6f6e184f37afca991a873af05909fbd2
Summary:
This glues together the d6d lifecycle via probe timeout and raise timeout.
Had to put these two timeouts in the base transport because it has all the
necessary accountings (e.g. check close state, process callbacks) that should
happen before scheduling timeouts.
Other notable changes (included here because code is simple):
- Keep track of d6d probes in loss state. Upon second thought, it makes more
sense because we are reducing the available bandwidth as a result of sending
probes anyway. And not tracking them imposes a delay on congestion controller.
I think this does not violate the d6d spec's point of not penalizing congestion
window for d6d probes, because
- 1. we don't put losses of d6d probes in loss event. Therefore from the POV of
congestion controller, d6d probes never get lost.
- there will be at most kDefaultD6DMaxOutstandingProbes losses (i.e. 2)
that we don't tell congestion controller about. Even if those are actually
caused by congestion, it should have minimal impact because 2 is small and if there's really a congestion, the loss of normal packets should provide the signal.
- Pacing d6d probes
- Kick off d6d after a delay of 1s. This should filter out short-lived connections where probing is relatively expensive and less useful.
Reviewed By: mjoras
Differential Revision: D23736656
fbshipit-source-id: 8121fa8bcebab10a56a4e046c32c4e99ed6c3013
Summary:
This should be a noop in our current set up. I added some comments to clarify
the logic. Put it in another way,
- `udpSendPacketLen = f(max_packet_size, kDefaultMaxUDPPayload, canIgnorePathMTU)`
- `d6d.maxPMTU = g(max_packet_size, kDefaultMaxUDPPayload, d6dConfig.enabled)`
`f` and `g` are what the code does.
Reviewed By: mjoras
Differential Revision: D23745844
fbshipit-source-id: bc8c38a8a9086fe31e5f367d01737f360c403353
Summary:
Similar to raise timeout, client can choose the probe timeout via transport
parameter. This timeout might not end up being useful because by the time the
recommended timeout (15s) expires, either:
i. the probe gets acked, d6d send a larger probe or sleeps if the upper bound
is found
ii. the probe is lost, then quic will likely determine its loss faster than
15s, upon which a PMTU blackhole is recognized
So adding this is mostly for mvfst to be compliant with the d6d spec, and
potentially useful if we want to control probe sending rate upon ack, e.g. send
the next probe after 1s upon ack instead of immediately.
Reviewed By: yangchi
Differential Revision: D23700182
fbshipit-source-id: 18b740d05343591d6afa086b9fae746e6c71aca5
Summary:
Currently it logs error even if transport parameters are not present, but in
that we should assume the client doesn't want d6d, so we should not log error at
all.
Reviewed By: yangchi
Differential Revision: D23681935
fbshipit-source-id: 6420ff3053cd6c7d2d0ddad854f481e4f422c992
Summary:
According to the spec, loss of d6d probe packet should not affect congestion
control, but AFAIU its ack should be considered a normal ack and has all the
implications of an ack (e.g. sample srtt, increment largest ack num).
Additionally, although d6d probe uses ping frame, neither sending a d6d probe
nor receiving the ack should have any bearing on either pendingEvents.sendPing
or pendingEvents.cancelPingTimeout.
To differentiate a d6d probe from a normal packet in tx/rx path, the isD6DProbe
flag is added. I also added a new struct to store d6d specific states (1 field
in this diff, more to come in subsequent diffs). In updateConnection, we
identify a d6d probe by comparing the packet sequence num with the sequence num
stored in the lastProbe field of the d6d state.
Reviewed By: mjoras
Differential Revision: D22551400
fbshipit-source-id: 85ec30c185666c3d5cf827bf03b4f92e6f22d4ec
Summary: This enables the TokenlessPacer if the version is MVFST_EXPERIMENAL.
Reviewed By: yangchi
Differential Revision: D23600318
fbshipit-source-id: 22f2c702a0aa7f1219d3a84bb21a4ad6135240b5
Summary:
This will make migrating the fizz parts way easier.
Pull Request resolved: https://github.com/facebookincubator/mvfst/pull/161
Reviewed By: yangchi
Differential Revision: D23560257
Pulled By: xttjsn
fbshipit-source-id: 1f0f78f26d221f23542a9d900b23ba0bc4e60f6d
Summary:
As a second attempt to add d6d, I tried to be as non-intrusive as possible, by de-coupling all state that d6d needs from the existing transport state.
To reduce complexity, I made the assumption that, as a starter, only server does the probing. To make it easy to control d6d in different connection settings, both the server and the client has a toggle `enabled`. It is only when both the server and client are `enabled`, that server will do probing for a connection.
Among all the changes, this adds:
- Two transport parameters:
- `d6d_base_pmtu`: this is the base PMTU client advertises to server during handshake. A valid presence of this value indicates that clients d6d module is `enabled`. Although this config value is not used by server, I kept it in `D6DConfig` to avoid complexity and make it possible for future extension where clients might also do probing.
- `d6d_raise_timeout`: this is the raise timeout client advertises to server during handshake. It is the amount of time d6d "sleeps" after it finds an upper bond. It is optional. We want this because depending on the network conditions we might need to adjust this timeout.
Reviewed By: mjoras
Differential Revision: D23409623
fbshipit-source-id: bad6df443cc13dc4d69532342f182cb919c5a7dd
Summary:
First step towards d6d. Semantically we need to separate the old `udpSendPacketLen` into `peerMaxPacketSize` as well as `currPMTU`. The former is directly tied to the peer's max_packet_size transport parameter whereas the second is controlled by d6d. To get the actual udp mss, call `conn_->getUdpSendPacketLen()`, which will use the minimum of the two if d6d is enabled, otherwise it will fallback to use `peerMaxPacketSize` only.
During processClientInitialParams and processServerInitialParams, we no longer need to check whether `canIgnorePathMTU` is set because that logic is moved to `setUdpSendPacketLen`. If d6d is enabled, we set both `peerMaxPacketSize` and `currPMTU` to `packetSize` because receiving an initial packet of size x indicates both that the peer accepts x-sized packet and that the PMTU is at least x.
Many call sites and tests are changed.
Faebook:
For now, d6d is considered enabled if `canIgnorePathMTU==false` and `turnoffPMTUD==true`. Down the road, from semantic & practical POV at least one of them should be renamed to something like `enableD6D`, since enabling d6d implies turning off PMTUD and that we should not ignore PMTU. We can keep one for the sake of testing.
Reviewed By: mjoras
Differential Revision: D22049806
fbshipit-source-id: 7a9b30b7e2519c132101509be56a9e63b803dc93
Summary:
This should be safe, as by the time we have successfully decrypted a handshake packet there's no more initial data.
The caveat here, I suppose, is that we are now relying on an implicit ACK of the initial instead of an explicit RTT signal.
Reviewed By: yangchi
Differential Revision: D22667820
fbshipit-source-id: 8d34e063d4bf4bb435db09694153fbaa0f061be1
Summary:
The problem with Ping being a simple frame:
(1) All SimpleFrames are in the same scheduler. So sending ping means we may
also send other frames which can be problematic if we send in Initial or
Handshake space
(2) Ping isn't retranmisttable. But other Simple frames are. So we are
certainly setting this wrong when we send pure Ping packet today.
That being said, there are cases where we need to treat Ping as retransmittable.
One is when it comes to update ack state: If peer sends us Ping, we may want to
Ack early rather than late. so it makes sense to treat Ping as retransmittable.
Another place is insertion into OutstandingPackets list. When our API user sends
Ping, then also add a Ping timeout. Without adding pure Ping packets into OP list,
we won't be able to track the acks to our Pings.
Reviewed By: mjoras
Differential Revision: D21763935
fbshipit-source-id: a04e97b50cf4dd4e3974320a4d2cc16eda48eef9
Summary:
This implements the connection ID validation via transport parameters. Note we don't do anything with the retry transport parameter yet.
This will probably require further surgery to tests when we want the MVFST version to do this, but for now I'm punting on that test plumbing.
This retains support for h3-27.
Reviewed By: yangchi
Differential Revision: D22045631
fbshipit-source-id: e93841e734c0683655c751d808fd90b3b391eb3e
Summary:
Now we won't have a zero PTO and we will properly clear out the outstanding packets.
Note that this cipher dropping is not what the draft prescribes, instead dropping both the initial and handshake ciphers when we know 1-rtt communication is functioning.
Reviewed By: yangchi
Differential Revision: D20388737
fbshipit-source-id: 0b89eb80c8faa796ab09eda3eaa10a00dcf7bae9
Summary: This diff adds a new RetryPacket type, without changing any existing functionality.
Reviewed By: mjoras
Differential Revision: D19631435
fbshipit-source-id: 227864ee8f276fe4c593d5aa37209ca77267310d
Summary: This will limit us to standard Ethernet MTU (1500) for now, but I think that is fine. This will allow us to experiment with packet size from the client more easily.
Reviewed By: yangchi
Differential Revision: D20709146
fbshipit-source-id: 608463de53d4520a257052491683263e14fc9682
Summary:
When parsePacket returns anything other than RegularPacket, we already
log the Drop even inside the switch-case blocks before checking if
RegularPacket has been parsed. So the logging of Drop with PARSE_ERROR when the
CodecResult isn't RegularPacket is wrong. For example, right now when we
buffer 0-rtt data, we always log a Drop immediatly afterwards into QLog which
is incorrect.
Reviewed By: JunqiWang
Differential Revision: D20421934
fbshipit-source-id: d836700fd691645951d5e5b49b19cbcc1e5df51a
Summary: In the constructor of FileQlogger adds a bool that sets streaming mode. If it's set it creates a thread that reads events from the log and immediatly outputs them to an output file.
Reviewed By: mjoras
Differential Revision: D20250881
fbshipit-source-id: 2af3ff0aeaa5b62f90b0c01570c96c92fdab4412
Summary:
The CID Algo can possibly generate a CID that's already in the map.
This diff adds a mechanism to reject such CID and try another one.
ServerStateMachine will loop encoding CIDs until either QuicServerWorker no
longer rejects, or encode fails
Reviewed By: udippant, vchynarov
Differential Revision: D20251043
fbshipit-source-id: a38e4e8b33007779a9710c32057d47f32f7d1774
Summary: This has a mandatory minimum of 2. This diff doesn't fix the unit tests which use a lower value, but currently other clients will fail our connection as this is a MUST.
Reviewed By: lnicco
Differential Revision: D20299054
fbshipit-source-id: 769337ccc5bdf75b7b85518bf88e393979b63f3f
Summary:
This iterates the mvfst version to be semantically equivalent to draft-27, and leaves support for the old mvfst version.
The client will not yet be moved to draft-27 by default.
Reviewed By: lnicco
Differential Revision: D20182452
fbshipit-source-id: 1e11ad7296a6cd8d15ca5ed359d9ed82af79bb17
Summary:
The transport parameters format changed in draft 27. It is now self describing via varints.
This diff retains support for the old encoding and does not iterate the mvfst version.
Reviewed By: lnicco
Differential Revision: D20149977
fbshipit-source-id: c6fa9c226f859ed81ca83ada5a8bc5832b4a3388
Summary: This is without cipher dropping, but the frame is parseable and the server will send it at the correct time.
Reviewed By: yangchi, lnicco
Differential Revision: D20235013
fbshipit-source-id: 696c11ec573a530b3ed9f4185a2f6847ee08819f
Summary:
This eliminatees some tech debt by completely removing the notion of version from the core transport parameters structure and the app token for zero rtt.
Note that for the draft-27 changes we will need to temporarily re-introduce it, but to a different layer (the extension encoding itself).
Reviewed By: JunqiWang
Differential Revision: D20073578
fbshipit-source-id: 2b55af621566bf1c20e21dd17251116de1788fa0
Summary: This implements the handshake done signal and also cipher dropping.
Reviewed By: yangchi
Differential Revision: D19584922
fbshipit-source-id: a98bec8f1076393b051ff65a2d8aae7d572b42f5
Summary: no more surprises in upper layer
Reviewed By: mjoras
Differential Revision: D19976510
fbshipit-source-id: 3487e9aa2cb28d7bc748f13bc2bbc393216b4a8a
Summary:
Remove all the stream events, packet/udp recv event and ack event.
They are >40% of the events.
Reviewed By: mjoras
Differential Revision: D19466165
fbshipit-source-id: 3a20b201e630527e6d25d1a14f0f520728190d50
Summary: This is a somewhat arbitrary limit, but is useful for keepin a client from making the server build an enormous packet.
Reviewed By: yangchi
Differential Revision: D19438682
fbshipit-source-id: 2ec3b8c8ba630804e954f606ada2cc00682b3657
Summary:
Previously we stored an `IntervalSet` in each `WriteAckFrame`. We don't need to do this, as by the time we are writing an `ACK` the `IntervalSet` is complete. Instead of bothering with the `IntervalSet` operations, we can simply serialize it to a reverse-sorted `vector.`
Additionally this has some micro-optimizations for filling the ACK frame, with a new function for getting varint size.
Reviewed By: yangchi
Differential Revision: D19397728
fbshipit-source-id: ba6958fb36a4681edaa8394b1bcbbec3472e177d
Summary:
This moves the fizz specific part of the handshake into its own folder and library.
There is a bit of smurf naming going on as a result, not sure it is worth fixing or not at this stage. Maybe this code should be a in namespace named quic::fizz .
This should be doable with the client as well as soon as the key cache situation is figured out.
---
## Proxygen Canary
Reviewed By: yangchi
Differential Revision: D19290919
fbshipit-source-id: 48d7f7c70db42c65f7dffe3256805c268a481198
Summary:
Don't use IOBufQueue for most operations in mvfst and use BufQueue instead. Since BufQueue did not support a splitAtMost, added it in instead.
The only place that we still use IOBufQueue is in crypto because fizz still requires it
Reviewed By: mjoras
Differential Revision: D18846960
fbshipit-source-id: 4320b7f8614f8d2c75f6de0e6b786d33650e9656
Summary:
In the current client code we read one packet, go back to epoll, and then read
another packet. This is not very efficient.
This changes it so that we can read multiple packets in one go from an epoll
callback.
This only performs changes on the client
Reviewed By: mjoras
Differential Revision: D18797962
fbshipit-source-id: 81be82111064ade4fe3a07b1d9d3d01e180f29f5
Summary: As a part of Draft 17, application close frame has been removed, we use connection close frame to represent both application close and connection close.
Reviewed By: mjoras
Differential Revision: D18580856
fbshipit-source-id: d274fa2d3dbc59b926bca5a2b8a20328ae582703
Summary:
Client will set their active_connection_id_limit to the server as 7 (so it will
have 8 conn ids in total).
Reviewed By: JunqiWang
Differential Revision: D18532441
fbshipit-source-id: b0be65cec9f7c483469b0b4a2810bc370a6945c3
Summary: The state machine logic is quite abstruse, this modifies it to make it more readable.
Reviewed By: siyengar
Differential Revision: D18488301
fbshipit-source-id: c6fd52973880931e34904713e8b147f56d0c4629
Summary:
Use the Path rate limiter introduced in the previous diff.
When we initialize path validation of an unvalidated peer address,
enable pathValidationRateLimit.
When we receive a proper PATH_RESPONSE frame, disable this limit.
If this limit is enabled, we will check the pathValidationLimiter for
the amount of bytes we are allowed to write.
Change the migration tests in QuicServerTransportTest to use this new limiter
instead of writableByteLimits.
Update shouldWriteData to directly use the new congestionControlWritableBytes
function.
Reviewed By: yangchi
Differential Revision: D18145774
fbshipit-source-id: 1fe4fd5be7486077c58b0d1285dfb03f6c62831c
Summary: 0-RTT packet is also in AppData pn space
Reviewed By: vchynarov
Differential Revision: D18353017
fbshipit-source-id: a39fe5aae823fbe0d7522f895cff05cc9395928b
Summary:
QLogConnectionMigrationEvent:
Allow observing client-side ConnectionMigration attempts (replacing the
socket), and observing the server-side changing the peer address it
is writing to.
QLogPathValidationEvent:
Allow observing successful/failed path validation attempts.
Success is considered as a correct PathResponse being returned.
A Failure is only published on the timeout expiring, not an invalid
PathChallenge frame being returned (we do not cancel this).
There are already QlogEvents for PathChallenge/PathResponse that
can be observed.
Reviewed By: JunqiWang
Differential Revision: D18340999
fbshipit-source-id: 512108f82a6e082021c0bd3254f108c128b17ba3
Summary:
When server has a pending path challenge frame to be sent, it's
possible that client can migrate again. This diff handles that case.
Reviewed By: vchynarov
Differential Revision: D18351213
fbshipit-source-id: c6887db0274ccddf267eb227de0a7de7ee103b4c
Summary:
Using the helper introduced in the previous diff, we replace generating the
initial server connection id, adding it to the selfConnectionIds, and
generating the initial stateless reset token.
Reviewed By: yangchi
Differential Revision: D18066595
fbshipit-source-id: f37450eecf0926ec145bc7a7194f2a1651cae024
Summary:
My goal in this stack is to properly support the functionality of issuing new
connection ids.
There are at least three cases in which this is done (server-side):
* generate initial server connection id based on host id parameters
* provide several NewConnectionId frames to the client (for use with
migration) after handshake
* responding to RetireConnectionIdFrame and issuing more NewConnectionId frames
as needed
**Changes**:
* move connIdAlgo away from parent ConnectionStateBase to just
QuicServerConnectionState
* create virtual function in ConnectionStateBase to generate
folly::none ConnectionIdData by default,
and server subclass will generate a new server id
* add unit tests to test this behaviour.
Intended for Junqi's diff of server issuing 7 new connection ids
to be rebased on this (D15178642)
Reviewed By: yangchi
Differential Revision: D17840780
fbshipit-source-id: 1a01077742d01d058eb0a726c4c9c44e39eafb24