netconf-wg / netconf-over-quic

0 stars 1 forks source link

Clarify ambiguous QUIC stream mapping #18

Open aochagavia opened 4 weeks ago

aochagavia commented 4 weeks ago

The current specification of the QUIC stream mapping is ambiguous. Below are a few ideas to improve it.

4.1. Bidirectional Stream Between client and server

Current text:

NETCONF protocol uses an RPC-based communication model. So, the configuration data from client to server is exchanged based on <rpc> (the server initiating) and <rpc-reply> (sent by the server) and so on. So the messages used to exchange configuration data MUST be mapped into one or more bidirectional stream whose stream type is 0x0 according to the above table.

Suggestions:

  1. The paragraph mentions that <rpc> is initiated by the server, but also that <rpc-reply> is sent by the server. That sounds contradictory. From the perspective of QUIC, <rpc> is sent by the client, so I'd suggest we change the wording to reflect that.
  2. The paragraph allows an implementor to use "one or more bidirectional streams", which is overly broad. My suggestion would be to mandate one bidirectional stream for each request. That way QUIC handles the framing for us, and we only need to send the actual NETCONF payload through the stream.

4.2. Unidirectional Stream from server to client

There are some notification data exchanged between the client and the server. Notification is an server initiated message indicating that a certain event has been recognized by the server.

Notification messages are initiated by the server and no reply is needed from the client. So the messages used to exchange configuration data SHOULD be mapped into one unidirectional stream whose stream type is 0x3 according to the above table.

Same as for 4.1, my suggestion would be to explicitly mandate one unidirectional stream for each message, if the possibility of having notifications arrive out-of-order is acceptable. Otherwise, we should probably mandate one unidirectional stream for the whole session (messages would be then framed outside of QUIC, e.g. prepending a length to each notification).

Handling of capabilities exchange (aka <hello>)

There's currently no mapping for the <hello> message, sent on startup by the server and the client. IMO, the logical QUIC mapping for this would be to require the following:

  1. At the beginning of the connection, the client opens a bidirectional stream (stream type is 0x0) and sends the <hello> message right away
  2. At the beginning of the connection, the server accepts the incoming bidirectional stream and sends the <hello> message right away
  3. Only after receiving the <hello> message from the peer you may start handling other kinds of messages
  4. Finally, I think it makes sense to structure the mapping subsections as follows: 4.1 Capabilities exchange; 4.2 RPC calls; 4.3 Notifications.
aochagavia commented 3 weeks ago

On a second thought, I also feel the attractive of keeping things as simple as possible. Instead of coming up with a mapping to multiple QUIC streams (and validating that we have everything covered), we could use a single bidirectional stream instead and let all traffic go through it. This is analogous to what happens in NETCONF over TLS, so we could even base our specification on RFC 7589. We won't be using any fancy QUIC features, but since we probably don't need them anyway, this might be the best way forward after all.

marcblanchet commented 1 week ago

From Andy Bierman, andy@yumaworks.com on mailing list (https://mailarchive.ietf.org/arch/msg/netconf/eRWTJVsikihEt-UdaRYqTrXA-Ko/)

NETCONF uses sessions. RESTCONF does not.

https://datatracker.ietf.org/doc/html/rfc6241#section-4.5

Within a single session the RPC processing is serialized.

There is a bi-directional stream per NETCONF session, not per request.

aochagavia commented 1 week ago

Good to hear! That will probably let us reuse most of RFC 7589.