How do you get a transport stream out of a client?

⚓ Rust    📅 2025-11-02    👤 surdeus    👁️ 3      

surdeus

Hello, I am writing an X.500 directory client in Rust. It works like LDAP in the sense that it is a request-response protocol, with messages identified with integers, and where responses can be returned in a different order from the corresponding requests. Like LDAP, the X.500 protocols have a mechanism for StartTLS, so I need to be able to swap a TCP transport for a TLS transport.

I have the code working for this quite well, but one problem that seems to be extremely hairy is designing the client so that the underlying transport can be returned to the caller. I want the caller to be able to .into_transport() and get the underlying TcpStream (or whatever other transport) back from the X.500 client. This is not only how I plan to implement StartTLS, but I also think it would be good design to be able to return the transport back to the caller, if desired.

It seems that most async libraries for similar request-response protocols don't even have this as a feature: once you hand over the transport to the client, you can never get it back. I think the idiomatic protocol client implementations, where you spawn a separate task that continually reads frames, messages, etc. in a loop from a ReadHalf, where the "parent task" keeps the WriteHalf makes it extremely complex to return the transport back to the user. It seems like any approach would at least necessitate that getting the underlying transport back would be either fallible, async, or both.

Is there an elegant way to do this at all?

1 post - 1 participant

Read full topic

🏷️ Rust_feed