Skip to main content

Minutes IETF110: webtrans
minutes-110-webtrans-00

Meeting Minutes WebTransport (webtrans) WG
Date and time 2021-03-08 16:00
Title Minutes IETF110: webtrans
State Active
Other versions plain text
Last updated 2021-03-09

minutes-110-webtrans-00
IETF 110 WEBTRANS WG Minutes
Monday, March 8, 2021
08:00 - 10:00 Pacific Time
Session III, Room 3
Chairs: Bernard Aboba and David Schinazi

IETF 110 Info: https://www.ietf.org/how/meetings/110/
Meeting URL: https://gce.conf.meetecho.com/conference/?group=webtrans
Etherpad: https://codimd.ietf.org/notes-ietf-110-webtrans
Slides:
https://docs.google.com/presentation/d/15u9F-YgP8mpE7gUYhfM5Bn7ZGa3AiG6GQIo2wFZgC_Y/

## Preliminaries, Chairs (10 minutes)
Note WellJabber Scribe, Etherpad Note Takers
Speaking Queue Manager (David Schinazi)
Agenda Bash

## W3C WebTransport Update, Will Law (10 minutes)
[Slide 7 onwards]
(https://datatracker.ietf.org/meeting/110/materials/slides-110-webtrans-ietf-110-webtrans-wg-01)
Summary of changes from W3C since November 16
Issues currently under debate
Request for the IETF: please finalize a scheme to be used, some preference was
expressed for "https"

## WebTransport over HTTP/3, Victor Vasiliev (40 minutes)
https://tools.ietf.org/html/draft-ietf-webtrans-http3
Goal: Resolve issues blocking shipping interoperable version of WebTransport

### [Issue
23](https://github.com/ietf-wg-webtrans/draft-ietf-webtrans-http3/issues/23)
Proposal: use the same syntax as client-initiated bidirectional streams Alan
Frindell: Aren't client-initiated bidirectional streams identified by being a
CONNECT request? Ah, they have a frame type. Martin Thomson: Client ones look
like they have a frame type, but don't. They have a frame "type", would this be
the same? Victor Vasiliev: The proposal here is that they should behave the
same, will be modifying how they work in the next slides Martin Thomson: Sounds
reasonable Alan: Do we want/need a way for everyone who wants to extend
server-initiated bidirectional streams to solve this? Do we want all extensions
to follow the same thing so that different extensions can be demultiplexed in
the same way? Should there be guidance for extension writers so that we don't
need to do this over and over for each HTTP extension. David Schinazi: (as
individual) Similar to how we have a document for how to use datagrams in
HTTP/3, maybe what we need here is an incredibly short document that describes
how you use server-initiated bidirectional streams in HTTP/3. Victor: Not
entirely sure a separate draft is required as long as we pick an approach that
is compatible with further extensibility. David: Makes sense, works if we tie
it to a different setting from the WebTransport setting. Don't want others to
need WebTransport to use their own extensions. Ian Swett: I'm not completely
sure you need to talk about Settings in all circumstances, this is more about
how does one extend HTTP/3. If we do this, other folks will want to make a
similar decision both because it's extensible and to be consistent with this.
This is more about "it's best practice not to hog all the server-initiated
bidirectional streams" and this is the obvious way to do so. If HTTP/3 wasn't
already so far along, I'd suggest we shove it in right there. I don't think it
really matters though, I think we can just move forward with a consistent
design. Martin: We don't really own HTTP/3 and we'd have to talk to the people
who do, probably best for httpbis to define a generic document that says this.
Would also describe what it means to use a client initiated bidirectional
stream. David: Doesn't the core HTTP/3 document describe how client-initiated
bidirectional streams work? They carry frames and others can extend frames.
Martin: I think it currently says "carries requests" which are made of frames,
so we'd want something to make it clear how general usage should work. David:
(as chair) I can take an action item to reach out to httpbis chairs to
understand where this should live. Alan: One more point that I raised on issue
23, has to do with the fact that unidirectional streams are identified by
stream type and bidirectional streams are identified by a frame time. If you
ignore that difference, they look the same at the beginning of the stream, and
I take advantage of that. If anyone ever added a new frame type (?), that would
break a nice symmetric implementation. It might be nice to reserve the
unidirectional stream type number in the frame type space to allow for that
sort of implementation. That could also be done in a separate issue. David:
Thanks, Alan. Let's have Bernard and myself circle back after talking with
other chairs and that will be a great issue for that document wherever it lands.

### [Issue
26](https://github.com/ietf-wg-webtrans/draft-ietf-webtrans-http3/issues/26)
Victor: Previously said that you could have a datagram frame that went to the
end of the stream (i.e. use Type-Value without Length) and avoid additional
framing. Issue discussion highlighted that people don't agree that it can be
omitted. Question here, if we don't have length, should we add it? David: (as
individual) Personally, I think this would be a useful HTTP/3 feature to have a
frame length of zero mean that it goes to the end of the stream. Got turned
down when adding it to HTTP/3 at some point, but we'd need to see if people
were okay with doing that in HTTP/3 or if that's specific to WebTransport. Ian:
Not that strong of an opinion, although I thought we were going to use the Type
Value form for this. Would be nice to put best practices in an httpbis document
if we were doing it. This is a special case because if you don't understand
what the type is your parser will immediately fail, so these are already
special frames that are non-standard HTTP/3 frames. Alan: Recognizing that
either is possible, I do have an implementation where I had to go write code
that handled frames without length. Was about 3 lines, not ridiculous. Might be
a reason why you could start it with length zero. Pick one or decide on best
practice. Lucas Pardue: I'm kind of confused by this because if my
implementation saw an extension frame that it doesn't recognize, it will try to
skip that frame, but I'm not sure how I can ignore a frame where I don't know
what it is if it doesn't have a length. Victor: That's why we'd define a
setting, you can't send the frame without the setting. Lucas: If I don't set
the setting and you send me one, then my connection is dead? The current HTTP/3
extension story is that we just ignore extension frames. Victor: Fatal error to
send the frame when both parties aren't sure that it's webtransport Martin: To
answer Lucas, there's provision for settings that change the way the protocol
behaves. Here, you'd be saying that everything after that frame is something
other than frames, etc. can bake that meaning into the setting. Seems
workable.Alan's point about stream types and frame types is relevant here, as
the bidirectional streams will be just stream types and not frame types.
Victor: I assume that speaks in favor of not using length here. Martin: I don't
think length gives you anything at this point. A length of zero doesn't help,
since your parser is going to choke there anyways. Result is undefined either
way, so you have to rely on the setting here. Eric Kinnear: Having something
that extends-until-it-doesn't is annoying when trying to implement some of
these things, probably fine here, but wouldn't want to do this generically in
all cases. Alan: I like the idea that this is a different thing and that we
don't overload having zero length since that can have other meaning for other
frames. David: My earlier comment about trying to do something generic doesn't
work based on this conversation, so I'd support doing something WebTransport
specific that works via the setting. Martin: I don't think it's something we
can avoid generically for bidirectional streams, but aside from that the frame
stuff I think that's going to be on a per-frame type basis.

