tfpauly / draft-pauly-quic-datagram Goto Github PK
View Code? Open in Web Editor NEWAn Unreliable Datagram Extension to QUIC
An Unreliable Datagram Extension to QUIC
From @martinthomson (link to email):
Is it illegal to send an empty DATAGRAM frame?
Flow control is painful because getting it wrong is painful.
Not having flow control doesn't mean having it done right!
Would be great to have a brief reminder around this in the draft!
We should add text on how DATAGRAM frames interact with congestion control. In particular they should be congestion controlled so an application that sends too much data will not flood the network.
Right now, the TP specifies a maximum frame size, including frame type, length and payload. This makes certain values invalid (0, 1?). Also, since this values practically is a kind of flow control, indicating how much data I'm willing to receive at a time, it's the payload length that's important here, not the framing.
For these reasons, I'm arguing to change this to specifying a maximum payload length. Then, the question of what a value of zero means. Should a value of 0 be the same thing as not present or should it mean that only 0 length datagrams are allowed? I think it is simpler to say that a value of zero is the same as not present (i.e. disabled).
We should add text to explain how the application may effectively still have smaller datagram payload sizes due to small PMTU (and interface MTU) even if the max datagram frame size is large. Essentially, the effective at any point is the MIN(max frame size, PMTU, MTU)
This spec currently is missing details on 0-RTT. Specifically:
The definition of new transport parameters (Section 7.3.2) MUST specify whether they MUST, MAY, or MUST NOT be stored for 0-RTT.
How to handle the new TP after 0-RTT. For example, the TP can be completely gone (and DATAGRAM becomes unsupported) or it could decrease or increase the size of the DATAGRAM.
If we tell implementations to store the TP with the 0-RTT metadata, it's possible that we can send DATAGRAM frames in 0-RTT packets but suddenly we won't be able to send any more DATAGRAM frames if the TP is missing after the handshake. We need language to clarify what to do in this case.
If a sender detects that a packet containing a specific DATAGRAM frame has been lost, the implementation MAY notify the application that the datagram was lost. Similarly, if a packet containing a DATAGRAM frame is acknowledged, the implementation MAY notify the application that the datagram was successfully transmitted and received.
A lost DATAGRAM is not necessarily lost. It might be received by the peer after it is deemed lost. The late receiving peer cannot trivially be sure the sender thinks the frame is lost so it has a choice to make to drop the DATAGRAM or to give it to the application. Likely it will give it to the application. Hence, a lost DATAGRAM is merely suggestive of a possibly loss, and at least a delayed delivery.
As QUIC transport provides congestion control, the receiver SHOULD acknowledge all the datagram frames that it received even if it is about to drop it. Some applications might do it implicitly but we want to ensure that all of them comply. Otherwise the congestion control will continue to lower the congestion window without any actual network loss.
This is even more important as the unreliable QUIC doesn't provide flow control.
Should we call DATAGRAM ID -> DATAGRAM FLOW ID?
This may be a bit clearer
From @martinthomson (link to email):
The bit that mentions flow identifiers shouldn't presume so much about how these frames will be used. The only point you need to make is that it is up to the protocol in use to define how the receiver of a DATAGRAM frame processes that frame. If you are going to make a point, you might observe that it might be desirable in some protocols to have multiple logical entities receiving DATAGRAM frames, in which case it is up to the protocol to define how DATAGRAM frames are efficiently routed to one of those entities.
I think we need per datagram flow control along with the per stream flow control. Otherwise the sender could end up using the connection level flow control entirely for the datagram flow and stream flows won't get any chance to send data.
Now the implementation could provide some internal flow control for the datagram flow but it would be non-trivial. It would entail the following on every send on datagram flow:
If we want to skip these steps and allow datagram flow to grow to connection-level flow control, the application would need to manage its sends between streams and datagram flows which I think is not ideal.
I think adding some form of flow control for datagram flow would solve the sender’s conundrum.
The introduction says:
This document defines four new DATAGRAM QUIC frame types, which carry
application data without requiring retransmissions.
However, only two types seem to be defined with code points 0x30 and 0x31.
Rephrasing what I mentioned at the mic, imagine a scenario where an application uses DATAGRAM to send a single fixed message ("fire the missile"). An adversary on path can start selectively dropping packets and checking to see whether or not they're retransmitted to learn whether or not this special message was sent. (Retransmission detection could be done by looking at the size of the QUIC packet carrying the DATAGRAM, for example.)
I don't claim this is easy to do in practice, or useful, but I think it does raise interesting questions about how this new frame affects QUIC's security posture. Perhaps some text in the security considerations is needed?
If an API allows the creation of a QUIC stream before the connection is established, this API might also allow the creation of a DATAGRAM stream. If the remote endpoint doesn't support the DATAGRAM extension, the implementation can either return an error to the application ("failed to create stream") or it could simply convert the stream abstraction to use QUIC STREAM frames instead. There are arguments on both sides and it depends on the specific application, but I'm creating this issue because perhaps this ought to be mentioned in the spec.
"This frame SHOULD NOT be delayed, but MAY be coalesced with other STREAM or DATAGRAM frames."
Is STREAM or DATAGRAM important? Instead, should we just say:
"This frame SHOULD NOT be delayed, but MAY be coalesced with other frames."
At the side meeting in Prague, we had lots of discussion about whether or not DATAGRAM frames should include the ID field. Creating this issue to track resolving that discussion.
We have a need for text regarding prioritization in the document, similar to the “Stream Prioritization” section in the main transport document. The application should be able to indicate to the quic implementation the relative priority of a flow of datagrams with regards to other streams and other flows, thus indicating how to schedule frames when congestion control opens up.
If I understand correctly, The endpoint can set a max_datagram_frame_size that is too small (0-1) for the peer to send DATAGRAM frames.
The specification says as follows
The max_datagram_frame_size transport parameter is an integer value (represented as a variable-length integer) that represents the maximum size of a DATAGRAM frame (including the frame type, flow identifier, length and payload) the endpoint is willing to receive, in bytes.
Type (1byte), Flow ID (0 ~ 8bytes), Length (0 ~ 8bytes). To send payload, it needs to be larger than 1byte, and if Flow ID and Length are used, larger value is necessary.
I suppose that max_datagram_frame_size (0-1) should be forbidden, or define recommended values to support. I suppose that behavior should be defined when an endpoint that needs to send DATAGARAM frames receives max_datagram_frame_size with insufficient value .
By defining in this specification, specifications that reference this specification do not need to consider it.
thank you
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.