Hi, please don't top post.
On Thu, Jun 25, 2026 at 10:13 AM Gianfrancesco Aurecchia < [email protected]> wrote: > Hi Jakub, > > Thanks a lot for looking at this. Your view as the ext/openssl maintainer > is exactly what I was hoping for. > > I'll be honest: I hadn't considered exposing DTLS as a stream wrapper (a > 'dtls://' built like 'tls://' is over 'tcp://'). It's a really good idea. > For the common case of a dedicated UDP socket that carries only DTLS, > that's clearly the most idiomatic and discoverable API in PHP, and much > closer to what people already know from 'tls://' than what I proposed. > > I thought about this and one thing to note is that this should be future proof solution that will support DTLS 1.3 which is currently in works and should be part of OpenSSL 4.1. Currently it doesn't look that it will support DTLSv1_listen so I would recommend to study it's implementation to make sure that the design is good for 1.3 as well. See feature/dtls-1.3 and this PR (handling the listen logic) for more details: https://github.com/openssl/openssl/pull/31137 . > So rather than seeing it as an alternative, I think we should take the > opportunity and do **both**, because the two genuinely complement each > other and cover different needs: > > - dtls://' stream wrapper: owns a UDP socket, mirrors 'tls://'. The > right default for the simple "one socket, DTLS only" case (CoAP-style, > point-to-point, a DTLS server on its own port, etc.). > - Low-level, application-driven engine (memory BIOs, > 'feed()'/'pull()'): for the cases where the application must own packet > I/O. > > > Definitely not do both of them together as it would be too much to reveiw and I don't think the low level solution is optimal anyway (see below). > That second layer isn't a stylistic preference; it's a hard requirement of > the motivating use case. In WebRTC, DTLS records are multiplexed with other > protocols on the *same* UDP 5-tuple: STUN (ICE) and SRTP/SCTP (media/data) > share one socket and are demultiplexed by the application from the first > byte of each datagram (RFC 7983 / RFC 5764). A 'dtls://' stream that owns > its socket can't serve that, since it would swallow the STUN and SRTP/SCTP > packets too, with nowhere for the application to route them. The same holds > for anything that shares a transport with DTLS. > > We are actually looking to the IO hooks where we plan to add support for IO offloading which would basically need to use custom SSL BIO . It was initially meant for io_uring but if allowed limitation per stream, then it should cover your use without exposing some extra unnecessary class. > The nice part is that these aren't two separate implementations. The > stream wrapper can be **built on top of** the same low-level engine: the > engine drives the handshake and the records, and the wrapper just adds a > UDP socket and the familiar stream API around it. **One core, two > surfaces:** the stream for the 90% simple case (exactly the 'tls://'-style > ergonomics you have in mind), and the driver for the multiplexed or > embedded cases the stream can't reach (WebRTC, and anything where DTLS > coexists with other traffic on one socket). > > I'm not sure it would be overlapping that much. Does that direction sound right to you? I'm very flexible on the surface > API. Rowan's points about certificate/key objects and enums fit either > shape, and I'll fold them in. The only property I'd want to preserve is the > ability to run DTLS without owning the socket, so the WebRTC case (the main > motivation) stays on the table. > > Yeah and that's exactly what will be possible to do with IO offloading without any need for any extra API. > For context, I already have the application-driven engine working > end-to-end against Chrome and Firefox via a pure-PHP WebRTC data channel, > so I can speak to the multiplexing requirement concretely: > https://github.com/GianfriAur/php-webrtc-datachannel > > Since the engine is already prototyped, I'm happy to also draft the > 'dtls://' stream wrapper on top of it, so we can evaluate both surfaces > against real code rather than in the abstract. If the layered direction > sounds reasonable to you, I'll put together a proof of concept of the > wrapper and share it. > I'd prefer to start only with stream and then we can discuss the offloading but for that stream implementation is prerequisite. Kind regards, Jakub