### [Issue
38](https://github.com/ietf-wg-webtrans/draft-ietf-webtrans-http3/issues/38)
Victor: Pick a URI scheme, please. Proposal: Use "https"No real reason to make
a new one, as far as we can tell they're just HTTP resources, they do require a
specific HTTP method but that's not new to some HTTP resources. The main
objection was that there were subtle differences in how it behaves around
things like cookies and HTTP auth, specifically that it does not, but that's
different from the concern around how these resources are identified. Martin:
I'd support "https", this seems pretty reasonable. Jonathan Lennox asked in
Jabber why "ws" was a separate stream. "ws" and "wss" are examples of what not
to do in this case. We should probably just treat it as a different method on
the same HTTPS resource. That would be different if it were QuicTransport, but
now that we've taken this path that's a much easier decision. David: (as chair)
Not seeing any opposition to going with "https" here, so unless someone wants
to speak up now or on the list, I think we can assume consensus on this one and
move forward.

### [Issue
10](https://github.com/ietf-wg-webtrans/draft-ietf-webtrans-http3/issues/10)
Victor: These are less critical for interop, but still important. Stream IDs --
reconfirming what we already have. We made a decision that WebTransport would
not expose the stream IDs from QUIC. In QuicTransport it might have been okay,
but for HTTP and especially if there are proxies in the middle, that makes no
sense whatsoever. Wanted to reconfirm that we're not going to expose QUIC
stream IDs as part of the protocol. Luke Curley: We made the original ticket,
for context we wanted to know the ordering/creation date. That's not
necessarily possible with HTTP/3 transport or pooling. We might need a custom
way of doing that within WebTransport. Victor: I was thinking if it was
possible to preserve ordering without preserving the idea of the exact stream
IDs, one question I have: when you're interested in ordering do you care about
relative ordering or does this ordering need to have no gaps. Luke: Initially
we did odd/even ones for different types of streams, and we used the fact that
QUIC streams are increasing. Again, that's not possible because if there's a
gap we won't know if it's an HTTP request. There's no way of knowing how many
streams may have been created. We can just add a header on top of the request,
and that may be acceptable, tell applications to assign their own stream IDs.
Jan-Ivar Bruaroey: I just wanted to make sure I understood that, I think
ordering is going to be important in the API since I think framing is going to
be hard for javascript developers to get right. One thing we get asked a lot is
how to wrap websocket-like API onto WebTransport. Two ways: either wrap on
transport itself or introduce head of line blocking on a request stream. It
seems that preserving the ordering of what was sent is critical. I wanted to
clarify if we were able to guarantee that order. Victor: If you send on
explicit streams, you're guaranteed that order will not be preserved,
preserving ordering introduces head of line blocking. Jan-Ivar: I was happy to
find in the QUIC spec that stream IDs are always increasing. If we can carry
that forward to the API, if you await a stream then the appearance is going to
be in the order that they were sent. Victor: I don't think this is true, you
don't know if the ones in the middle are even related to you. Doesn't really
make sense to assume that they're going to show up in the same order. Jan-Ivar:
It won't be blocking, if you get one that's newer than expected, then the
receiver can create the underlying streams for the missing numbers and then
populate them later. David: If packets get lost, you can't assume that the
ordering is enforced. I think you'd really diminish the benefits from QUIC if
you had the API enforce the order, as that introduces head of line blocking,
I'm sure there are applications that don't want that. Jan-Ivar: We're talking
about API now, I think the API doesn't force the application to choose, you can
choose what you want to do here. You can create dummy streams for any gaps that
you see. David: Given that we're not over HTTP/3 which is a multiplexed
protocol, we're going to need a new namespace, as we're not going to expose
that raw stream ID from QUIC to the application as that leaks information. So
the question becomes, do we introduce a new thing into WebTransport and make a
new namespace, or do we ask applications to make their own header and number
them according to their requirements. Martin: I think David covered most of it,
unless you want to make the application aware of things that are not for it.
You can't use the presence of stream 16 to assume that 12 exists and is for
you. The other way around it is a notion of dedicated connection for the
purposes of that application, then you can expose it because it knows that it's
going to be a WebTransport stream for it. Let's push this onto the application
for the header. Bernard Aboba: I think it's worth having an issue, there's a
number of cases where it's the application's responsibility. Another example,
we decided to not make ACKs visible in the application, since people were
unclear about whether or not they need to handle their own reliability (note:
if you asked for unreliable, then yes you need to handle it yourself) David:
Who is going to document this? Bernard: Victor willVictor: Sure, I've got the
action item Jan-Ivar: The language that I found in the QUIC spec about streams
of lower numbers meaning they're opened, is that not true? Victor: They're
opened but we don't know which WebTransport stream they'll be, or even if
they're a WebTransport stream at all. Jan-Ivar: Once you've received data and
know what it is, an application could decide to open lower numbered streams.
Victor: If you do this, then you've introduced head of line blocking.If we
require streams to go in order, then all future streams would be blocked.
David: It sounds like the feature you're asking for is "hey I received the
client initiated stream and that stream told me that there's some other stream
that I want to send on". If you want to send something without the client
having spoken first, why not use a server-initiated stream? Jan-Ivar: The model
here is that when you create a stream, all the data inside it, then that data 
has guaranteed ordering. If I split it across two streams, then I'm not
guaranteed the ordered delivery of those streams. But it would be beneficial if
we could surface them in creation order and I don't see how that would block
anything. Framing is hard in javascript and stream IDs is an implementation of
framing that we could benefit from. I'll work on clarifying how I don't
consider that head of line blocking, but it would be nice to look at that in
WebTransport. David: This sounds interesting, can you write something up that
we can discuss offline. Luke: I think at a higher level this also applies to
the next issue. In my use case, we're using QUIC for mobile platforms and then
for Web support we're going to use WebTransport. There are a few QUIC features
that we've been using which don't map well into WebTransport. Stream IDs and
Reset are two of those things that don't map particularly well. Are we looking
for QUIC or a subset of QUIC API-wise? Victor: My intuition is that it has to
be a subset, I don't think we can do a 1:1 perfect mapping. Or if we could, I'm
not sure it's worth it. QUIC has a lot of semantics and some of those semantics
are dictated by the fact that QUIC is a transport protocol that has to handle
transport issues. Our goal is to implement as much of QUIC as possible and
expose as many of the semantics of QUIC, especially those that relate to
unreliability and avoidance of head of line blocking. Alan: Folks are telling
us what they want from the transport, we are ignoring them and trying to build
a batteries-not-included simplest version that's possible. If applications are
saying that more things are possible if we tell them about the ordering that
things were created, then I would be in support of building that into the
protocol. Timothy Panton: I just wanted to say in the WebRTC world we came
across the same problem and we solved it by introducing a lightweight protocol
that slots in a header and allows the API to label a stream. That's turned out
to be super useful, if something like that is possible without having too big
an overhead, then I'd be in support of that. Victor: It sounds like it's worth
discussing this one more, not for the most immediate interop draft.

### [Issue
31](https://github.com/ietf-wg-webtrans/draft-ietf-webtrans-http3/issues/31)
Victor: Issue 31 is very similar. Do we want to expose RESET_STREAM? Martin:
I'd argue for the first option, declare that RESET_STREAM is not reliable. The
only issue is that if someone is mixing WebTransport streams and request
streams and one of them gets reset and the other one doesn't get through, then
you have a weird stream that appeared and it can't tell what to do with it, but
that's fine. In those cases, the endpoint that created the stream and reset it
too quickly would have meant that the other side never heard about it. Luke:
From an application level, if I'm using WebTransport and I create a stream to
write a bunch of data and then close it with an error code. It's a reasonable
expectation that the error code will make it to the other side, especially if
data was sent. It seems like an invitation to future problems if people expect
those codes to be reliable but they aren't due to packet loss. Victor: Is this
specifically about the error code being reliable? Luke: I think so, the fact
that a stream existed and the error code both would want to be reliable. Do we
need the receiver to know that the stream ever existed if it never got data? If
it didn't know what protocol it was for? Martin: This is physics, if you use
RESET_STREAM for this purpose, you don't get to learn about the code sometimes.
The question is whether we build an additional facility into the protocol to
support it, or the only way I can see of getting these through reliably is
having a dedicated connection. Victor: I would say that it is possible to just
make it so that reset stream error codes always arrive, and that to some extent
is a solution. Martin: There is an option here that does work, that is to
reserve RESET_STREAM error codes for WebTransport. There is some ambiguity if
you have two tabs sharing a transport, and then each has its own WebTransport
you still can't tell what's going on, but otherwise you'd be able to tell that
it was for the WebTransport in question. Victor: I feel like we should reserve
some space for error codes just so we can distinguish from HTTP error codes
regardless. Jan-Ivar: Yeah I just wanted to echo that I think we're going to
have to find some way to make these APIs a little bit more predictable. I'm
hopeful that we might be able to do so at the API leve, but it seems like this
particular one, once you get a newer stream you might know that there was an
earlier one that could have been reset that never existed. It sounds like the
semantics are embedded in the protocol. David: I think just conceptually and
fundamentally, QUIC streams are not ordered. The fact that they have IDs that
are sequential is an implementation detail. Neither QUIC nor WebTransport
provide this capability to upper layers. If there's a need, it would be nice to
have the use cases identified.

### [Issue
28](https://github.com/ietf-wg-webtrans/draft-ietf-webtrans-http3/issues/28),
[29](https://github.com/ietf-wg-webtrans/draft-ietf-webtrans-http3/issues/29)
Bernard: I agree, we've encountered this in other things such as WebRTC, but
you might want to have limits on the buffer. Victor: Agreed. Need to limit the
state required.

### [Issue
27](https://github.com/ietf-wg-webtrans/draft-ietf-webtrans-http3/issues/27)
Victor: Assume reverse proxy with backend that sends GOAWAY, how should this be
indicated to the application/client that the session is being drained and will
go away soon. Do we want to support this in WebTransport? Alan: I just want to
say that it's very important that we find a solution to this problem, we have
something very similar to WebTransport today and the application that uses it
has a sequence of streams and we need a way to signal "please don't start any
new work, but don't prevent the creation of new streams that are required to
complete the transaction associated with that session". I could see using the
CONNECT stream associated with that session to signal that. Martin: I agree
with Alan. The way that we've been conceptualizing GOAWAY is about requests,
this is the next level down. I would imagine it would work such that GOAWAY at
H3 layer says "no more requests, please", but within a WebTransport session you
can still make new streams (not new sessions). Within a session you'd need a
similar way to say "stop making new streams" and that could be on CONNECT. Not
sure if that's needed or application can do it without additional support.

### [Issue
33](https://github.com/ietf-wg-webtrans/draft-ietf-webtrans-http3/issues/33)
Alan: I raised this issue after I implemented a lot of this last week, I found
that in my implementation this was the only reason I had to track which streams
belonged to which session within the transport stack. This meant that I had to
keep an extra list of things, if the higher level already has that then it can
handle it. Victor: I can kind of see that argument. I definitely agree that the
browser should reset the connect stream if the tab goes away. It's unclear if
we should relax the requirement for non-browser implementations. Luke: Only the
creator of the stream knows that it's associated to the connection, it seems
like however created it should close it when the connect stream is closed.
Victor: Lucas makes a good observation that if you allow them to continue, it
makes us less able to rely on CONNECT for control-stream semantics like GOAWAY,
etc.

### [Issue
34](https://github.com/ietf-wg-webtrans/draft-ietf-webtrans-http3/issues/34)
Victor: How does the server let the client know that pooling WebTransports is
not supported? Alan: (missed this) Bernard: I'd like to speak to option 2.
Option 1 would be awkward especially if linked to other things like what stats
you get. Yutaka Hirano: I don't understand why the client needs to send the
indiciation to the server, the client needs to wait for the first settings
frame just to find out that the server supports WebTransport. I don't know that
we'd need to have settings from the client to the server. Victor: I think I
agree with you, but this is something we need to think about more. We might be
able to get rid of the client signal. Dragana Damjanovic: You will need a
client indication if it wants to use that transport or separate HTTP/3
connections and WebTransport connections to the same origin. If you don't
indicate from the application that you want a separate connection, then you can
pool them. If the server only wants to support one, it seems complicated to
have a server that listens on the same port on the same origin but requires
separate connections. Victor: The reason I want to add a dedicated from the
signal is that there are developers who want to allow that sort of thing.
Dragana: Then you'd need to indicate that you want to open that connection for
HTTP/3 or WebTransport so the browser knows what to do. I can try to explain
further on the issue. Martin: Firmly against having a dedicated flag. The
decision to use HTTP/3 means you're making an HTTP connection and there are a
number of other ways for a server to say that it doesn't want other requests to
happen. For example, we've got 421 to say "I've got a certificate but I'm not
willing to answer requests for this origin", you could also put them on their
own origin. I'd also second Yutaka's point about not needing this on the client
side. Victor: Sure, if you're sending HTTP requests you already know where
you're sending them. But what about having two WebTransport sessions for the
same client. Martin: Key point here is resource management from a server
perspective, having max sessions and maybe max streams per session would be a
useful control here. Eric: So this isn't even really QUIC vs. HTTP isn't more
about controlling that endpoint and being able to choose what requests you
respond to. Martin: Can use 406 (405?) to say "method not supported", respond
to what you want to handle.

### Datagram Flows
How to encode them? Come to MASQUE tomorrow.

## WebTransport using HTTP/2, Eric Kinnear (30 minutes)
https://tools.ietf.org/html/draft-kinnear-webtransport-http2

Some networks don't support QUIC (nee UDP) - what is a fallback? Web traffic
can go back to TCP, what does WebTransport do? Choices: fail, build your own
fallback (on top of WebSockets?), or WebTransport over HTTP/2. So lets think
about what WebTransport over HTTP/2 looks like. It looks similar but TCP/TLS
means we lose some features or capabilities. Is this worth pursuing even if
there is not feature parity? Principle 1: it's okay to require an optional
feature, make it clear when creating a session via the API. It might fail and
you might need to provide your own alternative. Principle 2: application needs
to know what features are available in a given session. Adjust what you do
based on features Principle 3: Wherever possible WebTransport over H2, should
be equivalent to WebTransport over H3. Draft has been updated now that we've
adopted the single draft. So is this something worth doing, are the principles
sound, is modelling it after HTTP/3 transport reasonable. Bernard: WebTransport
over H2 is the best solution for developers. TCP fallback is important because
UDP blocking is particularly prevalent in Enterprise Networks (affecting as
much as 15 percent of enterprise usage). The question is how to support
fallback. Without WebTransport over H2, WebSocketStreams API (which provides a
WHATWG Streams-based interface to WebSockets) could be the fallback. Unlike
WebTransport over H2, which would allow an application to support fallback with
a single API (WebTransport), two APIs would be needed. There are differences
between WebTransport API and WebSocketStream API, so developers would need to
create their own wrappers to support both APIs. So this is not as clean as
WebTransport over H2, but it can work whenever WebSockets is supported, and at
least both APIs are based on Streams. However, my understanding that
WebSocketStream API, which was in Origin Trial, is not moving forward. If the
only alternative to WebTransport over H2 is to require developers to write to
two very different APIs (WebTransport and WebSockets API) that is difficult and
will present challenges. For example, WebSockets API has known issues with
backpressure. MT: Requirements are spot on. Bernard's point is similar to
points that myself and colleagues have made. Have reservations about technical
aspects of approach; can probably simplify things. Maybe pack all of it in one
H2 stream, rather than intermixing with HTTP request streams. This is the right
work to be doing but I'd like to see more discussion on the technical side of
things. David: From comments here and W3C there seems to be interest in this
work. We want to reserve some time each session to discuss WebTransport over H2
(or TCP) at the end of each session, with a view to some future adoption. We
want people to respond to gauge interest in this approach. Yutaka: We're still
working on WebSocketStream. Jonathan: a little concerned that the failure rate
of QUIC is low and that this code might not get well exercised. W3C probably
need to help keep an eye on things. David: my understanding that this is
oriented more towards networks that don't support UDP rather than servers that
don't want to support a UDP-baed WebTransport Jonathan: web developers using
their dev environment might not have traffic that is reflective of the
Internet, there may be unanticipated surprising behavior David: interest and no
opposition to discussing this. Too early to judge whether to adopt. Please
continue discusion on
[GitHub](https://github.com/ekinnear/draft-webtransport-http2/) and future
session. We'll probably have an interim session before the net IETF meeting,
please look out for information on the list.

## Hums, Wrap up and Summary, Chairs & ADs (30 minutes)