Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Network] Add support for Xcode 15. #19418

Merged
merged 25 commits into from
Jan 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
f09e7a3
[Network] Add support for Xcode 15.
mandel-macaque Nov 7, 2023
157128d
Auto-format source code
Nov 9, 2023
6164cdd
Update src/Network/NWProxyConfig.cs
mandel-macaque Nov 13, 2023
6c33837
Apply suggestions from code review
mandel-macaque Nov 16, 2023
30ffe2f
Merge branch 'main' into net8.0-xcode15-network
mandel-macaque Nov 16, 2023
08a5c63
Fix some errors from the reviews.
mandel-macaque Nov 17, 2023
b20eb88
[Network] Add support for Xcode 15.
mandel-macaque Nov 7, 2023
b71441e
Auto-format source code
Nov 9, 2023
8cff4eb
Update src/Network/NWProxyConfig.cs
mandel-macaque Nov 13, 2023
2cea843
Apply suggestions from code review
mandel-macaque Nov 16, 2023
7bf8f7c
Fix some errors from the reviews.
mandel-macaque Nov 17, 2023
7e5e2e5
Merge branch 'net8.0-xcode15-network' of github.com:mandel-macaque/xa…
mandel-macaque Dec 12, 2023
06c5f17
Adress reviews.
mandel-macaque Dec 12, 2023
17683b4
Auto-format source code
Dec 12, 2023
f9ee129
Fix enumerators bindings and tests.
mandel-macaque Dec 18, 2023
f6aadec
Merge branch 'main' into net8.0-xcode15-network
mandel-macaque Dec 18, 2023
256fc51
Auto-format source code
Dec 18, 2023
1e6fa48
Apply suggestions from code review
mandel-macaque Dec 19, 2023
1dc492b
Merge branch 'main' into net8.0-xcode15-network
mandel-macaque Dec 20, 2023
b891386
Merge branch 'main' into net8.0-xcode15-network
mandel-macaque Jan 2, 2024
e4c279e
Expose the Proxy config in the NSUrlSessionConfiguration.
mandel-macaque Jan 2, 2024
0ea5148
Merge branch 'main' into net8.0-xcode15-network
rolfbjarne Jan 3, 2024
305d38a
Auto-format source code
Jan 3, 2024
a6c921b
Better implementation of the property.
mandel-macaque Jan 3, 2024
fbd9e27
Auto-format source code
Jan 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions src/Foundation/NSUrlSessionConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// Manuel de la Pena <[email protected]>
using System;
using ObjCRuntime;
using Network;

using Foundation;

Expand Down Expand Up @@ -64,5 +65,22 @@ public static NSUrlSessionConfiguration CreateBackgroundSessionConfiguration (st
return config;
}

#if NET
[SupportedOSPlatform ("ios17.0")]
[SupportedOSPlatform ("macos14.0")]
[SupportedOSPlatform ("maccatalyst17.0")]
[SupportedOSPlatform ("tvos17.0")]
#else
[TV (17, 0), Watch (10, 0), iOS (17, 0), Mac (14, 0), MacCatalyst (17, 0)]
#endif
public NWProxyConfig [] ProxyConfigurations {
get => NSArray.ArrayFromHandleFunc (_ProxyConfigurations, handle => new NWProxyConfig (handle, owns: false));
set {
var arr = NSArray.FromNSObjects (value);
_ProxyConfigurations = arr.Handle;
GC.KeepAlive (arr);
}
}

}
}
53 changes: 53 additions & 0 deletions src/Network/NWPrivacyContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Foundation;
using OS_nw_privacy_context = System.IntPtr;
using OS_nw_resolver_config = System.IntPtr;
using OS_nw_proxy_config = System.IntPtr;

#if !NET
using NativeHandle = System.IntPtr;
Expand Down Expand Up @@ -66,5 +67,57 @@ public void DisableLogging ()

public void RequireEncryptedNameResolution (bool requireEncryptedNameResolution, NWResolverConfig? fallbackResolverConfig)
=> nw_privacy_context_require_encrypted_name_resolution (GetCheckedHandle (), requireEncryptedNameResolution, fallbackResolverConfig.GetHandle ());

#if NET
[SupportedOSPlatform ("tvos17.0")]
[SupportedOSPlatform ("macos14.0")]
[SupportedOSPlatform ("ios17.0")]
[SupportedOSPlatform ("maccatalyst17.0")]
#else
[Watch (10, 0), TV (17, 0), Mac (14, 0), iOS (17, 0), MacCatalyst (17, 0)]
#endif
[DllImport (Constants.NetworkLibrary)]
static extern void nw_privacy_context_add_proxy (OS_nw_privacy_context privacy_context, OS_nw_proxy_config proxy_config);

