// // This file was generated by uniffi-bindgen-cs v0.10.0+v0.29.4 // See https://github.com/NordSecurity/uniffi-bindgen-cs for more information. // #nullable enable using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Threading; namespace ProtonVPN.ProTun.Generated; using FfiConverterTypeIpAddress = FfiConverterString; using FfiConverterTypeWgClientPrivateKey = FfiConverterByteArray; using FfiConverterTypeWgPeerPublicKey = FfiConverterByteArray; using IpAddress = String; using WgClientPrivateKey = byte[]; using WgPeerPublicKey = byte[]; // This is a helper for safely working with byte buffers returned from the Rust code. // A rust-owned buffer is represented by its capacity, its current length, and a // pointer to the underlying data. [StructLayout(LayoutKind.Sequential)] internal struct RustBuffer { public ulong capacity; public ulong len; public IntPtr data; public static RustBuffer Alloc(int size) { return _UniffiHelpers.RustCall((ref UniffiRustCallStatus status) => { var buffer = _UniFFILib.ffi_protun_rustbuffer_alloc(Convert.ToUInt64(size), ref status); if (buffer.data == IntPtr.Zero) { throw new AllocationException($"RustBuffer.Alloc() returned null data pointer (size={size})"); } return buffer; }); } public static void Free(RustBuffer buffer) { _UniffiHelpers.RustCall((ref UniffiRustCallStatus status) => { _UniFFILib.ffi_protun_rustbuffer_free(buffer, ref status); }); } public static BigEndianStream MemoryStream(IntPtr data, long length) { unsafe { return new BigEndianStream(new UnmanagedMemoryStream((byte*)data.ToPointer(), length)); } } public BigEndianStream AsStream() { unsafe { return new BigEndianStream( new UnmanagedMemoryStream((byte*)data.ToPointer(), Convert.ToInt64(len)) ); } } public BigEndianStream AsWriteableStream() { unsafe { return new BigEndianStream( new UnmanagedMemoryStream( (byte*)data.ToPointer(), Convert.ToInt64(capacity), Convert.ToInt64(capacity), FileAccess.Write ) ); } } } // This is a helper for safely passing byte references into the rust code. // It's not actually used at the moment, because there aren't many things that you // can take a direct pointer to managed memory, and if we're going to copy something // then we might as well copy it into a `RustBuffer`. But it's here for API // completeness. [StructLayout(LayoutKind.Sequential)] internal struct ForeignBytes { public int length; public IntPtr data; } // The FfiConverter interface handles converter types to and from the FFI // // All implementing objects should be public to support external types. When a // type is external we need to import it's FfiConverter. internal abstract class FfiConverter { // Convert an FFI type to a C# type public abstract CsType Lift(FfiType value); // Convert C# type to an FFI type public abstract FfiType Lower(CsType value); // Read a C# type from a `ByteBuffer` public abstract CsType Read(BigEndianStream stream); // Calculate bytes to allocate when creating a `RustBuffer` // // This must return at least as many bytes as the write() function will // write. It can return more bytes than needed, for example when writing // Strings we can't know the exact bytes needed until we the UTF-8 // encoding, so we pessimistically allocate the largest size possible (3 // bytes per codepoint). Allocating extra bytes is not really a big deal // because the `RustBuffer` is short-lived. public abstract int AllocationSize(CsType value); // Write a C# type to a `ByteBuffer` public abstract void Write(CsType value, BigEndianStream stream); // Lower a value into a `RustBuffer` // // This method lowers a value into a `RustBuffer` rather than the normal // FfiType. It's used by the callback interface code. Callback interface // returns are always serialized into a `RustBuffer` regardless of their // normal FFI type. public RustBuffer LowerIntoRustBuffer(CsType value) { var rbuf = RustBuffer.Alloc(AllocationSize(value)); try { var stream = rbuf.AsWriteableStream(); Write(value, stream); rbuf.len = Convert.ToUInt64(stream.Position); return rbuf; } catch { RustBuffer.Free(rbuf); throw; } } // Lift a value from a `RustBuffer`. // // This here mostly because of the symmetry with `lowerIntoRustBuffer()`. // It's currently only used by the `FfiConverterRustBuffer` class below. protected CsType LiftFromRustBuffer(RustBuffer rbuf) { var stream = rbuf.AsStream(); try { var item = Read(stream); if (stream.HasRemaining()) { throw new InternalException("junk remaining in buffer after lifting, something is very wrong!!"); } return item; } finally { RustBuffer.Free(rbuf); } } } // FfiConverter that uses `RustBuffer` as the FfiType internal abstract class FfiConverterRustBuffer: FfiConverter { public override CsType Lift(RustBuffer value) { return LiftFromRustBuffer(value); } public override RustBuffer Lower(CsType value) { return LowerIntoRustBuffer(value); } } // A handful of classes and functions to support the generated data structures. // This would be a good candidate for isolating in its own ffi-support lib. // Error runtime. [StructLayout(LayoutKind.Sequential)] struct UniffiRustCallStatus { public sbyte code; public RustBuffer error_buf; public bool IsSuccess() { return code == 0; } public bool IsError() { return code == 1; } public bool IsPanic() { return code == 2; } } // Base class for all uniffi exceptions public class UniffiException: System.Exception { public UniffiException(): base() {} public UniffiException(string message): base(message) {} } public class UndeclaredErrorException: UniffiException { public UndeclaredErrorException(string message): base(message) {} } public class PanicException: UniffiException { public PanicException(string message): base(message) {} } public class AllocationException: UniffiException { public AllocationException(string message): base(message) {} } public class InternalException: UniffiException { public InternalException(string message): base(message) {} } public class InvalidEnumException: InternalException { public InvalidEnumException(string message): base(message) { } } public class UniffiContractVersionException: UniffiException { public UniffiContractVersionException(string message): base(message) { } } public class UniffiContractChecksumException: UniffiException { public UniffiContractChecksumException(string message): base(message) { } } // Each top-level error class has a companion object that can lift the error from the call status's rust buffer interface CallStatusErrorHandler where E: System.Exception { E Lift(RustBuffer error_buf); } // CallStatusErrorHandler implementation for times when we don't expect a CALL_ERROR class NullCallStatusErrorHandler: CallStatusErrorHandler { public static NullCallStatusErrorHandler INSTANCE = new NullCallStatusErrorHandler(); public UniffiException Lift(RustBuffer error_buf) { RustBuffer.Free(error_buf); return new UndeclaredErrorException("library has returned an error not declared in UNIFFI interface file"); } } // Helpers for calling Rust // In practice we usually need to be synchronized to call this safely, so it doesn't // synchronize itself class _UniffiHelpers { public delegate void RustCallAction(ref UniffiRustCallStatus status); public delegate U RustCallFunc(ref UniffiRustCallStatus status); // Call a rust function that returns a Result<>. Pass in the Error class companion that corresponds to the Err public static U RustCallWithError(CallStatusErrorHandler errorHandler, RustCallFunc callback) where E: UniffiException { var status = new UniffiRustCallStatus(); var return_value = callback(ref status); if (status.IsSuccess()) { return return_value; } else if (status.IsError()) { throw errorHandler.Lift(status.error_buf); } else if (status.IsPanic()) { // when the rust code sees a panic, it tries to construct a rustbuffer // with the message. but if that code panics, then it just sends back // an empty buffer. if (status.error_buf.len > 0) { throw new PanicException(FfiConverterString.INSTANCE.Lift(status.error_buf)); } else { throw new PanicException("Rust panic"); } } else { throw new InternalException($"Unknown rust call status: {status.code}"); } } // Call a rust function that returns a Result<>. Pass in the Error class companion that corresponds to the Err public static void RustCallWithError(CallStatusErrorHandler errorHandler, RustCallAction callback) where E: UniffiException { _UniffiHelpers.RustCallWithError(errorHandler, (ref UniffiRustCallStatus status) => { callback(ref status); return 0; }); } // Call a rust function that returns a plain value public static U RustCall(RustCallFunc callback) { return _UniffiHelpers.RustCallWithError(NullCallStatusErrorHandler.INSTANCE, callback); } // Call a rust function that returns a plain value public static void RustCall(RustCallAction callback) { _UniffiHelpers.RustCall((ref UniffiRustCallStatus status) => { callback(ref status); return 0; }); } } static class FFIObjectUtil { public static void DisposeAll(params Object?[] list) { Dispose(list); } // Dispose is implemented by recursive type inspection at runtime. This is because // generating correct Dispose calls for recursive complex types, e.g. List> // is quite cumbersome. private static void Dispose(Object? obj) { if (obj == null) { return; } if (obj is IDisposable disposable) { disposable.Dispose(); return; } var objType = obj.GetType(); var typeCode = Type.GetTypeCode(objType); if (typeCode != TypeCode.Object) { return; } var genericArguments = objType.GetGenericArguments(); if (genericArguments.Length == 0 && !objType.IsArray) { return; } if (obj is System.Collections.IDictionary objDictionary) { //This extra code tests to not call "Dispose" for a Dictionary() //for all values as "double" and alike doesn't support interface "IDisposable" var valuesType = objType.GetGenericArguments()[1]; var elementValuesTypeCode = Type.GetTypeCode(valuesType); if (elementValuesTypeCode != TypeCode.Object) { return; } foreach (var value in objDictionary.Values) { Dispose(value); } } else if (obj is System.Collections.IEnumerable listValues) { //This extra code tests to not call "Dispose" for a List() //for all keys as "int" and alike doesn't support interface "IDisposable" var elementType = objType.IsArray ? objType.GetElementType() : genericArguments[0]; var elementValuesTypeCode = Type.GetTypeCode(elementType); if (elementValuesTypeCode != TypeCode.Object) { return; } foreach (var value in listValues) { Dispose(value); } } } } // Big endian streams are not yet available in dotnet :'( // https://github.com/dotnet/runtime/issues/26904 class StreamUnderflowException: System.Exception { public StreamUnderflowException() { } } static class BigEndianStreamExtensions { public static void WriteInt32(this Stream stream, int value, int bytesToWrite = 4) { #if DOTNET_8_0_OR_GREATER Span buffer = stackalloc byte[bytesToWrite]; #else byte[] buffer = new byte[bytesToWrite]; #endif var posByte = bytesToWrite; while (posByte != 0) { posByte--; buffer[posByte] = (byte)(value); value >>= 8; } #if DOTNET_8_0_OR_GREATER stream.Write(buffer); #else stream.Write(buffer, 0, buffer.Length); #endif } public static void WriteInt64(this Stream stream, long value) { int bytesToWrite = 8; #if DOTNET_8_0_OR_GREATER Span buffer = stackalloc byte[bytesToWrite]; #else byte[] buffer = new byte[bytesToWrite]; #endif var posByte = bytesToWrite; while (posByte != 0) { posByte--; buffer[posByte] = (byte)(value); value >>= 8; } #if DOTNET_8_0_OR_GREATER stream.Write(buffer); #else stream.Write(buffer, 0, buffer.Length); #endif } public static uint ReadUint32(this Stream stream, int bytesToRead = 4) { CheckRemaining(stream, bytesToRead); #if DOTNET_8_0_OR_GREATER Span buffer = stackalloc byte[bytesToRead]; stream.Read(buffer); #else byte[] buffer = new byte[bytesToRead]; stream.Read(buffer, 0, bytesToRead); #endif uint result = 0; uint digitMultiplier = 1; int posByte = bytesToRead; while (posByte != 0) { posByte--; result |= buffer[posByte]*digitMultiplier; digitMultiplier <<= 8; } return result; } public static ulong ReadUInt64(this Stream stream) { int bytesToRead = 8; CheckRemaining(stream, bytesToRead); #if DOTNET_8_0_OR_GREATER Span buffer = stackalloc byte[bytesToRead]; stream.Read(buffer); #else byte[] buffer = new byte[bytesToRead]; stream.Read(buffer, 0, bytesToRead); #endif ulong result = 0; ulong digitMultiplier = 1; int posByte = bytesToRead; while (posByte != 0) { posByte--; result |= buffer[posByte]*digitMultiplier; digitMultiplier <<= 8; } return result; } public static void CheckRemaining(this Stream stream, int length) { if (stream.Length - stream.Position < length) { throw new StreamUnderflowException(); } } public static void ForEach(this T[] items, Action action){ foreach (var item in items) { action(item); } } } class BigEndianStream { Stream stream; public BigEndianStream(Stream stream) { this.stream = stream; } public bool HasRemaining() { return (stream.Length - Position) > 0; } public long Position { get => stream.Position; set => stream.Position = value; } public void WriteBytes(byte[] buffer) { #if DOTNET_8_0_OR_GREATER stream.Write(buffer); #else stream.Write(buffer, 0, buffer.Length); #endif } public void WriteByte(byte value) => stream.WriteInt32(value, bytesToWrite: 1); public void WriteSByte(sbyte value) => stream.WriteInt32(value, bytesToWrite: 1); public void WriteUShort(ushort value) => stream.WriteInt32(value, bytesToWrite: 2); public void WriteShort(short value) => stream.WriteInt32(value, bytesToWrite: 2); public void WriteUInt(uint value) => stream.WriteInt32((int)value); public void WriteInt(int value) => stream.WriteInt32(value); public void WriteULong(ulong value) => stream.WriteInt64((long)value); public void WriteLong(long value) => stream.WriteInt64(value); public void WriteFloat(float value) { unsafe { WriteInt(*((int*)&value)); } } public void WriteDouble(double value) => stream.WriteInt64(BitConverter.DoubleToInt64Bits(value)); public byte[] ReadBytes(int length) { stream.CheckRemaining(length); byte[] result = new byte[length]; stream.Read(result, 0, length); return result; } public byte ReadByte() => (byte)stream.ReadUint32(bytesToRead: 1); public ushort ReadUShort() => (ushort)stream.ReadUint32(bytesToRead: 2); public uint ReadUInt() => (uint)stream.ReadUint32(bytesToRead: 4); public ulong ReadULong() => stream.ReadUInt64(); public sbyte ReadSByte() => (sbyte)ReadByte(); public short ReadShort() => (short)ReadUShort(); public int ReadInt() => (int)ReadUInt(); public float ReadFloat() { unsafe { int value = ReadInt(); return *((float*)&value); } } public long ReadLong() => (long)ReadULong(); public double ReadDouble() => BitConverter.Int64BitsToDouble(ReadLong()); } // Contains loading, initialization code, // and the FFI Function declarations in a com.sun.jna.Library. // This is an implementation detail that will be called internally by the public API. static class _UniFFILib { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void UniffiRustFutureContinuationCallback( ulong @data,sbyte @pollResult ); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void UniffiForeignFutureFree( ulong @handle ); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void UniffiCallbackInterfaceFree( ulong @handle ); [StructLayout(LayoutKind.Sequential)] public struct UniffiForeignFuture { public ulong @handle; public IntPtr @free; } [StructLayout(LayoutKind.Sequential)] public struct UniffiForeignFutureStructU8 { public byte @returnValue; public UniffiRustCallStatus @callStatus; } [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void UniffiForeignFutureCompleteU8( ulong @callbackData,_UniFFILib.UniffiForeignFutureStructU8 @result ); [StructLayout(LayoutKind.Sequential)] public struct UniffiForeignFutureStructI8 { public sbyte @returnValue; public UniffiRustCallStatus @callStatus; } [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void UniffiForeignFutureCompleteI8( ulong @callbackData,_UniFFILib.UniffiForeignFutureStructI8 @result ); [StructLayout(LayoutKind.Sequential)] public struct UniffiForeignFutureStructU16 { public ushort @returnValue; public UniffiRustCallStatus @callStatus; } [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void UniffiForeignFutureCompleteU16( ulong @callbackData,_UniFFILib.UniffiForeignFutureStructU16 @result ); [StructLayout(LayoutKind.Sequential)] public struct UniffiForeignFutureStructI16 { public short @returnValue; public UniffiRustCallStatus @callStatus; } [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void UniffiForeignFutureCompleteI16( ulong @callbackData,_UniFFILib.UniffiForeignFutureStructI16 @result ); [StructLayout(LayoutKind.Sequential)] public struct UniffiForeignFutureStructU32 { public uint @returnValue; public UniffiRustCallStatus @callStatus; } [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void UniffiForeignFutureCompleteU32( ulong @callbackData,_UniFFILib.UniffiForeignFutureStructU32 @result ); [StructLayout(LayoutKind.Sequential)] public struct UniffiForeignFutureStructI32 { public int @returnValue; public UniffiRustCallStatus @callStatus; } [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void UniffiForeignFutureCompleteI32( ulong @callbackData,_UniFFILib.UniffiForeignFutureStructI32 @result ); [StructLayout(LayoutKind.Sequential)] public struct UniffiForeignFutureStructU64 { public ulong @returnValue; public UniffiRustCallStatus @callStatus; } [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void UniffiForeignFutureCompleteU64( ulong @callbackData,_UniFFILib.UniffiForeignFutureStructU64 @result ); [StructLayout(LayoutKind.Sequential)] public struct UniffiForeignFutureStructI64 { public long @returnValue; public UniffiRustCallStatus @callStatus; } [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void UniffiForeignFutureCompleteI64( ulong @callbackData,_UniFFILib.UniffiForeignFutureStructI64 @result ); [StructLayout(LayoutKind.Sequential)] public struct UniffiForeignFutureStructF32 { public float @returnValue; public UniffiRustCallStatus @callStatus; } [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void UniffiForeignFutureCompleteF32( ulong @callbackData,_UniFFILib.UniffiForeignFutureStructF32 @result ); [StructLayout(LayoutKind.Sequential)] public struct UniffiForeignFutureStructF64 { public double @returnValue; public UniffiRustCallStatus @callStatus; } [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void UniffiForeignFutureCompleteF64( ulong @callbackData,_UniFFILib.UniffiForeignFutureStructF64 @result ); [StructLayout(LayoutKind.Sequential)] public struct UniffiForeignFutureStructPointer { public IntPtr @returnValue; public UniffiRustCallStatus @callStatus; } [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void UniffiForeignFutureCompletePointer( ulong @callbackData,_UniFFILib.UniffiForeignFutureStructPointer @result ); [StructLayout(LayoutKind.Sequential)] public struct UniffiForeignFutureStructRustBuffer { public RustBuffer @returnValue; public UniffiRustCallStatus @callStatus; } [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void UniffiForeignFutureCompleteRustBuffer( ulong @callbackData,_UniFFILib.UniffiForeignFutureStructRustBuffer @result ); [StructLayout(LayoutKind.Sequential)] public struct UniffiForeignFutureStructVoid { public UniffiRustCallStatus @callStatus; } [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void UniffiForeignFutureCompleteVoid( ulong @callbackData,_UniFFILib.UniffiForeignFutureStructVoid @result ); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void UniffiCallbackInterfaceClientLoggerMethod0( ulong @uniffiHandle,RustBuffer @level,RustBuffer @message,IntPtr @uniffiOutReturn,ref UniffiRustCallStatus _uniffi_out_err ); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void UniffiCallbackInterfaceEventCallbackMethod0( ulong @uniffiHandle,RustBuffer @event,IntPtr @uniffiOutReturn,ref UniffiRustCallStatus _uniffi_out_err ); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void UniffiCallbackInterfaceStateChangedCallbackMethod0( ulong @uniffiHandle,RustBuffer @state,IntPtr @uniffiOutReturn,ref UniffiRustCallStatus _uniffi_out_err ); [StructLayout(LayoutKind.Sequential)] public struct UniffiVTableCallbackInterfaceClientLogger { public IntPtr @log; public IntPtr @uniffiFree; } [StructLayout(LayoutKind.Sequential)] public struct UniffiVTableCallbackInterfaceEventCallback { public IntPtr @onEvent; public IntPtr @uniffiFree; } [StructLayout(LayoutKind.Sequential)] public struct UniffiVTableCallbackInterfaceStateChangedCallback { public IntPtr @onStateChanged; public IntPtr @uniffiFree; } static _UniFFILib() { _UniFFILib.uniffiCheckContractApiVersion(); _UniFFILib.uniffiCheckApiChecksums(); UniffiCallbackInterfaceClientLogger.Register(); UniffiCallbackInterfaceEventCallback.Register(); UniffiCallbackInterfaceStateChangedCallback.Register(); } [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr uniffi_protun_fn_clone_connection(IntPtr @ptr,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void uniffi_protun_fn_free_connection(IntPtr @ptr,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void uniffi_protun_fn_method_connection_disconnect(IntPtr @ptr,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void uniffi_protun_fn_method_connection_disconnect_and_wait(IntPtr @ptr,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void uniffi_protun_fn_method_connection_get_stats(IntPtr @ptr,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void uniffi_protun_fn_method_connection_on_connectivity_change(IntPtr @ptr,RustBuffer @event,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void uniffi_protun_fn_method_connection_start_packet_capture(IntPtr @ptr,RustBuffer @pcapFile,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void uniffi_protun_fn_method_connection_stop_packet_capture(IntPtr @ptr,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void uniffi_protun_fn_method_connection_update_peers(IntPtr @ptr,RustBuffer @peers,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void uniffi_protun_fn_method_connection_update_wg_private_key(IntPtr @ptr,RustBuffer @info,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr uniffi_protun_fn_clone_protun(IntPtr @ptr,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void uniffi_protun_fn_free_protun(IntPtr @ptr,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr uniffi_protun_fn_constructor_protun_initialize(RustBuffer @logLevel,ulong @loggerCallback,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void uniffi_protun_fn_method_protun_delete_routes(IntPtr @ptr,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr uniffi_protun_fn_clone_windowsconnection(IntPtr @ptr,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void uniffi_protun_fn_free_windowsconnection(IntPtr @ptr,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr uniffi_protun_fn_constructor_windowsconnection_connect(RustBuffer @connectionConfig,RustBuffer @networkConfig,ulong @clientStateChangeCallback,ulong @eventCallback,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern RustBuffer uniffi_protun_fn_method_windowsconnection_get_adapter_details(IntPtr @ptr,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr uniffi_protun_fn_method_windowsconnection_get_connection(IntPtr @ptr,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern sbyte uniffi_protun_fn_method_windowsconnection_set_dns(IntPtr @ptr,RustBuffer @customDnsServerIps,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern sbyte uniffi_protun_fn_method_windowsconnection_set_ipv6(IntPtr @ptr,sbyte @isEnabled,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void uniffi_protun_fn_init_callback_vtable_clientlogger(ref _UniFFILib.UniffiVTableCallbackInterfaceClientLogger @vtable ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void uniffi_protun_fn_init_callback_vtable_eventcallback(ref _UniFFILib.UniffiVTableCallbackInterfaceEventCallback @vtable ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void uniffi_protun_fn_init_callback_vtable_statechangedcallback(ref _UniFFILib.UniffiVTableCallbackInterfaceStateChangedCallback @vtable ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void uniffi_protun_fn_func_init_logger(RustBuffer @level,ulong @logger,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern RustBuffer ffi_protun_rustbuffer_alloc(ulong @size,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern RustBuffer ffi_protun_rustbuffer_from_bytes(ForeignBytes @bytes,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rustbuffer_free(RustBuffer @buf,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern RustBuffer ffi_protun_rustbuffer_reserve(RustBuffer @buf,ulong @additional,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_poll_u8(IntPtr @handle,IntPtr @callback,IntPtr @callbackData ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_cancel_u8(IntPtr @handle ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_free_u8(IntPtr @handle ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern byte ffi_protun_rust_future_complete_u8(IntPtr @handle,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_poll_i8(IntPtr @handle,IntPtr @callback,IntPtr @callbackData ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_cancel_i8(IntPtr @handle ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_free_i8(IntPtr @handle ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern sbyte ffi_protun_rust_future_complete_i8(IntPtr @handle,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_poll_u16(IntPtr @handle,IntPtr @callback,IntPtr @callbackData ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_cancel_u16(IntPtr @handle ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_free_u16(IntPtr @handle ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern ushort ffi_protun_rust_future_complete_u16(IntPtr @handle,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_poll_i16(IntPtr @handle,IntPtr @callback,IntPtr @callbackData ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_cancel_i16(IntPtr @handle ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_free_i16(IntPtr @handle ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern short ffi_protun_rust_future_complete_i16(IntPtr @handle,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_poll_u32(IntPtr @handle,IntPtr @callback,IntPtr @callbackData ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_cancel_u32(IntPtr @handle ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_free_u32(IntPtr @handle ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern uint ffi_protun_rust_future_complete_u32(IntPtr @handle,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_poll_i32(IntPtr @handle,IntPtr @callback,IntPtr @callbackData ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_cancel_i32(IntPtr @handle ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_free_i32(IntPtr @handle ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern int ffi_protun_rust_future_complete_i32(IntPtr @handle,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_poll_u64(IntPtr @handle,IntPtr @callback,IntPtr @callbackData ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_cancel_u64(IntPtr @handle ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_free_u64(IntPtr @handle ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern ulong ffi_protun_rust_future_complete_u64(IntPtr @handle,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_poll_i64(IntPtr @handle,IntPtr @callback,IntPtr @callbackData ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_cancel_i64(IntPtr @handle ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_free_i64(IntPtr @handle ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern long ffi_protun_rust_future_complete_i64(IntPtr @handle,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_poll_f32(IntPtr @handle,IntPtr @callback,IntPtr @callbackData ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_cancel_f32(IntPtr @handle ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_free_f32(IntPtr @handle ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern float ffi_protun_rust_future_complete_f32(IntPtr @handle,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_poll_f64(IntPtr @handle,IntPtr @callback,IntPtr @callbackData ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_cancel_f64(IntPtr @handle ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_free_f64(IntPtr @handle ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern double ffi_protun_rust_future_complete_f64(IntPtr @handle,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_poll_pointer(IntPtr @handle,IntPtr @callback,IntPtr @callbackData ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_cancel_pointer(IntPtr @handle ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_free_pointer(IntPtr @handle ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr ffi_protun_rust_future_complete_pointer(IntPtr @handle,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_poll_rust_buffer(IntPtr @handle,IntPtr @callback,IntPtr @callbackData ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_cancel_rust_buffer(IntPtr @handle ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_free_rust_buffer(IntPtr @handle ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern RustBuffer ffi_protun_rust_future_complete_rust_buffer(IntPtr @handle,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_poll_void(IntPtr @handle,IntPtr @callback,IntPtr @callbackData ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_cancel_void(IntPtr @handle ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_free_void(IntPtr @handle ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern void ffi_protun_rust_future_complete_void(IntPtr @handle,ref UniffiRustCallStatus _uniffi_out_err ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern ushort uniffi_protun_checksum_func_init_logger( ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern ushort uniffi_protun_checksum_method_connection_disconnect( ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern ushort uniffi_protun_checksum_method_connection_disconnect_and_wait( ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern ushort uniffi_protun_checksum_method_connection_get_stats( ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern ushort uniffi_protun_checksum_method_connection_on_connectivity_change( ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern ushort uniffi_protun_checksum_method_connection_start_packet_capture( ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern ushort uniffi_protun_checksum_method_connection_stop_packet_capture( ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern ushort uniffi_protun_checksum_method_connection_update_peers( ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern ushort uniffi_protun_checksum_method_connection_update_wg_private_key( ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern ushort uniffi_protun_checksum_method_protun_delete_routes( ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern ushort uniffi_protun_checksum_method_windowsconnection_get_adapter_details( ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern ushort uniffi_protun_checksum_method_windowsconnection_get_connection( ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern ushort uniffi_protun_checksum_method_windowsconnection_set_dns( ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern ushort uniffi_protun_checksum_method_windowsconnection_set_ipv6( ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern ushort uniffi_protun_checksum_constructor_protun_initialize( ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern ushort uniffi_protun_checksum_constructor_windowsconnection_connect( ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern ushort uniffi_protun_checksum_method_clientlogger_log( ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern ushort uniffi_protun_checksum_method_eventcallback_on_event( ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern ushort uniffi_protun_checksum_method_statechangedcallback_on_state_changed( ); [DllImport("protun", CallingConvention = CallingConvention.Cdecl)] public static extern uint ffi_protun_uniffi_contract_version( ); static void uniffiCheckContractApiVersion() { var scaffolding_contract_version = _UniFFILib.ffi_protun_uniffi_contract_version(); if (29 != scaffolding_contract_version) { throw new UniffiContractVersionException($"ProtonVPN.ProTun.Generated: uniffi bindings expected version `29`, library returned `{scaffolding_contract_version}`"); } } static void uniffiCheckApiChecksums() { { var checksum = _UniFFILib.uniffi_protun_checksum_func_init_logger(); if (checksum != 64419) { throw new UniffiContractChecksumException($"ProtonVPN.ProTun.Generated: uniffi bindings expected function `uniffi_protun_checksum_func_init_logger` checksum `64419`, library returned `{checksum}`"); } } { var checksum = _UniFFILib.uniffi_protun_checksum_method_connection_disconnect(); if (checksum != 59943) { throw new UniffiContractChecksumException($"ProtonVPN.ProTun.Generated: uniffi bindings expected function `uniffi_protun_checksum_method_connection_disconnect` checksum `59943`, library returned `{checksum}`"); } } { var checksum = _UniFFILib.uniffi_protun_checksum_method_connection_disconnect_and_wait(); if (checksum != 15460) { throw new UniffiContractChecksumException($"ProtonVPN.ProTun.Generated: uniffi bindings expected function `uniffi_protun_checksum_method_connection_disconnect_and_wait` checksum `15460`, library returned `{checksum}`"); } } { var checksum = _UniFFILib.uniffi_protun_checksum_method_connection_get_stats(); if (checksum != 8320) { throw new UniffiContractChecksumException($"ProtonVPN.ProTun.Generated: uniffi bindings expected function `uniffi_protun_checksum_method_connection_get_stats` checksum `8320`, library returned `{checksum}`"); } } { var checksum = _UniFFILib.uniffi_protun_checksum_method_connection_on_connectivity_change(); if (checksum != 45238) { throw new UniffiContractChecksumException($"ProtonVPN.ProTun.Generated: uniffi bindings expected function `uniffi_protun_checksum_method_connection_on_connectivity_change` checksum `45238`, library returned `{checksum}`"); } } { var checksum = _UniFFILib.uniffi_protun_checksum_method_connection_start_packet_capture(); if (checksum != 44192) { throw new UniffiContractChecksumException($"ProtonVPN.ProTun.Generated: uniffi bindings expected function `uniffi_protun_checksum_method_connection_start_packet_capture` checksum `44192`, library returned `{checksum}`"); } } { var checksum = _UniFFILib.uniffi_protun_checksum_method_connection_stop_packet_capture(); if (checksum != 11640) { throw new UniffiContractChecksumException($"ProtonVPN.ProTun.Generated: uniffi bindings expected function `uniffi_protun_checksum_method_connection_stop_packet_capture` checksum `11640`, library returned `{checksum}`"); } } { var checksum = _UniFFILib.uniffi_protun_checksum_method_connection_update_peers(); if (checksum != 15424) { throw new UniffiContractChecksumException($"ProtonVPN.ProTun.Generated: uniffi bindings expected function `uniffi_protun_checksum_method_connection_update_peers` checksum `15424`, library returned `{checksum}`"); } } { var checksum = _UniFFILib.uniffi_protun_checksum_method_connection_update_wg_private_key(); if (checksum != 45720) { throw new UniffiContractChecksumException($"ProtonVPN.ProTun.Generated: uniffi bindings expected function `uniffi_protun_checksum_method_connection_update_wg_private_key` checksum `45720`, library returned `{checksum}`"); } } { var checksum = _UniFFILib.uniffi_protun_checksum_method_protun_delete_routes(); if (checksum != 61796) { throw new UniffiContractChecksumException($"ProtonVPN.ProTun.Generated: uniffi bindings expected function `uniffi_protun_checksum_method_protun_delete_routes` checksum `61796`, library returned `{checksum}`"); } } { var checksum = _UniFFILib.uniffi_protun_checksum_method_windowsconnection_get_adapter_details(); if (checksum != 23612) { throw new UniffiContractChecksumException($"ProtonVPN.ProTun.Generated: uniffi bindings expected function `uniffi_protun_checksum_method_windowsconnection_get_adapter_details` checksum `23612`, library returned `{checksum}`"); } } { var checksum = _UniFFILib.uniffi_protun_checksum_method_windowsconnection_get_connection(); if (checksum != 12107) { throw new UniffiContractChecksumException($"ProtonVPN.ProTun.Generated: uniffi bindings expected function `uniffi_protun_checksum_method_windowsconnection_get_connection` checksum `12107`, library returned `{checksum}`"); } } { var checksum = _UniFFILib.uniffi_protun_checksum_method_windowsconnection_set_dns(); if (checksum != 64522) { throw new UniffiContractChecksumException($"ProtonVPN.ProTun.Generated: uniffi bindings expected function `uniffi_protun_checksum_method_windowsconnection_set_dns` checksum `64522`, library returned `{checksum}`"); } } { var checksum = _UniFFILib.uniffi_protun_checksum_method_windowsconnection_set_ipv6(); if (checksum != 29942) { throw new UniffiContractChecksumException($"ProtonVPN.ProTun.Generated: uniffi bindings expected function `uniffi_protun_checksum_method_windowsconnection_set_ipv6` checksum `29942`, library returned `{checksum}`"); } } { var checksum = _UniFFILib.uniffi_protun_checksum_constructor_protun_initialize(); if (checksum != 25390) { throw new UniffiContractChecksumException($"ProtonVPN.ProTun.Generated: uniffi bindings expected function `uniffi_protun_checksum_constructor_protun_initialize` checksum `25390`, library returned `{checksum}`"); } } { var checksum = _UniFFILib.uniffi_protun_checksum_constructor_windowsconnection_connect(); if (checksum != 6810) { throw new UniffiContractChecksumException($"ProtonVPN.ProTun.Generated: uniffi bindings expected function `uniffi_protun_checksum_constructor_windowsconnection_connect` checksum `6810`, library returned `{checksum}`"); } } { var checksum = _UniFFILib.uniffi_protun_checksum_method_clientlogger_log(); if (checksum != 37409) { throw new UniffiContractChecksumException($"ProtonVPN.ProTun.Generated: uniffi bindings expected function `uniffi_protun_checksum_method_clientlogger_log` checksum `37409`, library returned `{checksum}`"); } } { var checksum = _UniFFILib.uniffi_protun_checksum_method_eventcallback_on_event(); if (checksum != 970) { throw new UniffiContractChecksumException($"ProtonVPN.ProTun.Generated: uniffi bindings expected function `uniffi_protun_checksum_method_eventcallback_on_event` checksum `970`, library returned `{checksum}`"); } } { var checksum = _UniFFILib.uniffi_protun_checksum_method_statechangedcallback_on_state_changed(); if (checksum != 30152) { throw new UniffiContractChecksumException($"ProtonVPN.ProTun.Generated: uniffi bindings expected function `uniffi_protun_checksum_method_statechangedcallback_on_state_changed` checksum `30152`, library returned `{checksum}`"); } } } } // Public interface members begin here. #pragma warning disable 8625 class FfiConverterUInt16: FfiConverter { public static FfiConverterUInt16 INSTANCE = new FfiConverterUInt16(); public override ushort Lift(ushort value) { return value; } public override ushort Read(BigEndianStream stream) { return stream.ReadUShort(); } public override ushort Lower(ushort value) { return value; } public override int AllocationSize(ushort value) { return 2; } public override void Write(ushort value, BigEndianStream stream) { stream.WriteUShort(value); } } class FfiConverterUInt32: FfiConverter { public static FfiConverterUInt32 INSTANCE = new FfiConverterUInt32(); public override uint Lift(uint value) { return value; } public override uint Read(BigEndianStream stream) { return stream.ReadUInt(); } public override uint Lower(uint value) { return value; } public override int AllocationSize(uint value) { return 4; } public override void Write(uint value, BigEndianStream stream) { stream.WriteUInt(value); } } class FfiConverterInt32: FfiConverter { public static FfiConverterInt32 INSTANCE = new FfiConverterInt32(); public override int Lift(int value) { return value; } public override int Read(BigEndianStream stream) { return stream.ReadInt(); } public override int Lower(int value) { return value; } public override int AllocationSize(int value) { return 4; } public override void Write(int value, BigEndianStream stream) { stream.WriteInt(value); } } class FfiConverterUInt64: FfiConverter { public static FfiConverterUInt64 INSTANCE = new FfiConverterUInt64(); public override ulong Lift(ulong value) { return value; } public override ulong Read(BigEndianStream stream) { return stream.ReadULong(); } public override ulong Lower(ulong value) { return value; } public override int AllocationSize(ulong value) { return 8; } public override void Write(ulong value, BigEndianStream stream) { stream.WriteULong(value); } } class FfiConverterFloat: FfiConverter { public static FfiConverterFloat INSTANCE = new FfiConverterFloat(); public override float Lift(float value) { return value; } public override float Read(BigEndianStream stream) { return stream.ReadFloat(); } public override float Lower(float value) { return value; } public override int AllocationSize(float value) { return 4; } public override void Write(float value, BigEndianStream stream) { stream.WriteFloat(value); } } class FfiConverterBoolean: FfiConverter { public static FfiConverterBoolean INSTANCE = new FfiConverterBoolean(); public override bool Lift(sbyte value) { return value != 0; } public override bool Read(BigEndianStream stream) { return Lift(stream.ReadSByte()); } public override sbyte Lower(bool value) { return value ? (sbyte)1 : (sbyte)0; } public override int AllocationSize(bool value) { return (sbyte)1; } public override void Write(bool value, BigEndianStream stream) { stream.WriteSByte(Lower(value)); } } class FfiConverterString: FfiConverter { public static FfiConverterString INSTANCE = new FfiConverterString(); // Note: we don't inherit from FfiConverterRustBuffer, because we use a // special encoding when lowering/lifting. We can use `RustBuffer.len` to // store our length and avoid writing it out to the buffer. public override string Lift(RustBuffer value) { try { var bytes = value.AsStream().ReadBytes(Convert.ToInt32(value.len)); return System.Text.Encoding.UTF8.GetString(bytes); } finally { RustBuffer.Free(value); } } public override string Read(BigEndianStream stream) { var length = stream.ReadInt(); var bytes = stream.ReadBytes(length); return System.Text.Encoding.UTF8.GetString(bytes); } public override RustBuffer Lower(string value) { var bytes = System.Text.Encoding.UTF8.GetBytes(value); var rbuf = RustBuffer.Alloc(bytes.Length); rbuf.AsWriteableStream().WriteBytes(bytes); return rbuf; } // TODO(CS) // We aren't sure exactly how many bytes our string will be once it's UTF-8 // encoded. Allocate 3 bytes per unicode codepoint which will always be // enough. public override int AllocationSize(string value) { const int sizeForLength = 4; var sizeForString = System.Text.Encoding.UTF8.GetByteCount(value); return sizeForLength + sizeForString; } public override void Write(string value, BigEndianStream stream) { var bytes = System.Text.Encoding.UTF8.GetBytes(value); stream.WriteInt(bytes.Length); stream.WriteBytes(bytes); } } class FfiConverterByteArray: FfiConverterRustBuffer { public static FfiConverterByteArray INSTANCE = new FfiConverterByteArray(); public override byte[] Read(BigEndianStream stream) { var length = stream.ReadInt(); return stream.ReadBytes(length); } public override int AllocationSize(byte[] value) { return 4 + value.Length; } public override void Write(byte[] value, BigEndianStream stream) { stream.WriteInt(value.Length); stream.WriteBytes(value); } } class FfiConverterDuration: FfiConverterRustBuffer { public static FfiConverterDuration INSTANCE = new FfiConverterDuration(); // https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/TimeSpan.cs private const uint NanosecondsPerTick = 100; public override TimeSpan Read(BigEndianStream stream) { var seconds = stream.ReadULong(); var nanoseconds = stream.ReadUInt(); var ticks = seconds * TimeSpan.TicksPerSecond; ticks += nanoseconds / NanosecondsPerTick; return new TimeSpan(Convert.ToInt64(ticks)); } public override int AllocationSize(TimeSpan value) { // 8 bytes for seconds, 4 bytes for nanoseconds return 12; } public override void Write(TimeSpan value, BigEndianStream stream) { stream.WriteULong(Convert.ToUInt64(value.Ticks / TimeSpan.TicksPerSecond)); stream.WriteUInt(Convert.ToUInt32(value.Ticks % TimeSpan.TicksPerSecond * NanosecondsPerTick)); } } /// /// Represents an active VPN connection. /// Platform-specific constructor (::*_connect) is defined in dedicated module /// (see e.g. [crate::api::connection_unix]). Helper constructor capturing common logic /// ([Connection::connect_internal]) is added for convenience. /// /// Connection will make a best effort to maintain VPN connection cycling through a set of candidate peers /// (along with ports and protocols) based on their priority and availability in current network conditions. /// /// For initializing logging, see [crate::api::logger::init_logger]. /// public interface IConnection { /// /// Disconnects. Connection should not be used after this. /// void Disconnect(); /// /// Disconnects and waits for the connection to be fully closed. /// void DisconnectAndWait(); void GetStats(); /// /// Call it when connectivity or underlying network adapter(s) change /// (e.g. network switched from wifi to mobile). Library will use that information /// to reset VPN connection sockets. /// void OnConnectivityChange(ConnectivityEvent @event); void StartPacketCapture(PcapFileInfo @pcapFile); void StopPacketCapture(); /// /// Updates candidate peers for connection. /// Method call might not necessarily result in new connection if suitable peer is already connected. /// void UpdatePeers(PeerInfo[] @peers); /// /// Updates WireGuard private key. /// void UpdateWgPrivateKey(PrivateKeyUpdateInfo @info); } /// /// Represents an active VPN connection. /// Platform-specific constructor (::*_connect) is defined in dedicated module /// (see e.g. [crate::api::connection_unix]). Helper constructor capturing common logic /// ([Connection::connect_internal]) is added for convenience. /// /// Connection will make a best effort to maintain VPN connection cycling through a set of candidate peers /// (along with ports and protocols) based on their priority and availability in current network conditions. /// /// For initializing logging, see [crate::api::logger::init_logger]. /// public class Connection : IConnection, IDisposable { protected IntPtr pointer; private int _wasDestroyed = 0; private long _callCounter = 1; public Connection(IntPtr pointer) { this.pointer = pointer; } ~Connection() { Destroy(); } protected void FreeRustArcPtr() { _UniffiHelpers.RustCall((ref UniffiRustCallStatus status) => { _UniFFILib.uniffi_protun_fn_free_connection(this.pointer, ref status); }); } protected IntPtr CloneRustArcPtr() { return _UniffiHelpers.RustCall((ref UniffiRustCallStatus status) => { return _UniFFILib.uniffi_protun_fn_clone_connection(this.pointer, ref status); }); } public void Destroy() { // Only allow a single call to this method. if (Interlocked.CompareExchange(ref _wasDestroyed, 1, 0) == 0) { // This decrement always matches the initial count of 1 given at creation time. if (Interlocked.Decrement(ref _callCounter) == 0) { FreeRustArcPtr(); } } } public void Dispose() { Destroy(); GC.SuppressFinalize(this); // Suppress finalization to avoid unnecessary GC overhead. } private void IncrementCallCounter() { // Check and increment the call counter, to keep the object alive. // This needs a compare-and-set retry loop in case of concurrent updates. long count; do { count = Interlocked.Read(ref _callCounter); if (count == 0L) throw new System.ObjectDisposedException(String.Format("'{0}' object has already been destroyed", this.GetType().Name)); if (count == long.MaxValue) throw new System.OverflowException(String.Format("'{0}' call counter would overflow", this.GetType().Name)); } while (Interlocked.CompareExchange(ref _callCounter, count + 1, count) != count); } private void DecrementCallCounter() { // This decrement always matches the increment we performed above. if (Interlocked.Decrement(ref _callCounter) == 0) { FreeRustArcPtr(); } } internal void CallWithPointer(Action action) { IncrementCallCounter(); try { action(CloneRustArcPtr()); } finally { DecrementCallCounter(); } } internal T CallWithPointer(Func func) { IncrementCallCounter(); try { return func(CloneRustArcPtr()); } finally { DecrementCallCounter(); } } /// /// Disconnects. Connection should not be used after this. /// public void Disconnect() { CallWithPointer(thisPtr => _UniffiHelpers.RustCall( (ref UniffiRustCallStatus _status) => _UniFFILib.uniffi_protun_fn_method_connection_disconnect(thisPtr, ref _status) )); } /// /// Disconnects and waits for the connection to be fully closed. /// public void DisconnectAndWait() { CallWithPointer(thisPtr => _UniffiHelpers.RustCall( (ref UniffiRustCallStatus _status) => _UniFFILib.uniffi_protun_fn_method_connection_disconnect_and_wait(thisPtr, ref _status) )); } public void GetStats() { CallWithPointer(thisPtr => _UniffiHelpers.RustCall( (ref UniffiRustCallStatus _status) => _UniFFILib.uniffi_protun_fn_method_connection_get_stats(thisPtr, ref _status) )); } /// /// Call it when connectivity or underlying network adapter(s) change /// (e.g. network switched from wifi to mobile). Library will use that information /// to reset VPN connection sockets. /// public void OnConnectivityChange(ConnectivityEvent @event) { CallWithPointer(thisPtr => _UniffiHelpers.RustCall( (ref UniffiRustCallStatus _status) => _UniFFILib.uniffi_protun_fn_method_connection_on_connectivity_change(thisPtr, FfiConverterTypeConnectivityEvent.INSTANCE.Lower(@event), ref _status) )); } public void StartPacketCapture(PcapFileInfo @pcapFile) { CallWithPointer(thisPtr => _UniffiHelpers.RustCall( (ref UniffiRustCallStatus _status) => _UniFFILib.uniffi_protun_fn_method_connection_start_packet_capture(thisPtr, FfiConverterTypePcapFileInfo.INSTANCE.Lower(@pcapFile), ref _status) )); } public void StopPacketCapture() { CallWithPointer(thisPtr => _UniffiHelpers.RustCall( (ref UniffiRustCallStatus _status) => _UniFFILib.uniffi_protun_fn_method_connection_stop_packet_capture(thisPtr, ref _status) )); } /// /// Updates candidate peers for connection. /// Method call might not necessarily result in new connection if suitable peer is already connected. /// public void UpdatePeers(PeerInfo[] @peers) { CallWithPointer(thisPtr => _UniffiHelpers.RustCall( (ref UniffiRustCallStatus _status) => _UniFFILib.uniffi_protun_fn_method_connection_update_peers(thisPtr, FfiConverterSequenceTypePeerInfo.INSTANCE.Lower(@peers), ref _status) )); } /// /// Updates WireGuard private key. /// public void UpdateWgPrivateKey(PrivateKeyUpdateInfo @info) { CallWithPointer(thisPtr => _UniffiHelpers.RustCall( (ref UniffiRustCallStatus _status) => _UniFFILib.uniffi_protun_fn_method_connection_update_wg_private_key(thisPtr, FfiConverterTypePrivateKeyUpdateInfo.INSTANCE.Lower(@info), ref _status) )); } } class FfiConverterTypeConnection: FfiConverter { public static FfiConverterTypeConnection INSTANCE = new FfiConverterTypeConnection(); public override IntPtr Lower(Connection value) { return value.CallWithPointer(thisPtr => thisPtr); } public override Connection Lift(IntPtr value) { return new Connection(value); } public override Connection Read(BigEndianStream stream) { return Lift(new IntPtr(stream.ReadLong())); } public override int AllocationSize(Connection value) { return 8; } public override void Write(Connection value, BigEndianStream stream) { stream.WriteLong(Lower(value).ToInt64()); } } public interface IProTun { void DeleteRoutes(); } public class ProTun : IProTun, IDisposable { protected IntPtr pointer; private int _wasDestroyed = 0; private long _callCounter = 1; public ProTun(IntPtr pointer) { this.pointer = pointer; } ~ProTun() { Destroy(); } protected void FreeRustArcPtr() { _UniffiHelpers.RustCall((ref UniffiRustCallStatus status) => { _UniFFILib.uniffi_protun_fn_free_protun(this.pointer, ref status); }); } protected IntPtr CloneRustArcPtr() { return _UniffiHelpers.RustCall((ref UniffiRustCallStatus status) => { return _UniFFILib.uniffi_protun_fn_clone_protun(this.pointer, ref status); }); } public void Destroy() { // Only allow a single call to this method. if (Interlocked.CompareExchange(ref _wasDestroyed, 1, 0) == 0) { // This decrement always matches the initial count of 1 given at creation time. if (Interlocked.Decrement(ref _callCounter) == 0) { FreeRustArcPtr(); } } } public void Dispose() { Destroy(); GC.SuppressFinalize(this); // Suppress finalization to avoid unnecessary GC overhead. } private void IncrementCallCounter() { // Check and increment the call counter, to keep the object alive. // This needs a compare-and-set retry loop in case of concurrent updates. long count; do { count = Interlocked.Read(ref _callCounter); if (count == 0L) throw new System.ObjectDisposedException(String.Format("'{0}' object has already been destroyed", this.GetType().Name)); if (count == long.MaxValue) throw new System.OverflowException(String.Format("'{0}' call counter would overflow", this.GetType().Name)); } while (Interlocked.CompareExchange(ref _callCounter, count + 1, count) != count); } private void DecrementCallCounter() { // This decrement always matches the increment we performed above. if (Interlocked.Decrement(ref _callCounter) == 0) { FreeRustArcPtr(); } } internal void CallWithPointer(Action action) { IncrementCallCounter(); try { action(CloneRustArcPtr()); } finally { DecrementCallCounter(); } } internal T CallWithPointer(Func func) { IncrementCallCounter(); try { return func(CloneRustArcPtr()); } finally { DecrementCallCounter(); } } public void DeleteRoutes() { CallWithPointer(thisPtr => _UniffiHelpers.RustCall( (ref UniffiRustCallStatus _status) => _UniFFILib.uniffi_protun_fn_method_protun_delete_routes(thisPtr, ref _status) )); } /// public static ProTun Initialize(LogLevel @logLevel, ClientLogger @loggerCallback) { return new ProTun( _UniffiHelpers.RustCallWithError(FfiConverterTypeProTunFatalError.INSTANCE, (ref UniffiRustCallStatus _status) => _UniFFILib.uniffi_protun_fn_constructor_protun_initialize(FfiConverterTypeLogLevel.INSTANCE.Lower(@logLevel), FfiConverterTypeClientLogger.INSTANCE.Lower(@loggerCallback), ref _status) )); } } class FfiConverterTypeProTun: FfiConverter { public static FfiConverterTypeProTun INSTANCE = new FfiConverterTypeProTun(); public override IntPtr Lower(ProTun value) { return value.CallWithPointer(thisPtr => thisPtr); } public override ProTun Lift(IntPtr value) { return new ProTun(value); } public override ProTun Read(BigEndianStream stream) { return Lift(new IntPtr(stream.ReadLong())); } public override int AllocationSize(ProTun value) { return 8; } public override void Write(ProTun value, BigEndianStream stream) { stream.WriteLong(Lower(value).ToInt64()); } } public interface IWindowsConnection { ProTunAdapterDetails GetAdapterDetails(); Connection GetConnection(); /// bool SetDns(IpAddress[] @customDnsServerIps); /// bool SetIpv6(bool @isEnabled); } public class WindowsConnection : IWindowsConnection, IDisposable { protected IntPtr pointer; private int _wasDestroyed = 0; private long _callCounter = 1; public WindowsConnection(IntPtr pointer) { this.pointer = pointer; } ~WindowsConnection() { Destroy(); } protected void FreeRustArcPtr() { _UniffiHelpers.RustCall((ref UniffiRustCallStatus status) => { _UniFFILib.uniffi_protun_fn_free_windowsconnection(this.pointer, ref status); }); } protected IntPtr CloneRustArcPtr() { return _UniffiHelpers.RustCall((ref UniffiRustCallStatus status) => { return _UniFFILib.uniffi_protun_fn_clone_windowsconnection(this.pointer, ref status); }); } public void Destroy() { // Only allow a single call to this method. if (Interlocked.CompareExchange(ref _wasDestroyed, 1, 0) == 0) { // This decrement always matches the initial count of 1 given at creation time. if (Interlocked.Decrement(ref _callCounter) == 0) { FreeRustArcPtr(); } } } public void Dispose() { Destroy(); GC.SuppressFinalize(this); // Suppress finalization to avoid unnecessary GC overhead. } private void IncrementCallCounter() { // Check and increment the call counter, to keep the object alive. // This needs a compare-and-set retry loop in case of concurrent updates. long count; do { count = Interlocked.Read(ref _callCounter); if (count == 0L) throw new System.ObjectDisposedException(String.Format("'{0}' object has already been destroyed", this.GetType().Name)); if (count == long.MaxValue) throw new System.OverflowException(String.Format("'{0}' call counter would overflow", this.GetType().Name)); } while (Interlocked.CompareExchange(ref _callCounter, count + 1, count) != count); } private void DecrementCallCounter() { // This decrement always matches the increment we performed above. if (Interlocked.Decrement(ref _callCounter) == 0) { FreeRustArcPtr(); } } internal void CallWithPointer(Action action) { IncrementCallCounter(); try { action(CloneRustArcPtr()); } finally { DecrementCallCounter(); } } internal T CallWithPointer(Func func) { IncrementCallCounter(); try { return func(CloneRustArcPtr()); } finally { DecrementCallCounter(); } } public ProTunAdapterDetails GetAdapterDetails() { return CallWithPointer(thisPtr => FfiConverterTypeProTunAdapterDetails.INSTANCE.Lift( _UniffiHelpers.RustCall( (ref UniffiRustCallStatus _status) => _UniFFILib.uniffi_protun_fn_method_windowsconnection_get_adapter_details(thisPtr, ref _status) ))); } public Connection GetConnection() { return CallWithPointer(thisPtr => FfiConverterTypeConnection.INSTANCE.Lift( _UniffiHelpers.RustCall( (ref UniffiRustCallStatus _status) => _UniFFILib.uniffi_protun_fn_method_windowsconnection_get_connection(thisPtr, ref _status) ))); } /// public bool SetDns(IpAddress[] @customDnsServerIps) { return CallWithPointer(thisPtr => FfiConverterBoolean.INSTANCE.Lift( _UniffiHelpers.RustCallWithError(FfiConverterTypeProTunFatalError.INSTANCE, (ref UniffiRustCallStatus _status) => _UniFFILib.uniffi_protun_fn_method_windowsconnection_set_dns(thisPtr, FfiConverterSequenceTypeIpAddress.INSTANCE.Lower(@customDnsServerIps), ref _status) ))); } /// public bool SetIpv6(bool @isEnabled) { return CallWithPointer(thisPtr => FfiConverterBoolean.INSTANCE.Lift( _UniffiHelpers.RustCallWithError(FfiConverterTypeProTunFatalError.INSTANCE, (ref UniffiRustCallStatus _status) => _UniFFILib.uniffi_protun_fn_method_windowsconnection_set_ipv6(thisPtr, FfiConverterBoolean.INSTANCE.Lower(@isEnabled), ref _status) ))); } /// public static WindowsConnection Connect(InitialConnectionConfig @connectionConfig, NetworkConfig @networkConfig, StateChangedCallback @clientStateChangeCallback, EventCallback @eventCallback) { return new WindowsConnection( _UniffiHelpers.RustCallWithError(FfiConverterTypeProTunFatalError.INSTANCE, (ref UniffiRustCallStatus _status) => _UniFFILib.uniffi_protun_fn_constructor_windowsconnection_connect(FfiConverterTypeInitialConnectionConfig.INSTANCE.Lower(@connectionConfig), FfiConverterTypeNetworkConfig.INSTANCE.Lower(@networkConfig), FfiConverterTypeStateChangedCallback.INSTANCE.Lower(@clientStateChangeCallback), FfiConverterTypeEventCallback.INSTANCE.Lower(@eventCallback), ref _status) )); } } class FfiConverterTypeWindowsConnection: FfiConverter { public static FfiConverterTypeWindowsConnection INSTANCE = new FfiConverterTypeWindowsConnection(); public override IntPtr Lower(WindowsConnection value) { return value.CallWithPointer(thisPtr => thisPtr); } public override WindowsConnection Lift(IntPtr value) { return new WindowsConnection(value); } public override WindowsConnection Read(BigEndianStream stream) { return Lift(new IntPtr(stream.ReadLong())); } public override int AllocationSize(WindowsConnection value) { return 8; } public override void Write(WindowsConnection value, BigEndianStream stream) { stream.WriteLong(Lower(value).ToInt64()); } } public record AdapterConfig ( IpAddress[] @customDnsServerIps, bool @isIpv6Enabled, ushort @mtu, uint @bufferSizeBytes ) { } class FfiConverterTypeAdapterConfig: FfiConverterRustBuffer { public static FfiConverterTypeAdapterConfig INSTANCE = new FfiConverterTypeAdapterConfig(); public override AdapterConfig Read(BigEndianStream stream) { return new AdapterConfig( @customDnsServerIps: FfiConverterSequenceTypeIpAddress.INSTANCE.Read(stream), @isIpv6Enabled: FfiConverterBoolean.INSTANCE.Read(stream), @mtu: FfiConverterUInt16.INSTANCE.Read(stream), @bufferSizeBytes: FfiConverterUInt32.INSTANCE.Read(stream) ); } public override int AllocationSize(AdapterConfig value) { return 0 + FfiConverterSequenceTypeIpAddress.INSTANCE.AllocationSize(value.@customDnsServerIps) + FfiConverterBoolean.INSTANCE.AllocationSize(value.@isIpv6Enabled) + FfiConverterUInt16.INSTANCE.AllocationSize(value.@mtu) + FfiConverterUInt32.INSTANCE.AllocationSize(value.@bufferSizeBytes); } public override void Write(AdapterConfig value, BigEndianStream stream) { FfiConverterSequenceTypeIpAddress.INSTANCE.Write(value.@customDnsServerIps, stream); FfiConverterBoolean.INSTANCE.Write(value.@isIpv6Enabled, stream); FfiConverterUInt16.INSTANCE.Write(value.@mtu, stream); FfiConverterUInt32.INSTANCE.Write(value.@bufferSizeBytes, stream); } } public record InitialConnectionConfig ( WgClientPrivateKey @wgPrivateKey, PeerInfo[] @peers, bool @networkAvailable, PcapFileInfo? @pcapFile ) { } class FfiConverterTypeInitialConnectionConfig: FfiConverterRustBuffer { public static FfiConverterTypeInitialConnectionConfig INSTANCE = new FfiConverterTypeInitialConnectionConfig(); public override InitialConnectionConfig Read(BigEndianStream stream) { return new InitialConnectionConfig( @wgPrivateKey: FfiConverterTypeWgClientPrivateKey.INSTANCE.Read(stream), @peers: FfiConverterSequenceTypePeerInfo.INSTANCE.Read(stream), @networkAvailable: FfiConverterBoolean.INSTANCE.Read(stream), @pcapFile: FfiConverterOptionalTypePcapFileInfo.INSTANCE.Read(stream) ); } public override int AllocationSize(InitialConnectionConfig value) { return 0 + FfiConverterTypeWgClientPrivateKey.INSTANCE.AllocationSize(value.@wgPrivateKey) + FfiConverterSequenceTypePeerInfo.INSTANCE.AllocationSize(value.@peers) + FfiConverterBoolean.INSTANCE.AllocationSize(value.@networkAvailable) + FfiConverterOptionalTypePcapFileInfo.INSTANCE.AllocationSize(value.@pcapFile); } public override void Write(InitialConnectionConfig value, BigEndianStream stream) { FfiConverterTypeWgClientPrivateKey.INSTANCE.Write(value.@wgPrivateKey, stream); FfiConverterSequenceTypePeerInfo.INSTANCE.Write(value.@peers, stream); FfiConverterBoolean.INSTANCE.Write(value.@networkAvailable, stream); FfiConverterOptionalTypePcapFileInfo.INSTANCE.Write(value.@pcapFile, stream); } } public record NetworkConfig ( AdapterConfig @tunAdapter, SocketConfig @udpSocket ) { } class FfiConverterTypeNetworkConfig: FfiConverterRustBuffer { public static FfiConverterTypeNetworkConfig INSTANCE = new FfiConverterTypeNetworkConfig(); public override NetworkConfig Read(BigEndianStream stream) { return new NetworkConfig( @tunAdapter: FfiConverterTypeAdapterConfig.INSTANCE.Read(stream), @udpSocket: FfiConverterTypeSocketConfig.INSTANCE.Read(stream) ); } public override int AllocationSize(NetworkConfig value) { return 0 + FfiConverterTypeAdapterConfig.INSTANCE.AllocationSize(value.@tunAdapter) + FfiConverterTypeSocketConfig.INSTANCE.AllocationSize(value.@udpSocket); } public override void Write(NetworkConfig value, BigEndianStream stream) { FfiConverterTypeAdapterConfig.INSTANCE.Write(value.@tunAdapter, stream); FfiConverterTypeSocketConfig.INSTANCE.Write(value.@udpSocket, stream); } } /// /// File size limit in bytes. When the limit is reached, the library will stop writing. /// public record PcapFileInfo ( PcapFile @file, /// /// File size limit in bytes. When the limit is reached, the library will stop writing. /// ulong? @maxBytes ) { } class FfiConverterTypePcapFileInfo: FfiConverterRustBuffer { public static FfiConverterTypePcapFileInfo INSTANCE = new FfiConverterTypePcapFileInfo(); public override PcapFileInfo Read(BigEndianStream stream) { return new PcapFileInfo( @file: FfiConverterTypePcapFile.INSTANCE.Read(stream), @maxBytes: FfiConverterOptionalUInt64.INSTANCE.Read(stream) ); } public override int AllocationSize(PcapFileInfo value) { return 0 + FfiConverterTypePcapFile.INSTANCE.AllocationSize(value.@file) + FfiConverterOptionalUInt64.INSTANCE.AllocationSize(value.@maxBytes); } public override void Write(PcapFileInfo value, BigEndianStream stream) { FfiConverterTypePcapFile.INSTANCE.Write(value.@file, stream); FfiConverterOptionalUInt64.INSTANCE.Write(value.@maxBytes, stream); } } public record PeerConnectionInfo ( string @peerId, string @entryIp, Protocol @protocol, ushort @port ) { } class FfiConverterTypePeerConnectionInfo: FfiConverterRustBuffer { public static FfiConverterTypePeerConnectionInfo INSTANCE = new FfiConverterTypePeerConnectionInfo(); public override PeerConnectionInfo Read(BigEndianStream stream) { return new PeerConnectionInfo( @peerId: FfiConverterString.INSTANCE.Read(stream), @entryIp: FfiConverterString.INSTANCE.Read(stream), @protocol: FfiConverterTypeProtocol.INSTANCE.Read(stream), @port: FfiConverterUInt16.INSTANCE.Read(stream) ); } public override int AllocationSize(PeerConnectionInfo value) { return 0 + FfiConverterString.INSTANCE.AllocationSize(value.@peerId) + FfiConverterString.INSTANCE.AllocationSize(value.@entryIp) + FfiConverterTypeProtocol.INSTANCE.AllocationSize(value.@protocol) + FfiConverterUInt16.INSTANCE.AllocationSize(value.@port); } public override void Write(PeerConnectionInfo value, BigEndianStream stream) { FfiConverterString.INSTANCE.Write(value.@peerId, stream); FfiConverterString.INSTANCE.Write(value.@entryIp, stream); FfiConverterTypeProtocol.INSTANCE.Write(value.@protocol, stream); FfiConverterUInt16.INSTANCE.Write(value.@port, stream); } } /// /// Represents a candidate peer for connection. /// /// /// Unique identifier of connected peer (as defined by client). This id will be available in /// connection states when given peer is connecting/connected (see peer_id in [State]). /// public record PeerInfo ( /// /// Unique identifier of connected peer (as defined by client). This id will be available in /// connection states when given peer is connecting/connected (see peer_id in [State]). /// string @peerId, IpAddress @serverIp, WgPeerPublicKey @serverPublicKey, ushort[] @udpPorts, ushort[] @tcpPorts, ushort[] @tlsPorts, int @priority ) { } class FfiConverterTypePeerInfo: FfiConverterRustBuffer { public static FfiConverterTypePeerInfo INSTANCE = new FfiConverterTypePeerInfo(); public override PeerInfo Read(BigEndianStream stream) { return new PeerInfo( @peerId: FfiConverterString.INSTANCE.Read(stream), @serverIp: FfiConverterTypeIpAddress.INSTANCE.Read(stream), @serverPublicKey: FfiConverterTypeWgPeerPublicKey.INSTANCE.Read(stream), @udpPorts: FfiConverterSequenceUInt16.INSTANCE.Read(stream), @tcpPorts: FfiConverterSequenceUInt16.INSTANCE.Read(stream), @tlsPorts: FfiConverterSequenceUInt16.INSTANCE.Read(stream), @priority: FfiConverterInt32.INSTANCE.Read(stream) ); } public override int AllocationSize(PeerInfo value) { return 0 + FfiConverterString.INSTANCE.AllocationSize(value.@peerId) + FfiConverterTypeIpAddress.INSTANCE.AllocationSize(value.@serverIp) + FfiConverterTypeWgPeerPublicKey.INSTANCE.AllocationSize(value.@serverPublicKey) + FfiConverterSequenceUInt16.INSTANCE.AllocationSize(value.@udpPorts) + FfiConverterSequenceUInt16.INSTANCE.AllocationSize(value.@tcpPorts) + FfiConverterSequenceUInt16.INSTANCE.AllocationSize(value.@tlsPorts) + FfiConverterInt32.INSTANCE.AllocationSize(value.@priority); } public override void Write(PeerInfo value, BigEndianStream stream) { FfiConverterString.INSTANCE.Write(value.@peerId, stream); FfiConverterTypeIpAddress.INSTANCE.Write(value.@serverIp, stream); FfiConverterTypeWgPeerPublicKey.INSTANCE.Write(value.@serverPublicKey, stream); FfiConverterSequenceUInt16.INSTANCE.Write(value.@udpPorts, stream); FfiConverterSequenceUInt16.INSTANCE.Write(value.@tcpPorts, stream); FfiConverterSequenceUInt16.INSTANCE.Write(value.@tlsPorts, stream); FfiConverterInt32.INSTANCE.Write(value.@priority, stream); } } public record PrivateKeyUpdateInfo ( WgClientPrivateKey @wgPrivateKey ) { } class FfiConverterTypePrivateKeyUpdateInfo: FfiConverterRustBuffer { public static FfiConverterTypePrivateKeyUpdateInfo INSTANCE = new FfiConverterTypePrivateKeyUpdateInfo(); public override PrivateKeyUpdateInfo Read(BigEndianStream stream) { return new PrivateKeyUpdateInfo( @wgPrivateKey: FfiConverterTypeWgClientPrivateKey.INSTANCE.Read(stream) ); } public override int AllocationSize(PrivateKeyUpdateInfo value) { return 0 + FfiConverterTypeWgClientPrivateKey.INSTANCE.AllocationSize(value.@wgPrivateKey); } public override void Write(PrivateKeyUpdateInfo value, BigEndianStream stream) { FfiConverterTypeWgClientPrivateKey.INSTANCE.Write(value.@wgPrivateKey, stream); } } public record ProTunAdapterDetails ( uint @interfaceIndex, string @clientIpv4Addr, string @serverIpv4Addr, string @clientIpv6Addr, string @serverIpv6Addr ) { } class FfiConverterTypeProTunAdapterDetails: FfiConverterRustBuffer { public static FfiConverterTypeProTunAdapterDetails INSTANCE = new FfiConverterTypeProTunAdapterDetails(); public override ProTunAdapterDetails Read(BigEndianStream stream) { return new ProTunAdapterDetails( @interfaceIndex: FfiConverterUInt32.INSTANCE.Read(stream), @clientIpv4Addr: FfiConverterString.INSTANCE.Read(stream), @serverIpv4Addr: FfiConverterString.INSTANCE.Read(stream), @clientIpv6Addr: FfiConverterString.INSTANCE.Read(stream), @serverIpv6Addr: FfiConverterString.INSTANCE.Read(stream) ); } public override int AllocationSize(ProTunAdapterDetails value) { return 0 + FfiConverterUInt32.INSTANCE.AllocationSize(value.@interfaceIndex) + FfiConverterString.INSTANCE.AllocationSize(value.@clientIpv4Addr) + FfiConverterString.INSTANCE.AllocationSize(value.@serverIpv4Addr) + FfiConverterString.INSTANCE.AllocationSize(value.@clientIpv6Addr) + FfiConverterString.INSTANCE.AllocationSize(value.@serverIpv6Addr); } public override void Write(ProTunAdapterDetails value, BigEndianStream stream) { FfiConverterUInt32.INSTANCE.Write(value.@interfaceIndex, stream); FfiConverterString.INSTANCE.Write(value.@clientIpv4Addr, stream); FfiConverterString.INSTANCE.Write(value.@serverIpv4Addr, stream); FfiConverterString.INSTANCE.Write(value.@clientIpv6Addr, stream); FfiConverterString.INSTANCE.Write(value.@serverIpv6Addr, stream); } } public record SocketConfig ( uint @sendBufferSizeBytes, uint @receiveBufferSizeBytes ) { } class FfiConverterTypeSocketConfig: FfiConverterRustBuffer { public static FfiConverterTypeSocketConfig INSTANCE = new FfiConverterTypeSocketConfig(); public override SocketConfig Read(BigEndianStream stream) { return new SocketConfig( @sendBufferSizeBytes: FfiConverterUInt32.INSTANCE.Read(stream), @receiveBufferSizeBytes: FfiConverterUInt32.INSTANCE.Read(stream) ); } public override int AllocationSize(SocketConfig value) { return 0 + FfiConverterUInt32.INSTANCE.AllocationSize(value.@sendBufferSizeBytes) + FfiConverterUInt32.INSTANCE.AllocationSize(value.@receiveBufferSizeBytes); } public override void Write(SocketConfig value, BigEndianStream stream) { FfiConverterUInt32.INSTANCE.Write(value.@sendBufferSizeBytes, stream); FfiConverterUInt32.INSTANCE.Write(value.@receiveBufferSizeBytes, stream); } } public record CaptureStopReason { public record Request ( PcapFileInfo @file ) : CaptureStopReason {} public record MaxSizeReached ( PcapFileInfo @file ) : CaptureStopReason {} public record Disconnected ( PcapFileInfo @file ) : CaptureStopReason {} public record AlreadyStopped: CaptureStopReason {} } class FfiConverterTypeCaptureStopReason : FfiConverterRustBuffer{ public static FfiConverterRustBuffer INSTANCE = new FfiConverterTypeCaptureStopReason(); public override CaptureStopReason Read(BigEndianStream stream) { var value = stream.ReadInt(); switch (value) { case 1: return new CaptureStopReason.Request( FfiConverterTypePcapFileInfo.INSTANCE.Read(stream) ); case 2: return new CaptureStopReason.MaxSizeReached( FfiConverterTypePcapFileInfo.INSTANCE.Read(stream) ); case 3: return new CaptureStopReason.Disconnected( FfiConverterTypePcapFileInfo.INSTANCE.Read(stream) ); case 4: return new CaptureStopReason.AlreadyStopped( ); default: throw new InternalException(String.Format("invalid enum value '{0}' in FfiConverterTypeCaptureStopReason.Read()", value)); } } public override int AllocationSize(CaptureStopReason value) { switch (value) { case CaptureStopReason.Request variant_value: return 4 + FfiConverterTypePcapFileInfo.INSTANCE.AllocationSize(variant_value.@file); case CaptureStopReason.MaxSizeReached variant_value: return 4 + FfiConverterTypePcapFileInfo.INSTANCE.AllocationSize(variant_value.@file); case CaptureStopReason.Disconnected variant_value: return 4 + FfiConverterTypePcapFileInfo.INSTANCE.AllocationSize(variant_value.@file); case CaptureStopReason.AlreadyStopped variant_value: return 4; default: throw new InternalException(String.Format("invalid enum value '{0}' in FfiConverterTypeCaptureStopReason.AllocationSize()", value)); } } public override void Write(CaptureStopReason value, BigEndianStream stream) { switch (value) { case CaptureStopReason.Request variant_value: stream.WriteInt(1); FfiConverterTypePcapFileInfo.INSTANCE.Write(variant_value.@file, stream); break; case CaptureStopReason.MaxSizeReached variant_value: stream.WriteInt(2); FfiConverterTypePcapFileInfo.INSTANCE.Write(variant_value.@file, stream); break; case CaptureStopReason.Disconnected variant_value: stream.WriteInt(3); FfiConverterTypePcapFileInfo.INSTANCE.Write(variant_value.@file, stream); break; case CaptureStopReason.AlreadyStopped variant_value: stream.WriteInt(4); break; default: throw new InternalException(String.Format("invalid enum value '{0}' in FfiConverterTypeCaptureStopReason.Write()", value)); } } } public enum ConnectivityEvent: int { Up, Down, /// /// Network switch occurred (wifi -> mobile, between different wifi etc.). /// This informs the library that it should reset VPN sockets. /// NetworkSwitch } class FfiConverterTypeConnectivityEvent: FfiConverterRustBuffer { public static FfiConverterTypeConnectivityEvent INSTANCE = new FfiConverterTypeConnectivityEvent(); public override ConnectivityEvent Read(BigEndianStream stream) { var value = stream.ReadInt() - 1; if (Enum.IsDefined(typeof(ConnectivityEvent), value)) { return (ConnectivityEvent)value; } else { throw new InternalException(String.Format("invalid enum value '{0}' in FfiConverterTypeConnectivityEvent.Read()", value)); } } public override int AllocationSize(ConnectivityEvent value) { return 4; } public override void Write(ConnectivityEvent value, BigEndianStream stream) { stream.WriteInt((int)value + 1); } } public record DisconnectReason { /// /// There was a problem establishing TUN interface. /// public record TunEstablishError ( string @message ) : DisconnectReason {} } class FfiConverterTypeDisconnectReason : FfiConverterRustBuffer{ public static FfiConverterRustBuffer INSTANCE = new FfiConverterTypeDisconnectReason(); public override DisconnectReason Read(BigEndianStream stream) { var value = stream.ReadInt(); switch (value) { case 1: return new DisconnectReason.TunEstablishError( FfiConverterString.INSTANCE.Read(stream) ); default: throw new InternalException(String.Format("invalid enum value '{0}' in FfiConverterTypeDisconnectReason.Read()", value)); } } public override int AllocationSize(DisconnectReason value) { switch (value) { case DisconnectReason.TunEstablishError variant_value: return 4 + FfiConverterString.INSTANCE.AllocationSize(variant_value.@message); default: throw new InternalException(String.Format("invalid enum value '{0}' in FfiConverterTypeDisconnectReason.AllocationSize()", value)); } } public override void Write(DisconnectReason value, BigEndianStream stream) { switch (value) { case DisconnectReason.TunEstablishError variant_value: stream.WriteInt(1); FfiConverterString.INSTANCE.Write(variant_value.@message, stream); break; default: throw new InternalException(String.Format("invalid enum value '{0}' in FfiConverterTypeDisconnectReason.Write()", value)); } } } /// /// Connection events emitted by the library and delivered via [crate::api::connection::EventCallback] /// public record Event { public record ConnectionStats ( ulong @receivedBytes, ulong @sentBytes, TimeSpan @timeSinceLastHandshake, float @estimatedLoss, TimeSpan @estimatedRoundTripTime ) : Event {} public record PacketCaptureStarted ( PcapFileInfo @info ) : Event {} public record PacketCaptureStopped ( CaptureStopReason @reason ) : Event {} } class FfiConverterTypeEvent : FfiConverterRustBuffer{ public static FfiConverterRustBuffer INSTANCE = new FfiConverterTypeEvent(); public override Event Read(BigEndianStream stream) { var value = stream.ReadInt(); switch (value) { case 1: return new Event.ConnectionStats( FfiConverterUInt64.INSTANCE.Read(stream), FfiConverterUInt64.INSTANCE.Read(stream), FfiConverterDuration.INSTANCE.Read(stream), FfiConverterFloat.INSTANCE.Read(stream), FfiConverterDuration.INSTANCE.Read(stream) ); case 2: return new Event.PacketCaptureStarted( FfiConverterTypePcapFileInfo.INSTANCE.Read(stream) ); case 3: return new Event.PacketCaptureStopped( FfiConverterTypeCaptureStopReason.INSTANCE.Read(stream) ); default: throw new InternalException(String.Format("invalid enum value '{0}' in FfiConverterTypeEvent.Read()", value)); } } public override int AllocationSize(Event value) { switch (value) { case Event.ConnectionStats variant_value: return 4 + FfiConverterUInt64.INSTANCE.AllocationSize(variant_value.@receivedBytes) + FfiConverterUInt64.INSTANCE.AllocationSize(variant_value.@sentBytes) + FfiConverterDuration.INSTANCE.AllocationSize(variant_value.@timeSinceLastHandshake) + FfiConverterFloat.INSTANCE.AllocationSize(variant_value.@estimatedLoss) + FfiConverterDuration.INSTANCE.AllocationSize(variant_value.@estimatedRoundTripTime); case Event.PacketCaptureStarted variant_value: return 4 + FfiConverterTypePcapFileInfo.INSTANCE.AllocationSize(variant_value.@info); case Event.PacketCaptureStopped variant_value: return 4 + FfiConverterTypeCaptureStopReason.INSTANCE.AllocationSize(variant_value.@reason); default: throw new InternalException(String.Format("invalid enum value '{0}' in FfiConverterTypeEvent.AllocationSize()", value)); } } public override void Write(Event value, BigEndianStream stream) { switch (value) { case Event.ConnectionStats variant_value: stream.WriteInt(1); FfiConverterUInt64.INSTANCE.Write(variant_value.@receivedBytes, stream); FfiConverterUInt64.INSTANCE.Write(variant_value.@sentBytes, stream); FfiConverterDuration.INSTANCE.Write(variant_value.@timeSinceLastHandshake, stream); FfiConverterFloat.INSTANCE.Write(variant_value.@estimatedLoss, stream); FfiConverterDuration.INSTANCE.Write(variant_value.@estimatedRoundTripTime, stream); break; case Event.PacketCaptureStarted variant_value: stream.WriteInt(2); FfiConverterTypePcapFileInfo.INSTANCE.Write(variant_value.@info, stream); break; case Event.PacketCaptureStopped variant_value: stream.WriteInt(3); FfiConverterTypeCaptureStopReason.INSTANCE.Write(variant_value.@reason, stream); break; default: throw new InternalException(String.Format("invalid enum value '{0}' in FfiConverterTypeEvent.Write()", value)); } } } public enum FileWriteMode: int { Append, Overwrite } class FfiConverterTypeFileWriteMode: FfiConverterRustBuffer { public static FfiConverterTypeFileWriteMode INSTANCE = new FfiConverterTypeFileWriteMode(); public override FileWriteMode Read(BigEndianStream stream) { var value = stream.ReadInt() - 1; if (Enum.IsDefined(typeof(FileWriteMode), value)) { return (FileWriteMode)value; } else { throw new InternalException(String.Format("invalid enum value '{0}' in FfiConverterTypeFileWriteMode.Read()", value)); } } public override int AllocationSize(FileWriteMode value) { return 4; } public override void Write(FileWriteMode value, BigEndianStream stream) { stream.WriteInt((int)value + 1); } } public enum LogLevel: int { Trace, Debug, Info, Warn, Error } class FfiConverterTypeLogLevel: FfiConverterRustBuffer { public static FfiConverterTypeLogLevel INSTANCE = new FfiConverterTypeLogLevel(); public override LogLevel Read(BigEndianStream stream) { var value = stream.ReadInt() - 1; if (Enum.IsDefined(typeof(LogLevel), value)) { return (LogLevel)value; } else { throw new InternalException(String.Format("invalid enum value '{0}' in FfiConverterTypeLogLevel.Read()", value)); } } public override int AllocationSize(LogLevel value) { return 4; } public override void Write(LogLevel value, BigEndianStream stream) { stream.WriteInt((int)value + 1); } } public record PcapFile { public record Path ( string @path, FileWriteMode @mode ) : PcapFile {} } class FfiConverterTypePcapFile : FfiConverterRustBuffer{ public static FfiConverterRustBuffer INSTANCE = new FfiConverterTypePcapFile(); public override PcapFile Read(BigEndianStream stream) { var value = stream.ReadInt(); switch (value) { case 1: return new PcapFile.Path( FfiConverterString.INSTANCE.Read(stream), FfiConverterTypeFileWriteMode.INSTANCE.Read(stream) ); default: throw new InternalException(String.Format("invalid enum value '{0}' in FfiConverterTypePcapFile.Read()", value)); } } public override int AllocationSize(PcapFile value) { switch (value) { case PcapFile.Path variant_value: return 4 + FfiConverterString.INSTANCE.AllocationSize(variant_value.@path) + FfiConverterTypeFileWriteMode.INSTANCE.AllocationSize(variant_value.@mode); default: throw new InternalException(String.Format("invalid enum value '{0}' in FfiConverterTypePcapFile.AllocationSize()", value)); } } public override void Write(PcapFile value, BigEndianStream stream) { switch (value) { case PcapFile.Path variant_value: stream.WriteInt(1); FfiConverterString.INSTANCE.Write(variant_value.@path, stream); FfiConverterTypeFileWriteMode.INSTANCE.Write(variant_value.@mode, stream); break; default: throw new InternalException(String.Format("invalid enum value '{0}' in FfiConverterTypePcapFile.Write()", value)); } } } public class ProTunFatalException: UniffiException { ProTunFatalException() : base() {} ProTunFatalException(String @Message) : base(@Message) {} // Each variant is a nested class public class NoLocalIp : ProTunFatalException { // Members public string @v1; // Constructor public NoLocalIp( string @v1) : base( "@v1" + "=" + @v1) { this.@v1 = @v1; } } public class HandleCreationFailed : ProTunFatalException { // Members public string @v1; // Constructor public HandleCreationFailed( string @v1) : base( "@v1" + "=" + @v1) { this.@v1 = @v1; } } public class WinsockStartFailed : ProTunFatalException { // Members public string @v1; // Constructor public WinsockStartFailed( string @v1) : base( "@v1" + "=" + @v1) { this.@v1 = @v1; } } public class WintunLibraryLoadingFailed : ProTunFatalException { // Members public string @v1; // Constructor public WintunLibraryLoadingFailed( string @v1) : base( "@v1" + "=" + @v1) { this.@v1 = @v1; } } public class WintunInterfaceCreationFailed : ProTunFatalException { // Members public string @v1; // Constructor public WintunInterfaceCreationFailed( string @v1) : base( "@v1" + "=" + @v1) { this.@v1 = @v1; } } public class WintunAdapterIndexFetchFailed : ProTunFatalException { // Members public string @v1; // Constructor public WintunAdapterIndexFetchFailed( string @v1) : base( "@v1" + "=" + @v1) { this.@v1 = @v1; } } public class WintunSessionCreationFailed : ProTunFatalException { // Members public string @v1; // Constructor public WintunSessionCreationFailed( string @v1) : base( "@v1" + "=" + @v1) { this.@v1 = @v1; } } public class WintunIpAddressSetupFailed : ProTunFatalException { // Members public string @v1; // Constructor public WintunIpAddressSetupFailed( string @v1) : base( "@v1" + "=" + @v1) { this.@v1 = @v1; } } public class WintunSessionHandleCreationFailed : ProTunFatalException { // Members public string @v1; // Constructor public WintunSessionHandleCreationFailed( string @v1) : base( "@v1" + "=" + @v1) { this.@v1 = @v1; } } } class FfiConverterTypeProTunFatalError : FfiConverterRustBuffer, CallStatusErrorHandler { public static FfiConverterTypeProTunFatalError INSTANCE = new FfiConverterTypeProTunFatalError(); public override ProTunFatalException Read(BigEndianStream stream) { var value = stream.ReadInt(); switch (value) { case 1: return new ProTunFatalException.NoLocalIp( FfiConverterString.INSTANCE.Read(stream)); case 2: return new ProTunFatalException.HandleCreationFailed( FfiConverterString.INSTANCE.Read(stream)); case 3: return new ProTunFatalException.WinsockStartFailed( FfiConverterString.INSTANCE.Read(stream)); case 4: return new ProTunFatalException.WintunLibraryLoadingFailed( FfiConverterString.INSTANCE.Read(stream)); case 5: return new ProTunFatalException.WintunInterfaceCreationFailed( FfiConverterString.INSTANCE.Read(stream)); case 6: return new ProTunFatalException.WintunAdapterIndexFetchFailed( FfiConverterString.INSTANCE.Read(stream)); case 7: return new ProTunFatalException.WintunSessionCreationFailed( FfiConverterString.INSTANCE.Read(stream)); case 8: return new ProTunFatalException.WintunIpAddressSetupFailed( FfiConverterString.INSTANCE.Read(stream)); case 9: return new ProTunFatalException.WintunSessionHandleCreationFailed( FfiConverterString.INSTANCE.Read(stream)); default: throw new InternalException(String.Format("invalid error value '{0}' in FfiConverterTypeProTunFatalError.Read()", value)); } } public override int AllocationSize(ProTunFatalException value) { switch (value) { case ProTunFatalException.NoLocalIp variant_value: return 4 + FfiConverterString.INSTANCE.AllocationSize(variant_value.@v1); case ProTunFatalException.HandleCreationFailed variant_value: return 4 + FfiConverterString.INSTANCE.AllocationSize(variant_value.@v1); case ProTunFatalException.WinsockStartFailed variant_value: return 4 + FfiConverterString.INSTANCE.AllocationSize(variant_value.@v1); case ProTunFatalException.WintunLibraryLoadingFailed variant_value: return 4 + FfiConverterString.INSTANCE.AllocationSize(variant_value.@v1); case ProTunFatalException.WintunInterfaceCreationFailed variant_value: return 4 + FfiConverterString.INSTANCE.AllocationSize(variant_value.@v1); case ProTunFatalException.WintunAdapterIndexFetchFailed variant_value: return 4 + FfiConverterString.INSTANCE.AllocationSize(variant_value.@v1); case ProTunFatalException.WintunSessionCreationFailed variant_value: return 4 + FfiConverterString.INSTANCE.AllocationSize(variant_value.@v1); case ProTunFatalException.WintunIpAddressSetupFailed variant_value: return 4 + FfiConverterString.INSTANCE.AllocationSize(variant_value.@v1); case ProTunFatalException.WintunSessionHandleCreationFailed variant_value: return 4 + FfiConverterString.INSTANCE.AllocationSize(variant_value.@v1); default: throw new InternalException(String.Format("invalid error value '{0}' in FfiConverterTypeProTunFatalError.AllocationSize()", value)); } } public override void Write(ProTunFatalException value, BigEndianStream stream) { switch (value) { case ProTunFatalException.NoLocalIp variant_value: stream.WriteInt(1); FfiConverterString.INSTANCE.Write(variant_value.@v1, stream); break; case ProTunFatalException.HandleCreationFailed variant_value: stream.WriteInt(2); FfiConverterString.INSTANCE.Write(variant_value.@v1, stream); break; case ProTunFatalException.WinsockStartFailed variant_value: stream.WriteInt(3); FfiConverterString.INSTANCE.Write(variant_value.@v1, stream); break; case ProTunFatalException.WintunLibraryLoadingFailed variant_value: stream.WriteInt(4); FfiConverterString.INSTANCE.Write(variant_value.@v1, stream); break; case ProTunFatalException.WintunInterfaceCreationFailed variant_value: stream.WriteInt(5); FfiConverterString.INSTANCE.Write(variant_value.@v1, stream); break; case ProTunFatalException.WintunAdapterIndexFetchFailed variant_value: stream.WriteInt(6); FfiConverterString.INSTANCE.Write(variant_value.@v1, stream); break; case ProTunFatalException.WintunSessionCreationFailed variant_value: stream.WriteInt(7); FfiConverterString.INSTANCE.Write(variant_value.@v1, stream); break; case ProTunFatalException.WintunIpAddressSetupFailed variant_value: stream.WriteInt(8); FfiConverterString.INSTANCE.Write(variant_value.@v1, stream); break; case ProTunFatalException.WintunSessionHandleCreationFailed variant_value: stream.WriteInt(9); FfiConverterString.INSTANCE.Write(variant_value.@v1, stream); break; default: throw new InternalException(String.Format("invalid error value '{0}' in FfiConverterTypeProTunFatalError.Write()", value)); } } } public enum Protocol: int { WireguardUdp, WireguardTcp, Stealth } class FfiConverterTypeProtocol: FfiConverterRustBuffer { public static FfiConverterTypeProtocol INSTANCE = new FfiConverterTypeProtocol(); public override Protocol Read(BigEndianStream stream) { var value = stream.ReadInt() - 1; if (Enum.IsDefined(typeof(Protocol), value)) { return (Protocol)value; } else { throw new InternalException(String.Format("invalid enum value '{0}' in FfiConverterTypeProtocol.Read()", value)); } } public override int AllocationSize(Protocol value) { return 4; } public override void Write(Protocol value, BigEndianStream stream) { stream.WriteInt((int)value + 1); } } /// /// State of the VPN connection. /// public record State { /// /// Disconnected. [error] will be set if disconnection happened due to an error. /// public record Disconnected ( DisconnectReason? @error ) : State {} /// /// Library is attempting VPN connection to one or more candidate peers. /// public record Connecting ( PeerConnectionInfo[] @peers ) : State {} /// /// Library connection attempt requires app, user or system action to proceed. /// public record WaitingForAction ( WaitReason @reason ) : State {} /// /// Connection to [peer] is established. /// public record Connected ( PeerConnectionInfo @peer ) : State {} } class FfiConverterTypeState : FfiConverterRustBuffer{ public static FfiConverterRustBuffer INSTANCE = new FfiConverterTypeState(); public override State Read(BigEndianStream stream) { var value = stream.ReadInt(); switch (value) { case 1: return new State.Disconnected( FfiConverterOptionalTypeDisconnectReason.INSTANCE.Read(stream) ); case 2: return new State.Connecting( FfiConverterSequenceTypePeerConnectionInfo.INSTANCE.Read(stream) ); case 3: return new State.WaitingForAction( FfiConverterTypeWaitReason.INSTANCE.Read(stream) ); case 4: return new State.Connected( FfiConverterTypePeerConnectionInfo.INSTANCE.Read(stream) ); default: throw new InternalException(String.Format("invalid enum value '{0}' in FfiConverterTypeState.Read()", value)); } } public override int AllocationSize(State value) { switch (value) { case State.Disconnected variant_value: return 4 + FfiConverterOptionalTypeDisconnectReason.INSTANCE.AllocationSize(variant_value.@error); case State.Connecting variant_value: return 4 + FfiConverterSequenceTypePeerConnectionInfo.INSTANCE.AllocationSize(variant_value.@peers); case State.WaitingForAction variant_value: return 4 + FfiConverterTypeWaitReason.INSTANCE.AllocationSize(variant_value.@reason); case State.Connected variant_value: return 4 + FfiConverterTypePeerConnectionInfo.INSTANCE.AllocationSize(variant_value.@peer); default: throw new InternalException(String.Format("invalid enum value '{0}' in FfiConverterTypeState.AllocationSize()", value)); } } public override void Write(State value, BigEndianStream stream) { switch (value) { case State.Disconnected variant_value: stream.WriteInt(1); FfiConverterOptionalTypeDisconnectReason.INSTANCE.Write(variant_value.@error, stream); break; case State.Connecting variant_value: stream.WriteInt(2); FfiConverterSequenceTypePeerConnectionInfo.INSTANCE.Write(variant_value.@peers, stream); break; case State.WaitingForAction variant_value: stream.WriteInt(3); FfiConverterTypeWaitReason.INSTANCE.Write(variant_value.@reason, stream); break; case State.Connected variant_value: stream.WriteInt(4); FfiConverterTypePeerConnectionInfo.INSTANCE.Write(variant_value.@peer, stream); break; default: throw new InternalException(String.Format("invalid enum value '{0}' in FfiConverterTypeState.Write()", value)); } } } public record WaitReason { /// /// Device currently has no network (airplane mode, no signal, etc.) /// public record WaitingForNetwork: WaitReason {} /// /// There is I/O problem with TUN interface. Calling code might need to wait, recreate TUN or /// disconnect (when it was caused by connection by another VPN app). /// public record TunIoError ( string @message ) : WaitReason {} } class FfiConverterTypeWaitReason : FfiConverterRustBuffer{ public static FfiConverterRustBuffer INSTANCE = new FfiConverterTypeWaitReason(); public override WaitReason Read(BigEndianStream stream) { var value = stream.ReadInt(); switch (value) { case 1: return new WaitReason.WaitingForNetwork( ); case 2: return new WaitReason.TunIoError( FfiConverterString.INSTANCE.Read(stream) ); default: throw new InternalException(String.Format("invalid enum value '{0}' in FfiConverterTypeWaitReason.Read()", value)); } } public override int AllocationSize(WaitReason value) { switch (value) { case WaitReason.WaitingForNetwork variant_value: return 4; case WaitReason.TunIoError variant_value: return 4 + FfiConverterString.INSTANCE.AllocationSize(variant_value.@message); default: throw new InternalException(String.Format("invalid enum value '{0}' in FfiConverterTypeWaitReason.AllocationSize()", value)); } } public override void Write(WaitReason value, BigEndianStream stream) { switch (value) { case WaitReason.WaitingForNetwork variant_value: stream.WriteInt(1); break; case WaitReason.TunIoError variant_value: stream.WriteInt(2); FfiConverterString.INSTANCE.Write(variant_value.@message, stream); break; default: throw new InternalException(String.Format("invalid enum value '{0}' in FfiConverterTypeWaitReason.Write()", value)); } } } public interface ClientLogger { void Log(LogLevel @level, string @message); } class UniffiCallbackInterfaceClientLogger { static void Log(ulong @uniffiHandle,RustBuffer @level,RustBuffer @message,IntPtr @uniffiOutReturn,ref UniffiRustCallStatus _uniffi_out_err) { var handle = @uniffiHandle; if (FfiConverterTypeClientLogger.INSTANCE.handleMap.TryGet(handle, out var uniffiObject)) { uniffiObject.Log( FfiConverterTypeLogLevel.INSTANCE.Lift(@level), FfiConverterString.INSTANCE.Lift(@message)); } else { throw new InternalException($"No callback in handlemap '{handle}'"); } } static void UniffiFree(ulong @handle) { FfiConverterTypeClientLogger.INSTANCE.handleMap.Remove(@handle); } static _UniFFILib.UniffiCallbackInterfaceClientLoggerMethod0 _m0 = new _UniFFILib.UniffiCallbackInterfaceClientLoggerMethod0(Log); static _UniFFILib.UniffiCallbackInterfaceFree _callback_interface_free = new _UniFFILib.UniffiCallbackInterfaceFree(UniffiFree); public static _UniFFILib.UniffiVTableCallbackInterfaceClientLogger _vtable = new _UniFFILib.UniffiVTableCallbackInterfaceClientLogger { @log = Marshal.GetFunctionPointerForDelegate(_m0), @uniffiFree = Marshal.GetFunctionPointerForDelegate(_callback_interface_free) }; public static void Register() { _UniFFILib.uniffi_protun_fn_init_callback_vtable_clientlogger(ref UniffiCallbackInterfaceClientLogger._vtable); } } class ConcurrentHandleMap where T: notnull { Dictionary map = new Dictionary(); Object lock_ = new Object(); ulong currentHandle = 0; public ulong Insert(T obj) { lock (lock_) { currentHandle += 1; map[currentHandle] = obj; return currentHandle; } } public bool TryGet(ulong handle, out T result) { lock (lock_) { #pragma warning disable 8601 // Possible null reference assignment return map.TryGetValue(handle, out result); #pragma warning restore 8601 } } public T Get(ulong handle) { if (TryGet(handle, out var result)) { return result; } else { throw new InternalException("ConcurrentHandleMap: Invalid handle"); } } public bool Remove(ulong handle) { return Remove(handle, out T result); } public bool Remove(ulong handle, out T result) { lock (lock_) { // Possible null reference assignment #pragma warning disable 8601 if (map.TryGetValue(handle, out result)) { #pragma warning restore 8601 map.Remove(handle); return true; } else { return false; } } } } static class UniffiCallbackResponseStatus { public static sbyte SUCCESS = 0; public static sbyte ERROR = 1; public static sbyte UNEXPECTED_ERROR = 2; } // The ffiConverter which transforms the Callbacks in to Handles to pass to Rust. class FfiConverterTypeClientLogger: FfiConverter { public static FfiConverterTypeClientLogger INSTANCE = new FfiConverterTypeClientLogger(); public ConcurrentHandleMap handleMap = new ConcurrentHandleMap(); public override ulong Lower(ClientLogger value) { return handleMap.Insert(value); } public override ClientLogger Lift(ulong value) { if (handleMap.TryGet(value, out var uniffiCallback)) { return uniffiCallback; } else { throw new InternalException($"No callback in handlemap '{value}'"); } } public override ClientLogger Read(BigEndianStream stream) { return Lift(stream.ReadULong()); } public override int AllocationSize(ClientLogger value) { return 8; } public override void Write(ClientLogger value, BigEndianStream stream) { stream.WriteULong(Lower(value)); } } /// /// Callback interface for receiving events. Avoid doing heavy work in the callback to avoid /// blocking the connection thread (delegate to another thread if needed). /// public interface EventCallback { void OnEvent(Event @event); } class UniffiCallbackInterfaceEventCallback { static void OnEvent(ulong @uniffiHandle,RustBuffer @event,IntPtr @uniffiOutReturn,ref UniffiRustCallStatus _uniffi_out_err) { var handle = @uniffiHandle; if (FfiConverterTypeEventCallback.INSTANCE.handleMap.TryGet(handle, out var uniffiObject)) { uniffiObject.OnEvent( FfiConverterTypeEvent.INSTANCE.Lift(@event)); } else { throw new InternalException($"No callback in handlemap '{handle}'"); } } static void UniffiFree(ulong @handle) { FfiConverterTypeEventCallback.INSTANCE.handleMap.Remove(@handle); } static _UniFFILib.UniffiCallbackInterfaceEventCallbackMethod0 _m0 = new _UniFFILib.UniffiCallbackInterfaceEventCallbackMethod0(OnEvent); static _UniFFILib.UniffiCallbackInterfaceFree _callback_interface_free = new _UniFFILib.UniffiCallbackInterfaceFree(UniffiFree); public static _UniFFILib.UniffiVTableCallbackInterfaceEventCallback _vtable = new _UniFFILib.UniffiVTableCallbackInterfaceEventCallback { @onEvent = Marshal.GetFunctionPointerForDelegate(_m0), @uniffiFree = Marshal.GetFunctionPointerForDelegate(_callback_interface_free) }; public static void Register() { _UniFFILib.uniffi_protun_fn_init_callback_vtable_eventcallback(ref UniffiCallbackInterfaceEventCallback._vtable); } } // The ffiConverter which transforms the Callbacks in to Handles to pass to Rust. class FfiConverterTypeEventCallback: FfiConverter { public static FfiConverterTypeEventCallback INSTANCE = new FfiConverterTypeEventCallback(); public ConcurrentHandleMap handleMap = new ConcurrentHandleMap(); public override ulong Lower(EventCallback value) { return handleMap.Insert(value); } public override EventCallback Lift(ulong value) { if (handleMap.TryGet(value, out var uniffiCallback)) { return uniffiCallback; } else { throw new InternalException($"No callback in handlemap '{value}'"); } } public override EventCallback Read(BigEndianStream stream) { return Lift(stream.ReadULong()); } public override int AllocationSize(EventCallback value) { return 8; } public override void Write(EventCallback value, BigEndianStream stream) { stream.WriteULong(Lower(value)); } } /// /// Callback interface for receiving connection state changes. Avoid doing heavy work in the /// callback to avoid blocking the connection thread. /// public interface StateChangedCallback { void OnStateChanged(State @state); } class UniffiCallbackInterfaceStateChangedCallback { static void OnStateChanged(ulong @uniffiHandle,RustBuffer @state,IntPtr @uniffiOutReturn,ref UniffiRustCallStatus _uniffi_out_err) { var handle = @uniffiHandle; if (FfiConverterTypeStateChangedCallback.INSTANCE.handleMap.TryGet(handle, out var uniffiObject)) { uniffiObject.OnStateChanged( FfiConverterTypeState.INSTANCE.Lift(@state)); } else { throw new InternalException($"No callback in handlemap '{handle}'"); } } static void UniffiFree(ulong @handle) { FfiConverterTypeStateChangedCallback.INSTANCE.handleMap.Remove(@handle); } static _UniFFILib.UniffiCallbackInterfaceStateChangedCallbackMethod0 _m0 = new _UniFFILib.UniffiCallbackInterfaceStateChangedCallbackMethod0(OnStateChanged); static _UniFFILib.UniffiCallbackInterfaceFree _callback_interface_free = new _UniFFILib.UniffiCallbackInterfaceFree(UniffiFree); public static _UniFFILib.UniffiVTableCallbackInterfaceStateChangedCallback _vtable = new _UniFFILib.UniffiVTableCallbackInterfaceStateChangedCallback { @onStateChanged = Marshal.GetFunctionPointerForDelegate(_m0), @uniffiFree = Marshal.GetFunctionPointerForDelegate(_callback_interface_free) }; public static void Register() { _UniFFILib.uniffi_protun_fn_init_callback_vtable_statechangedcallback(ref UniffiCallbackInterfaceStateChangedCallback._vtable); } } // The ffiConverter which transforms the Callbacks in to Handles to pass to Rust. class FfiConverterTypeStateChangedCallback: FfiConverter { public static FfiConverterTypeStateChangedCallback INSTANCE = new FfiConverterTypeStateChangedCallback(); public ConcurrentHandleMap handleMap = new ConcurrentHandleMap(); public override ulong Lower(StateChangedCallback value) { return handleMap.Insert(value); } public override StateChangedCallback Lift(ulong value) { if (handleMap.TryGet(value, out var uniffiCallback)) { return uniffiCallback; } else { throw new InternalException($"No callback in handlemap '{value}'"); } } public override StateChangedCallback Read(BigEndianStream stream) { return Lift(stream.ReadULong()); } public override int AllocationSize(StateChangedCallback value) { return 8; } public override void Write(StateChangedCallback value, BigEndianStream stream) { stream.WriteULong(Lower(value)); } } class FfiConverterOptionalUInt64: FfiConverterRustBuffer { public static FfiConverterOptionalUInt64 INSTANCE = new FfiConverterOptionalUInt64(); public override ulong? Read(BigEndianStream stream) { if (stream.ReadByte() == 0) { return null; } return FfiConverterUInt64.INSTANCE.Read(stream); } public override int AllocationSize(ulong? value) { if (value == null) { return 1; } else { return 1 + FfiConverterUInt64.INSTANCE.AllocationSize((ulong)value); } } public override void Write(ulong? value, BigEndianStream stream) { if (value == null) { stream.WriteByte(0); } else { stream.WriteByte(1); FfiConverterUInt64.INSTANCE.Write((ulong)value, stream); } } } class FfiConverterOptionalTypePcapFileInfo: FfiConverterRustBuffer { public static FfiConverterOptionalTypePcapFileInfo INSTANCE = new FfiConverterOptionalTypePcapFileInfo(); public override PcapFileInfo? Read(BigEndianStream stream) { if (stream.ReadByte() == 0) { return null; } return FfiConverterTypePcapFileInfo.INSTANCE.Read(stream); } public override int AllocationSize(PcapFileInfo? value) { if (value == null) { return 1; } else { return 1 + FfiConverterTypePcapFileInfo.INSTANCE.AllocationSize((PcapFileInfo)value); } } public override void Write(PcapFileInfo? value, BigEndianStream stream) { if (value == null) { stream.WriteByte(0); } else { stream.WriteByte(1); FfiConverterTypePcapFileInfo.INSTANCE.Write((PcapFileInfo)value, stream); } } } class FfiConverterOptionalTypeDisconnectReason: FfiConverterRustBuffer { public static FfiConverterOptionalTypeDisconnectReason INSTANCE = new FfiConverterOptionalTypeDisconnectReason(); public override DisconnectReason? Read(BigEndianStream stream) { if (stream.ReadByte() == 0) { return null; } return FfiConverterTypeDisconnectReason.INSTANCE.Read(stream); } public override int AllocationSize(DisconnectReason? value) { if (value == null) { return 1; } else { return 1 + FfiConverterTypeDisconnectReason.INSTANCE.AllocationSize((DisconnectReason)value); } } public override void Write(DisconnectReason? value, BigEndianStream stream) { if (value == null) { stream.WriteByte(0); } else { stream.WriteByte(1); FfiConverterTypeDisconnectReason.INSTANCE.Write((DisconnectReason)value, stream); } } } class FfiConverterSequenceUInt16: FfiConverterRustBuffer { public static FfiConverterSequenceUInt16 INSTANCE = new FfiConverterSequenceUInt16(); public override ushort[] Read(BigEndianStream stream) { var length = stream.ReadInt(); if (length == 0) { return []; } var result = new ushort[(length)]; var readFn = FfiConverterUInt16.INSTANCE.Read; for (int i = 0; i < length; i++) { result[i] = readFn(stream); } return result; } public override int AllocationSize(ushort[] value) { var sizeForLength = 4; // details/1-empty-list-as-default-method-parameter.md if (value == null) { return sizeForLength; } var allocationSizeFn = FfiConverterUInt16.INSTANCE.AllocationSize; var sizeForItems = value.Sum(item => allocationSizeFn(item)); return sizeForLength + sizeForItems; } public override void Write(ushort[] value, BigEndianStream stream) { // details/1-empty-list-as-default-method-parameter.md if (value == null) { stream.WriteInt(0); return; } stream.WriteInt(value.Length); var writerFn = FfiConverterUInt16.INSTANCE.Write; value.ForEach(item => writerFn(item, stream)); } } class FfiConverterSequenceTypePeerConnectionInfo: FfiConverterRustBuffer { public static FfiConverterSequenceTypePeerConnectionInfo INSTANCE = new FfiConverterSequenceTypePeerConnectionInfo(); public override PeerConnectionInfo[] Read(BigEndianStream stream) { var length = stream.ReadInt(); if (length == 0) { return []; } var result = new PeerConnectionInfo[(length)]; var readFn = FfiConverterTypePeerConnectionInfo.INSTANCE.Read; for (int i = 0; i < length; i++) { result[i] = readFn(stream); } return result; } public override int AllocationSize(PeerConnectionInfo[] value) { var sizeForLength = 4; // details/1-empty-list-as-default-method-parameter.md if (value == null) { return sizeForLength; } var allocationSizeFn = FfiConverterTypePeerConnectionInfo.INSTANCE.AllocationSize; var sizeForItems = value.Sum(item => allocationSizeFn(item)); return sizeForLength + sizeForItems; } public override void Write(PeerConnectionInfo[] value, BigEndianStream stream) { // details/1-empty-list-as-default-method-parameter.md if (value == null) { stream.WriteInt(0); return; } stream.WriteInt(value.Length); var writerFn = FfiConverterTypePeerConnectionInfo.INSTANCE.Write; value.ForEach(item => writerFn(item, stream)); } } class FfiConverterSequenceTypePeerInfo: FfiConverterRustBuffer { public static FfiConverterSequenceTypePeerInfo INSTANCE = new FfiConverterSequenceTypePeerInfo(); public override PeerInfo[] Read(BigEndianStream stream) { var length = stream.ReadInt(); if (length == 0) { return []; } var result = new PeerInfo[(length)]; var readFn = FfiConverterTypePeerInfo.INSTANCE.Read; for (int i = 0; i < length; i++) { result[i] = readFn(stream); } return result; } public override int AllocationSize(PeerInfo[] value) { var sizeForLength = 4; // details/1-empty-list-as-default-method-parameter.md if (value == null) { return sizeForLength; } var allocationSizeFn = FfiConverterTypePeerInfo.INSTANCE.AllocationSize; var sizeForItems = value.Sum(item => allocationSizeFn(item)); return sizeForLength + sizeForItems; } public override void Write(PeerInfo[] value, BigEndianStream stream) { // details/1-empty-list-as-default-method-parameter.md if (value == null) { stream.WriteInt(0); return; } stream.WriteInt(value.Length); var writerFn = FfiConverterTypePeerInfo.INSTANCE.Write; value.ForEach(item => writerFn(item, stream)); } } class FfiConverterSequenceTypeIpAddress: FfiConverterRustBuffer { public static FfiConverterSequenceTypeIpAddress INSTANCE = new FfiConverterSequenceTypeIpAddress(); public override IpAddress[] Read(BigEndianStream stream) { var length = stream.ReadInt(); if (length == 0) { return []; } var result = new IpAddress[(length)]; var readFn = FfiConverterTypeIpAddress.INSTANCE.Read; for (int i = 0; i < length; i++) { result[i] = readFn(stream); } return result; } public override int AllocationSize(IpAddress[] value) { var sizeForLength = 4; // details/1-empty-list-as-default-method-parameter.md if (value == null) { return sizeForLength; } var allocationSizeFn = FfiConverterTypeIpAddress.INSTANCE.AllocationSize; var sizeForItems = value.Sum(item => allocationSizeFn(item)); return sizeForLength + sizeForItems; } public override void Write(IpAddress[] value, BigEndianStream stream) { // details/1-empty-list-as-default-method-parameter.md if (value == null) { stream.WriteInt(0); return; } stream.WriteInt(value.Length); var writerFn = FfiConverterTypeIpAddress.INSTANCE.Write; value.ForEach(item => writerFn(item, stream)); } } /** * Typealias from the type name used in the UDL file to the builtin type. This * is needed because the UDL type name is used in function/method signatures. * It's also what we have an external type that references a custom type. */ /** * Typealias from the type name used in the UDL file to the builtin type. This * is needed because the UDL type name is used in function/method signatures. * It's also what we have an external type that references a custom type. */ /** * Typealias from the type name used in the UDL file to the builtin type. This * is needed because the UDL type name is used in function/method signatures. * It's also what we have an external type that references a custom type. */ #pragma warning restore 8625 public static class ProTunApi { /// /// Initialize the logger and backtrace. It's thread safe and can be called multiple times, but /// only the first call will succeed, all subsequent calls will be ignored. /// [level] min log level to be logged. /// [logger] callback for the client to receive log messages. /// public static void InitLogger(LogLevel @level, ClientLogger @logger) { _UniffiHelpers.RustCall( (ref UniffiRustCallStatus _status) => _UniFFILib.uniffi_protun_fn_func_init_logger(FfiConverterTypeLogLevel.INSTANCE.Lower(@level), FfiConverterTypeClientLogger.INSTANCE.Lower(@logger), ref _status) ); } }