-
Notifications
You must be signed in to change notification settings - Fork 203
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: Begin lightly abstracting over the use of UDP as the underlying transport #4043
Conversation
…transport Based on recent mailing list feedback that this might possibly be OK, I decided to take a crack at reducing the "hard coding" of UDP in the spirit of other RFCs which strive to be agnostic to the underlying protocol. Due to the controversy over this, I imposed these constraints on myself to try to be as conservative as possible. - Absolutely no design changes on things which are already standardized, just editorial changes, and very simple extrapolation of the existing design. (I never ever considered the former at this time, just documenting this for posterity. - Anything that is not UDP (over IP) is deemed experimental. The size limitations I figure may not make sense for other transports / during other experiments, so I call that out. - When UDP was mentioned in some interesting way that generalized (e.g. something that separately mentions IP address and UDP port), I provide the general language (plain "address", but also provide the UDP common case as before so no specificity is lost. The purpose of this exercise is *not* to get QUIC over UDP "more ready for production", as that would slow down the WG for little gain, but rather to call out the dependencies that currently do exist so as to be sure there is no unintentional coupling. I fully leave to others to decide what coupling is intenional or unintentional, and whether anything at all is cause for concern. ---- In this first commit, I just audited all the occurrence of "UDP". If this looks good, I would then go back and likewise scan for "port" "IPv4", and "IPv6". My one regret is that in keeping the line length the same, I made the diff more complicated than it would otherwise be. Do you all have a process for that?
49fd64f
to
ca022d8
Compare
Hi @Ericson2314. Would you mind creating an accompanying issue for this PR so that we can track continued discussion on the concept of abstracting UDP. The PR can then stay focused on discussion of the file changes. Wrt line length, that's just something we have grown to deal with. Well done for keeping the CI checks happy on your first attempt 👍 |
: A message of the underlying transport protocol, which when used by QUIC will | ||
contain multiple QUIC packets. Calling this a "datagram" and not a "packet" | ||
emphasizes the message-oriented nature of the underlying transport, and helps | ||
distinguish these from QUIC packets. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you suggesting that that the underling transport has to be message based? That seems to be a large caveat that restricts the value of these changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on the feedback thread, I was trying to be super conservative, even if that risks an "any color as long as it's black" situation where UDP is basically the only protocol that meets the requirements.
If you think this is too cautious, I'm perfectly fine dropping it.
This protocol SHOULD NOT have automatic retransmission, ordering, congestion | ||
control, or other such mechanisms that would overlap with those provided by QUIC | ||
and therefore not actually enhance the overall quality of service. This | ||
protocol SHOULD be message-oriented. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This answers my earlier point (sorry for not reading in completeness). Are there many examples of IP-based, message-based, Internet transport protocols? My sense is that the scope of these changes are putting it in the "Yah Ain't Gonna Need It" bracket.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally, I'm reviewing this through the mental model of two additional transports:
- Message-based Websockets across an HTTP proxy
- Local datagram sockets for IPC
Websockets are clearly going to provide all those services which an underlying transport SHOULD NOT have, but that's just the suck you live with if that's your only way to speak QUIC to an endpoint. Local sockets, on the other hand, mean that a lot of the machinery within QUIC simply won't be needed -- but if you're porting over a protocol that's already built atop QUIC, that might be okay.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An interesting foray. I think this generalizes some pieces that really are UDP-specific, and would need to be redefined (or at least reconsidered) in other aspects.
datagram as necessary. (The payload is the assembled QUIC packets, and does not | ||
include any headers associated with the underlying protocol that are also part | ||
of the datagram.) A client that sends padded datagrams allows the server to send | ||
more data prior to completing address validation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like the anti-amplification features -- minimum initial size, the 3x limit, etc. -- really are UDP-focused because they mitigate attacks we know are common with UDP. A different transport might have such concerns, or might not. Perhaps, rather than generalizing these requirements, we should instead condition them on UDP.
draft-ietf-quic-transport.md
Outdated
conventional situations using UDP, the client cannot freely vary the IP address, | ||
but can much more readily change the UDP port. Since an address for QUIC when | ||
using UDP is the tuple of the IP address and UDP port, changing the source port | ||
along constitutes changing the QUIC address.) So changing the address from which | ||
it sends packets at the same time might cause the packet to appear as a | ||
connection migration. This ensures that the mechanisms that support migration |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems really wordy explaining why this is useful for UDP while still trying to generalize. You already changed the specific of UDP port to "source address"; probably all you need to add is that "When the underlying transport protocol is UDP, changing the source port is sufficient."
It might also be the case that changing the source address isn't possible with the alternate transport, so this is an "if supported by the underlying protocol" thing. (For that matter, the CID itself might be irrelevant on a transport where addresses can't change.)
This protocol SHOULD NOT have automatic retransmission, ordering, congestion | ||
control, or other such mechanisms that would overlap with those provided by QUIC | ||
and therefore not actually enhance the overall quality of service. This | ||
protocol SHOULD be message-oriented. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally, I'm reviewing this through the mental model of two additional transports:
- Message-based Websockets across an HTTP proxy
- Local datagram sockets for IPC
Websockets are clearly going to provide all those services which an underlying transport SHOULD NOT have, but that's just the suck you live with if that's your only way to speak QUIC to an endpoint. Local sockets, on the other hand, mean that a lot of the machinery within QUIC simply won't be needed -- but if you're porting over a protocol that's already built atop QUIC, that might be okay.
An underlying datagram MUST correspond to a single IP packet, if it is sent over | ||
IP. That means IP fragmentation MUST NOT be used. When using IPv4 | ||
({{!IPv4=RFC0791}}), the DF bit MUST be set to prevent fragmentation on the | ||
path. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not certain QUIC generically has this requirement across all underlying transports. The requirement is that datagrams be delivered whole to QUIC; if they were fragmented and reassembled along the way, that's irrelevant. For UDP, we don't fragment because we want to be able to assess the maximum packet size; for some other transport, we might be able to query the maximum size directly or have effectively-infinite maximum size.
In fact, given the way encryption overhead decreases with larger units of encryption, we might find that very large datagrams perform really well in certain environments with certain transports, even in the presence of fragmentation.
@@ -4030,12 +4086,16 @@ address of the client; see {{address-validation}}. | |||
|
|||
## Path Maximum Transmission Unit |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Much of the work referenced here is specific to UDP. I'd leave this as UDP-specific and merely note that a QUIC implementation on a different transport might need to use similar techniques to learn the properties of the path.
draft-ietf-quic-transport.md
Outdated
: The maximum UDP payload size parameter is an integer value that limits the | ||
size of UDP payloads that the endpoint is willing to receive. UDP packets | ||
with payloads larger than this limit are not likely to be processed by the | ||
receiver. | ||
size of underlying datagram payloads that the endpoint is willing to receive. | ||
Datagrams with payloads larger than this limit are not likely to be processed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A parameter that's specifically named UDP doesn't tell you anything about other underlying protocols. Either the parameter becomes generic (i.e. renamed, perhaps max_datagram_size
) or it remains specific to UDP and other parameters might be defined for other contexts.
@@ -6669,7 +6736,7 @@ attacker to establish connectivity on a given path. | |||
An on-path attacker can: | |||
|
|||
- Inspect packets | |||
- Modify IP and UDP packet headers | |||
- Modify underlying transport headers (e.g. UDP and IP headers) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here again, it's really going to depend on what that underlying transport is. This security analysis assumes UDP/IP; I think the safest statement is that QUIC over another transport needs its own security analysis to see what attackers might be able to do.
Co-authored-by: Mike Bishop <mbishop@evequefou.be>
Instead, just mention that it is one such example, since UDP is not the only option for the underlying transport.
As @MikeBishop points it the node may be assigned multiple IPv6 addresses.
Thanks for the feedback so far, just knocked off the easy stuff. I'll next switch to conditioning a lot of this stuff on UDP in particular as suggested. |
FYI, I converted this to a draft PR for now so we can track it better. |
I think that this PR makes the spec harder to read, with no obvious benefit. If someone wants to standardize QUIC over another medium, they'll have to write some sort of document for that, and simply saying "replace UDP with X" in that document should be good enough. I'd strongly prefer we didn't make the spec more generic at the cost of readability. |
@LPardue @MikeBishop So, going the basic thrust of both your comments so far, We'd end up with fewer constraints on the underlying protocol (e.g. need not be message-origin) and a good bit of information being conditioned on UDP only (ECN, MTU discovery and associated limits and restrictions, etc.). I see very different conclusions one might make based on that, such as:
I think before I put too much more work with it, would be good to confirm whether you agree with this analysis, and if so, which outlook you both take. Most of the broad feedback is still negative, so I don't want to just stir emotions while beating a dead horse. |
I'm seeing quite a bit of pushback on the issue and #4061. People who are in favor of making this change should please state their case soon. |
Personally, I come back to Christian's comment. I'm hesitant to publish a specification that hasn't been implemented and interoperated at all. If all we've got experience with is UDP, let's publish UDP. Nothing stops us from writing a subsequent spec about how to do QUIC over a different transport and making these changes in that doc. |
Since we closed the issue (#4061) as being out-of-charter, I"ll close this PR as well. |
Based on recent mailing list feedback that this might possibly be OK, I
decided to take a crack at reducing the "hard coding" of UDP in the
spirit of other RFCs which strive to be agnostic to the underlying
protocol.
Due to the controversy over this, I imposed these constraints on myself
to try to be as conservative as possible.
Absolutely no design changes on things which are already standardized,
just editorial changes, and very simple extrapolation of the existing
design. (I never ever considered the former at this time, just
documenting this for posterity.
Anything that is not UDP (over IP) is deemed experimental. The size
limitations I figure may not make sense for other transports / during
other experiments, so I call that out.
When UDP was mentioned in some interesting way that generalized (e.g.
something that separately mentions IP address and UDP port), I provide
the general language (plain "address", but also provide the UDP common
case as before so no specificity is lost.
The purpose of this exercise is not to get QUIC over UDP "more ready
for production", as that would slow down the WG for little gain, but
rather to call out the dependencies that currently do exist so as to be
sure there is no unintentional coupling. I fully leave to others to
decide what coupling is intenional or unintentional, and whether
anything at all is cause for concern.
In this first commit, I just audited all the occurrence of "UDP". If
this looks good, I would then go back and likewise scan for "port"
"IPv4", and "IPv6".
My one regret is that in keeping the line length the same, I made the
diff more complicated than it would otherwise be. Do you all have a
process for that?
Progress towards issue #4061.