#if NET
[SupportedOSPlatform ("tvos17.0")]
[SupportedOSPlatform ("macos14.0")]
[SupportedOSPlatform ("ios17.0")]
[SupportedOSPlatform ("maccatalyst17.0")]
#else
[Watch (10, 0), TV (17, 0), Mac (14, 0), iOS (17, 0), MacCatalyst (17, 0)]
#endif
public void AddProxy (NWProxyConfig proxyConfig)
rolfbjarne marked this conversation as resolved.
Show resolved Hide resolved
{
if (proxyConfig is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (proxyConfig));
nw_privacy_context_add_proxy (GetCheckedHandle (), proxyConfig.GetCheckedHandle ());
}

#if NET
[SupportedOSPlatform ("tvos17.0")]
[SupportedOSPlatform ("macos14.0")]
[SupportedOSPlatform ("ios17.0")]
[SupportedOSPlatform ("maccatalyst17.0")]
#else
[Watch (10, 0), TV (17, 0), Mac (14, 0), iOS (17, 0), MacCatalyst (17, 0)]
#endif
[DllImport (Constants.NetworkLibrary)]
static extern void nw_privacy_context_clear_proxies (OS_nw_privacy_context privacy_context);

#if NET
[SupportedOSPlatform ("tvos17.0")]
[SupportedOSPlatform ("macos14.0")]
[SupportedOSPlatform ("ios17.0")]
[SupportedOSPlatform ("maccatalyst17.0")]
#else
[Watch (10, 0), TV (17, 0), Mac (14, 0), iOS (17, 0), MacCatalyst (17, 0)]
#endif
public void ClearProxies ()
{
nw_privacy_context_clear_proxies (GetCheckedHandle ());
}

}

}
237 changes: 237 additions & 0 deletions src/Network/NWProxyConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
#nullable enable

using System;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using ObjCRuntime;
using Foundation;
using CoreFoundation;

using OS_nw_proxy_config = System.IntPtr;
using OS_nw_relay_hop = System.IntPtr;
using OS_nw_endpoint = System.IntPtr;
using OS_nw_protocol_options = System.IntPtr;

#if !NET
using NativeHandle = System.IntPtr;
#endif

