Change:
.. that gets in the way of using streams when cloning.
How does this interact with ?
NAME - this now states that it is irrelevant for Rendezvous(), and explicitly mentions the Initiate() and Listen() calls when talking about actively and passively opening a Connection. Why is it irrelevant? Remember, the problem is that you actively open a Connection that could be mapped to a stream, in which case an active Open doesn't do anything on the wire - and then, right away, you want to read. Then the peer never heard from you, you haven't even tried sending anything to it. Enabling this property will allow the TAPS system to carry out such a Connection = stream mapping. When calling rendezvous(), however, just using a stream is out of the question - you need signaling, and chances are that you're going to actively send stuff in any case. In other words, I don't think there's a mapping that would work with rendezvous() that enabling this property would allow, and hence the property is irrelevant for rendezvous().
Merging this now: I think I have addressed the comment by NAME We can always fix things later again if we must - but for now, this and it also relates to , which gates .... so it's probably better to move forward at this point.
Should ListenClone() fail for non-multiplexed transports How to specify if a top-level listener can accept cloned (multiplexed) streams Should ListenClone() be called ListenForClone()...?
Just a note to say that issue waits for this issue to be addressed.
Rename function Trying to do this without a multiplexing transport should fail
ping: issue is waiting for this...
Currently the "Clone" part of, e.g., TCP (section 10.1) only says: "Calling Clone on a TCP Connection creates a new Connection with equivalent parameters. The two Connections are otherwise independent." This text should reflect that equivalent behavior must be maintained upon later Connection configuration calls. And, there should be more text in general on cloning (see issue ).
This text must refer to a new "do I want a Connection that supports initiate followed by listen?" property. This property will be added to address - so I'll address this issue when the PR addressing has landed.
A couple of questions we might want to address regarding Connection Groups. 1) Can the application query the interface to figure if two connection in a group share the same transport connection but on different streams or not. Is that useful? I thinks we should explicitly say that if a multiplex protocol is used, calling Clone() MUST create a new stream (and not a new connection). 2) If a new connection is created by a Listener it is automatically part of a group, right? Can I detach that connection from the group? Otherwise how can I change a property only for that connection? Isn't is actually confusing that these connection are grouped? 2) Should we add a pointer to coupled congestion control (rmcat) in that section?
"Can the application query the interface to figure if two connection in a group share the same transport connection but on different streams or not." - no. "Is that useful?" - Good question. The behavior attained with coupled cc. for ongoing connections can be VERY similar to the behavior of multi-streaming - exposing such a detail to an application can then lead to unnecessarily protocol-specific code. Then again, it may be useful for an application to know if issuing Clone() comes with almost zero overhead, or if it produces a connection setup on the wire... so I lean towards "yes, it's useful". "I thinks we should explicitly say that if a multiplex protocol is used, calling Clone() MUST create a new stream (and not a new connection)." Fine by me. I think the query that you mention above, then, should be: "is a Connection multiplexing-capable?" (which will, due to your MUST, translate into "Clone() just means using a new stream"). The difference between Listening with and without cloning is explicit - normally, Listen does not produce a Connection that's grouped with some ongoing Connections. Rather, if you WANT to do a "listening clone", you need to issue "Listen" on an ongoing Connection, as described in Section 6.4. So it's a different "Listen" call. You can't detach Connections from groups. Yes! We've also done work on doing this with TCP connections, which works like a charm - I'll insert the coupled cc reference and cite the TCP coupling work too.
I agree with 1): having a query that indicates if a protocol provides multiplexing is probably sufficient (+ the MUST requirement) On 2) from how I read the document I understood that Connections that are derived from the same Preconnection are clones. If that is not the case of Listeners we need to clarify that and double-check the existing text.
On 2): that's what I meant in my answer, sorry if it wasn't clear. So what's the problem?
So are you saying Connection from the same Listeners are clones or not? And in each case shouldn't there be a way to also get the other?
Ahh, sorry, I misread, you talked about "the same Preconnection". No, that's not it. If you call Listen on a Preconnection, you get a new Connection that is not cloned. That's in: https://ietf-URL If, however, you call Listen on an existing Connection, you get a clone. That's in: https://ietf-URL
Just to add, I think its inconsistent that you would call listen() on an connection object. In all other parts of the draft it is only ever used on preconnections.
No that's also not what I was talking about. You call listen on a preconnnection. At some point someone connects and the listener creates a connection (A). Then another (or the same actually) peer connect to your server (again) and the same listener creates another connection (B). Are those connections(A and B) grouped or not?
The same listener = a listener that was called on a preconnection. So, in your example, you never called Listen on a Connection, which is semantically different. So, no, A and B would not be grouped - what makes you think they could be? Noone ever made the Listen call that would do that. What am I missing?
NAME that's just a naming thing. Using it on a connection is consistent with Clone() - it's just a different way of Cloning, as a passive instead of active open. We could call it something else - ListeningClone or something. Me, I like it as it stands because, to me, the semantics of "this is spawned off an existing connection" are nicely conveyed by the call being applied to a Connection instead of a Preconnection. But I wouldn't fight about the name if you think "ListeningClone" or something like that is better.
I agree, its mostly a naming thing but I think there are a few things here that need to be specified which aren't obvious. For example, what happens if you call listen on two connections that belong to the same group? Personally, I would assume that you can't and would get an error if you tried. I also agree with NAME that it is a bit confusing that listener objects, depending on how they have been created, sometimes group connections and sometimes they don't.
Why? The two connections are already both part of the same group, so any of these Listen calls should give you yet another connection that is in the same group. I don't think there's anything indicating any other semantics - such as the error you're describing. About this being confusing: this is just a matter of having a passive clone. How else would you do it?
But the listen wouldn't give you a new connection, it would give you a Listener object which in turn would give you new connection(s). Having multiple Listener objects for the same group seems wrong to me.
I think this whole discussion suggests that we should indeed use a different name, ListenClone or CloneListen seems the most natural choices to me. Perhaps update the name (and the text accordingly) and see if there is still any points for confusion left. While calling listen on a Preconnection and a Connection are semantically different, I can see that it is easy to get lost as to what Listen we are talking about in different parts of the text.
Yes!
I'm currently reading the Implementation draft again, where Section 4.8.3 talks about listening for multiplexed protocols. Interestingly, the implementation draft gives different answers to the questions here: The Implementation draft says that "The implementation should allow the application to introspect the Connection Group marked on the Connections to determine the grouping of the multiplexing." So I guess this would change the answer to question 1 here to "Yes", but the interface draft doesn't say how. "Protocols that provide multiplexing of streams into a single five-tuple can listen both for entirely new connections (a new HTTP/2 stream on a new TCP connection, for example) and for new sub-connections (a new HTTP/2 stream on an existing connection). If the abstraction of Connection presented to the application is mapped to the multiplexed stream, then the Listener should deliver new Connection objects in the same way for either case." - It doesn't say what "in the same way" means, but I guess it means "deliver a ConnectionReceived event". The sentence after that talks about querying Connection groups, cited above. So this sounds to me like this text presumes that Connections from new streams on existing connections are grouped, while Connections on entirely new connections are not. But I might be misreading this. In any case, it's not clear. This thread sounds to me like incoming Connections from a Listener created by Preconnection.Listen() are never grouped. So, I think either we should say explicitly that incoming Connections from that Listener may or may not be grouped (depending on whether there's an "entirely new connection" underlying or whether they're just a new stream), or we say they're never grouped and change the implementation draft later. However, in that latter case, we'd have outgoing multiplexed connections which are always Connection Groups, and we have incoming multiplexed connections which are never Connection Groups. That doesn't sound right.
Folks, this discussion and NAME last comment just made me remember something: I'm afraid we have designed something that just cannot work! I don't know about QUIC, but I assume it's the same: in SCTP, passively creating a new stream just doesn't exist - a stream comes into being as soon as a new message is sent on it. So, technically, the only thing that really works would be something much more restrictive, as for example: having a form of InitiateWithSend as an active clone, then, on the passive side, upon InitiateWithSend-cloning, Listener -> ConnectionReceived might just fire out of the blue, and only when that happens, Connections are cloned.
If initiate() is supposed to "open" new stream, calling initiate() will not lead to any action on the wire but also create some internal state that the next send of that connection will need a new stream (id). That's fine.
But is that a clean model? You call initiate, and because it's just like any other Connection, maybe you expect to possible be able to read something afterwards... but that will never be the case.
I agree that things get somewhat inconsistent here. When would a Connection created like this fire its ready event? Just immediately?
Felix Weinrank and Michael Tüxen described in detail how this works in case of NEAT in this paper: F. Weinrank and M. Tüxen. “Transparent Flow Mapping for NEAT“. In Workshop on Future of Internet Transport (FIT 2017), Stockholm, June 2017. URL For their implementation, the answer to your question is "yes". But that's just because we wanted to map Connections at any cost - it comes with the limitation of only being to send (not receive) later, so I'd say this is not fantastic API design. Being able to receive immediately after clone() + ready would require using a signal in the underlying protocol itself - the paper discusses that this could be done with the otherwise unused "Payload Protocol Identifier (PPID)", but the meaning of this signal (as: "I created a stream but I'm not sending anything") would of course have to be known to both sides too, requiring a new standard.
Opening a connection that just allocates stream ID state should be fine, no? I don't think it's necessarily a problem. As far as being able to read without sending, that's up to the protocol. No reason some future version of QUIC or similar couldn't support that.
Well that's true - although, why would future-QUIC do that? Just to support TAPS's communication model? It seems efficient to just implicitly create a new stream by transmitting data on it. Anyway, at the very least, we should warn the programmer that it may not be possible to initially read on a newly cloned connection, and provide this information as a readable connection property. Also note that we're now only discussing one aspect of the problem: is it ok to just have an "Initiate". The other aspect is listening: sure, we could make a general Listen map to things and have warnings and such, but what both QUIC and SCTP would currently be doing is completely different from that. I think it would be better to specify that Listener -> ConnectionReceived might just fire out of the blue, which would also indicate that the first data has probably (with current protocols: surely) already arrived at the stack.
No, not just to support TAPS! If there was some value in having a stream that a client can open, but not write, and have the server write, which presumably is the case you're concerned about here, and someone has a use case, they can use that. Even today, you can have a server for TCP that won't do anything until the client writes. I don't see any reason to have the API be restrictive based on particular protocol behavior, when there are cases that do allow that behavior.
Yes, that's the communication pattern I'm concerned about. It is rare - e.g. pub-sub systems, which in principle follow that pattern, will usually implement an application-level signal from the client to the server that at least says "I'm here". Because this pattern is rare, I doubt that it will be supported in future-QUIC-or-whatever. And that's fine! The problem is: if I write an application over TAPS and I decide to implement this "I listen, and then I'm the first to send" pattern, then: if the underlying protocol is TCP, this will work fine if the underlying protocol is a stream of QUIC or SCTP, my application simply gets stuck. So we should at least put a warning about this case in there, and let an application query if, after Listen, send-before-receive is possible.
Discussed in interim: this sounds like a property that does protocol selection that doesn't choose QUIC if you require being able to open a stream and then read without sending (TCP allows this, QUIC doesn't).
The Listen + ListenClone() discussion is moved to issue . I'll make a PR for the outcome above (protocol selection property).
NAME ping, will the protocol selection property land before the next interim?
ACK and YES. I had planned to do this today (not happening) or tomorrow (most likely) or the day after tomorrow (sigh, I hope tomorrow will work).
The "client opens the connection but server sends first" model is used in SMTP, right? It's not such an uncommon pattern.
lgtmWorks for me, but changing the name might help to get the pattern clearer

Discussion:
will necessarily be delivered, so applications cannot rely on receiving them. <ins> 5.2.17. activeReadBeforeSend Preference Ignore The most common client-server communication pattern involves the client actively opening a connection, then sending data to the server.  The server listens (passive open), reads, and then answers. This property specifies whether an application wants to diverge from this pattern - either by actively opening with Initiate(), immediately followed by reading, or passively opening with Listen(), immediately followed by writing.  This property is irrelevant for connection establishment using Rendezvous().  Requiring this property limits the choice of mappings to underlying protocols, which can reduce efficiency.  For example, it prevents the transport system from mapping Connections to SCTP streams, where the first transmitted data takes the role of an active open signal I-D.ietf-taps-impl. </ins> 5.3. Most security parameters, e.g., TLS ciphersuites, local identity and