quinn-rs / quinn-ffi

FFI bindings for Quinn QUIC protocol implemention

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Quinn FFI build for C#

Provides a thin FFI over Quinn

Main Components

Rust and C# are both safe languages, however they operate in different paradigms. The FFI is inherently unsafe between the two and therefore the right care has to be taken when designing this in-between layer. This library implements various ideas from this blog which is quite a popular reference to build FFI for rust and C#.

Handles

This library tries to minimize insecurity by introducing Handle<T>. A Handle is a wrapper of a pointer allocated on the heap. This Handle is bound by Rust safety rules. Because of those rules the calling application is prevented from abusing rust its rules. This is especially the case of C# were shared write/read access is not uncommon.

For now, there are two types of Handles: HandleMut which accepts only Send + Sync and wraps a mutable pointer, and HandleRef, which accepts only immutable pointers to types that are Send + Sync. This library defers from the blogpost who uses thread locals for synchronisation safety, however such handles could be added in the future.

In C#, ConnectionSafeHandle is a SafeHandle which wraps a pointer. A Safe Handle in C# and Handle in Rust are both pointers wrapped by some type. Any pointer given to a particular external function ought to be pointing to memory of a particular Handle type.

There are several other types that implement similar semantics: Ref, RefMut which are respectively an immutable and mutable pointer to a resource allocated by C#. Finally, there is Out which points to allocated memory in C# with the intention of initializing it in Rust. This allows us to work with the C# out were the called function initializes the calling function its state.

Invoking Rust with C# comes at some cost due to PInvoke function. It is seen as a good practice to reduce C# => Rust calls as much as possible. Since events occur once in a while this library allows to set callbacks that are called when events trigger. See the docs for what function interface the callback methods have to adhere to.

The client application MUST provide a callback for each function before the application starts running. DotQuic implements events for the given callbacks and enables different listeners for those events. And these listeners can in turn perform API actions. Be careful about calling FFI within the event handlers, as this can result in deadlocks since the callbacks are invoked in rust that probably locks some handle.

Safety

This may change in the future if it is not deemed useful. There are two api's (enabled by feature flag):

  • safe-api, performs null checks on each passed pointer to Rust, and catches all panics.
  • unsafe-api, does not perform null checks on any pointer to Rust, and does not catch panics.

Contribution

License

This contribution is dual licensed under EITHER OF

at your option.

About

FFI bindings for Quinn QUIC protocol implemention


Languages

Language:Rust 100.0%