namespace Network {

#if NET
[SupportedOSPlatform ("tvos17.0")]
[SupportedOSPlatform ("macos14.0")]
[SupportedOSPlatform ("ios17.0")]
[SupportedOSPlatform ("maccatalyst17.0")]
#else
[Watch (10, 0), TV (17, 0), Mac (14, 0), iOS (17, 0), MacCatalyst (17, 0)]
#endif
public class NWProxyConfig : NativeObject {
[Preserve (Conditional = true)]
#if NET
internal NWProxyConfig (NativeHandle handle, bool owns) : base (handle, owns) {}
#else
public NWProxyConfig (NativeHandle handle, bool owns) : base (handle, owns) { }
#endif

[DllImport (Constants.NetworkLibrary)]
static extern OS_nw_proxy_config nw_proxy_config_create_relay (OS_nw_relay_hop first_hop, /* [NullAllowed] */ OS_nw_relay_hop second_hop);

public static NWProxyConfig? CreateRelay (NWRelayHop firstHop, NWRelayHop? secondHop)
{
if (firstHop is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (firstHop));
var handle = nw_proxy_config_create_relay (firstHop.GetCheckedHandle (), secondHop.GetHandle ());
if (handle == NativeHandle.Zero)
return default;
return new NWProxyConfig (handle, owns: true);
}

[DllImport (Constants.NetworkLibrary)]
static unsafe extern OS_nw_proxy_config nw_proxy_config_create_oblivious_http (OS_nw_relay_hop relay, /* sbyte* */IntPtr relay_resource_path, byte* gateway_key_config, nuint gateway_key_config_length);

public static NWProxyConfig? CreateObliviousHttp (NWRelayHop hop, string relaysResourcePath, byte [] gatewayKeyConfig)
{
if (hop is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (hop));
if (relaysResourcePath is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (relaysResourcePath));
if (gatewayKeyConfig is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (gatewayKeyConfig));

using var resourcePathPtr = new TransientString (relaysResourcePath);

unsafe {
fixed (byte* gatewayKeyConfigPointer = gatewayKeyConfig) {
var handle = nw_proxy_config_create_oblivious_http (hop.GetCheckedHandle (), resourcePathPtr, gatewayKeyConfigPointer, (nuint) gatewayKeyConfig.Length);
if (handle == NativeHandle.Zero)
return default;
return new NWProxyConfig (handle, owns: true);
}
}
}

[DllImport (Constants.NetworkLibrary)]
static extern OS_nw_proxy_config nw_proxy_config_create_http_connect (OS_nw_endpoint proxy_endpoint, /* [NullAllowed] */ OS_nw_protocol_options proxy_tls_options);

public static NWProxyConfig? CreateHttpConnect (NWEndpoint proxyEndpoint, NWProtocolTlsOptions? options)
{
if (proxyEndpoint is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (proxyEndpoint));

var handle = nw_proxy_config_create_http_connect (proxyEndpoint.GetCheckedHandle (), options.GetHandle ());
if (handle == NativeHandle.Zero)
return default;
return new NWProxyConfig (handle, true);
}

[DllImport (Constants.NetworkLibrary)]
static extern OS_nw_proxy_config nw_proxy_config_create_socksv5 (OS_nw_endpoint proxy_endpoint);

public static NWProxyConfig? CreateSocksV5 (NWEndpoint endpoint)
{
if (endpoint is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (endpoint));
var handle = nw_proxy_config_create_socksv5 (endpoint.GetCheckedHandle ());
if (handle == NativeHandle.Zero)
return default;
return new NWProxyConfig (handle, true);
}

[DllImport (Constants.NetworkLibrary)]
static extern void nw_proxy_config_set_username_and_password (OS_nw_proxy_config proxy_config, /* sbyte* */ IntPtr username, /* sbyte* */ IntPtr password);

public void SetUsernameAndPassword (string username, string password)
{
if (username is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (username));
if (password is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (password));

using var usernamePtr = new TransientString (username);
using var passwordPtr = new TransientString (password);
nw_proxy_config_set_username_and_password (GetCheckedHandle (), usernamePtr, passwordPtr);
}

[DllImport (Constants.NetworkLibrary)]
static extern void nw_proxy_config_set_failover_allowed (OS_nw_proxy_config proxy_config, /* bool */ byte failover_allowed);

[DllImport (Constants.NetworkLibrary)]
static extern byte nw_proxy_config_get_failover_allowed (OS_nw_proxy_config proxy_config);

public bool FailoverAllowed {
get => nw_proxy_config_get_failover_allowed (GetCheckedHandle ()) != 0;
set => nw_proxy_config_set_failover_allowed (GetCheckedHandle (), (byte) (value ? 1 : 0));
}

[DllImport (Constants.NetworkLibrary)]
static extern void nw_proxy_config_add_match_domain (OS_nw_proxy_config config, /* sbyte* */ IntPtr match_domain);

public void AddMatchDomain (string domain)
{
if (domain is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (domain));
using var domainPtr = new TransientString (domain);
nw_proxy_config_add_match_domain (GetCheckedHandle (), domainPtr);
}

[DllImport (Constants.NetworkLibrary)]
static extern void nw_proxy_config_clear_match_domains (OS_nw_proxy_config config);

public void ClearMatchDomains () => nw_proxy_config_clear_match_domains (GetCheckedHandle ());

[DllImport (Constants.NetworkLibrary)]
static extern void nw_proxy_config_add_excluded_domain (OS_nw_proxy_config config, /* sbyte* */ IntPtr excluded_domain);

public void AddExcludedDomain (string domain)
{
if (domain is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (domain));
using var domainPtr = new TransientString (domain);
nw_proxy_config_add_excluded_domain (GetCheckedHandle (), domainPtr);
}

[DllImport (Constants.NetworkLibrary)]
static extern void nw_proxy_config_clear_excluded_domains (OS_nw_proxy_config config);

public void ClearExcludedDomains () => nw_proxy_config_clear_excluded_domains (GetCheckedHandle ());


[DllImport (Constants.NetworkLibrary)]
static unsafe extern void nw_proxy_config_enumerate_match_domains (OS_nw_proxy_config config, /* nw_proxy_domain_enumerator_t */ BlockLiteral* enumerator);

#if !NET
delegate void nw_proxy_config_enumerate_match_domains_t (IntPtr block, IntPtr domain);
static nw_proxy_config_enumerate_match_domains_t static_EnumerateMatchDomainHandler = TrampolineEnumerateMatchDomainHandler;

[MonoPInvokeCallback (typeof (nw_proxy_config_enumerate_match_domains_t))]
#else
[UnmanagedCallersOnly]
#endif
static void TrampolineEnumerateMatchDomainHandler (IntPtr block, IntPtr domainPtr)
{
var del = BlockLiteral.GetTarget<Action<string?>> (block);
if (del is not null) {
var domain = Marshal.PtrToStringAuto (domainPtr);
del (domain);
}
}

[BindingImpl (BindingImplOptions.Optimizable)]
public void EnumerateMatchDomains (Action<string?> handler)
{
if (handler is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (handler));

unsafe {
#if NET
delegate* unmanaged<IntPtr, IntPtr, void> trampoline = &TrampolineEnumerateMatchDomainHandler;
using var block = new BlockLiteral (trampoline, handler, typeof (NWProxyConfig), nameof (TrampolineEnumerateMatchDomainHandler));
#else
using var block = new BlockLiteral ();
block.SetupBlockUnsafe (static_EnumerateMatchDomainHandler, handler);
#endif
nw_proxy_config_enumerate_match_domains (GetCheckedHandle (), &block);
}
}

[DllImport (Constants.NetworkLibrary)]
static unsafe extern void nw_proxy_config_enumerate_excluded_domains (OS_nw_proxy_config config, BlockLiteral* enumerator);

#if !NET
delegate void nw_proxy_config_enumerate_exclude_domains_t (IntPtr block, IntPtr domain);
static nw_proxy_config_enumerate_exclude_domains_t static_EnumerateExcludeDomainHandler = TrampolineEnumerateExcludeDomainHandler;

[MonoPInvokeCallback (typeof (nw_proxy_config_enumerate_match_domains_t))]
#else
[UnmanagedCallersOnly]
#endif
static void TrampolineEnumerateExcludeDomainHandler (IntPtr block, IntPtr domainPtr)
{
var del = BlockLiteral.GetTarget<Action<string?>> (block);
if (del is not null) {
var domain = Marshal.PtrToStringAuto (domainPtr);
del (domain);
}
}

[BindingImpl (BindingImplOptions.Optimizable)]
public void EnumerateExcludedDomains (Action<string?> handler)
{
if (handler is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (handler));

unsafe {
#if NET
delegate* unmanaged<IntPtr, IntPtr, void> trampoline = &TrampolineEnumerateExcludeDomainHandler;
using var block = new BlockLiteral (trampoline, handler, typeof (NWProxyConfig), nameof (TrampolineEnumerateExcludeDomainHandler));
#else
using var block = new BlockLiteral ();
block.SetupBlockUnsafe (static_EnumerateExcludeDomainHandler, handler);
#endif
nw_proxy_config_enumerate_excluded_domains (GetCheckedHandle (), &block);
}
}

}
}
64 changes: 64 additions & 0 deletions src/Network/NWRelayHop.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#nullable enable

using System;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using ObjCRuntime;
using Foundation;
using CoreFoundation;

using OS_nw_relay_hop = System.IntPtr;
using OS_nw_endpoint = System.IntPtr;
using OS_nw_protocol_options = System.IntPtr;

#if !NET
using NativeHandle = System.IntPtr;
#endif

namespace Network {

#if NET
[SupportedOSPlatform ("tvos17.0")]
[SupportedOSPlatform ("macos14.0")]
[SupportedOSPlatform ("ios17.0")]
[SupportedOSPlatform ("maccatalyst17.0")]
#else
[Watch (10, 0), TV (17, 0), Mac (14, 0), iOS (17, 0), MacCatalyst (17, 0)]
#endif
public class NWRelayHop : NativeObject {
[Preserve (Conditional = true)]
#if NET
internal NWRelayHop (NativeHandle handle, bool owns) : base (handle, owns) {}
#else
public NWRelayHop (NativeHandle handle, bool owns) : base (handle, owns) { }
#endif

[DllImport (Constants.NetworkLibrary)]
static extern OS_nw_relay_hop nw_relay_hop_create (/*[NullAllowed]*/ OS_nw_endpoint http3_relay_endpoint, /*[NullAllowed]*/ OS_nw_endpoint http2_relay_endpoint, /* [NullAllowed]*/ OS_nw_protocol_options relay_tls_options);

public static NWRelayHop? Create (NWEndpoint? http3RelayEndpoint, NWEndpoint? http2RelayEndpoint,
NWProtocolOptions? relayTlsOptions)
{
var handle = nw_relay_hop_create (http3RelayEndpoint.GetHandle (), http2RelayEndpoint.GetHandle (), relayTlsOptions.GetHandle ());
if (handle == NativeHandle.Zero)
return default;
return new NWRelayHop (handle, owns: true);
}

[DllImport (Constants.NetworkLibrary)]
static extern void nw_relay_hop_add_additional_http_header_field (OS_nw_relay_hop relay_hop, /* sbyte* */ IntPtr field_name, /* sbyte* */ IntPtr field_value);

public void AddAdditionalHttpHeaderField (string fieldName, string fieldValue)
{
if (fieldName is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (fieldName));
if (fieldValue is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (fieldValue));

using var fieldNamePtr = new TransientString (fieldName);
using var fieldValuePtr = new TransientString (fieldValue);
nw_relay_hop_add_additional_http_header_field (GetCheckedHandle (), fieldNamePtr, fieldValuePtr);
}

}
}
Loading