PNRP stops working windows 10 1803 - windows

I had some code that uses PNRP to discover peers on network. Everything works fine since Windows 10 update 1803.
public void Init()
{
try
{
_ServiceUrl = Dns.GetHostAddresses(Dns.GetHostName()).Where(address => address.AddressFamily == AddressFamily.InterNetwork).Select(address => _Address = address).Select(address => $"net.tcp://{address}:{Port}/SiemensVR").FirstOrDefault();
if (string.IsNullOrEmpty(_ServiceUrl)) return;
_LocalProxy = new PeerProxy(_EventAggregator, this);
_Host = new ServiceHost(_LocalProxy, new Uri(_ServiceUrl));
var binding = new NetTcpBinding();
binding.Security.Mode = SecurityMode.None;
_Host.AddServiceEndpoint(typeof(IPeerContract), binding, new Uri(_ServiceUrl));
_Host.Open();
_PeerName = new PeerName(PEER_NAME_ID, PeerNameType.Unsecured);
_PeerNameRegistration = new PeerNameRegistration(_PeerName, Port) { Cloud = Cloud.AllLinkLocal };
_PeerNameRegistration.Comment = _UserId.ToString();
_PeerNameRegistration.Start();
ResolvePeers();
}
finally { }
}
private async void ResolvePeers()
{
var resolver = new PeerNameResolver();
resolver.ResolveProgressChanged += OnResolveProgressChanged;
resolver.ResolveCompleted += (s, e) =>
{
Console.WriteLine("Completed");
};
resolver.ResolveAsync(_PeerName, this);
await Task.Delay(1000);
resolver.ResolveAsyncCancel(this);
}
Does MS have replace PNRP by something ?
I already tested to activate pnrp services, reinstall teredo tunneling and more.

Microsoft has deprecated and is in the process of removing PNRP.
You're out of luck, since its service and client APIs are being removed completely.
See https://learn.microsoft.com/en-us/windows/deployment/planning/windows-10-deprecated-features

Having the same issue here... Let me know if you find any resolution.
Previously, our application works fine, but on 1803 it doesn't work anymore. I can see the cloud start to synchronize and then each peer just ends up going to status alone.

Same issue, I found a Microsoft note to set the following services to Automatic Delayed Start:
Computer Browser (Browser) <- Set to Automatic, not delayed start
Function Discovery Provider Host (FDPHost)
Function Discovery Resource Publication (FDResPub)
Network Connections (NetMan)
UPnP Device Host (UPnPHost)
Peer Name Resolution Protocol (PNRPSvc)
Peer Networking Grouping (P2PSvc)
Peer Networking Identity Manager (P2PIMSvc)
But it didn't resolve the issue.
Any progress in resolving this?

Related

Trouble with connecting to wifi in code in Xamarin

I've been trying to connect to a specific wifi through code, but with no succcess.
This is what i've come up with:
public void ConnectToWifi(string ssid, string password)
{
WifiManager wifiManager = (WifiManager)Android.App.Application.Context.GetSystemService(Context.WifiService);
if (!wifiManager.IsWifiEnabled)
{
wifiManager.SetWifiEnabled(true);
}
string formattedSsid = $"\"{ssid}\"";
string formattedPassword = $"\"{password}\"";
WifiConfiguration wifiConfig = new WifiConfiguration
{
Ssid = formattedSsid,
PreSharedKey = formattedPassword
};
var addNetwork = wifiManager.AddNetwork(wifiConfig);
WifiConfiguration network = wifiManager.ConfiguredNetworks.FirstOrDefault(n => n.Ssid == ssid);
if (network == null)
{
Console.WriteLine($"Cannot connect to network: {ssid}");
return;
}
wifiManager.Disconnect();
bool enableNetwork = wifiManager.EnableNetwork(network.NetworkId, true);
}
I've added permissions.
When testing it does turn the wifi on atleast, so i know it works until that point. What seems not to be working is the AddNetwork part.
I appreciate any help i can get!
You are missing one key method - reconnect(). You can read more about it in the WifiManager's docs here
The important part of the documentation is:
Reconnect to the currently active access point, if we are currently disconnected.
So, what you need to do it after you have disconnected and enabled your new network, call in the end this and you will be good to go:
wifiManager.Disconnect();
wifiManager.EnableNetwork(network.NetworkId, true);
wifiManager.Reconnect(); // This is the missing method
NB: Keep in mind that most of the WifiManager's code that you are using is being obsolete starting Android 10. So, if you want to target Android 10, then you will need to write an additional code for the connectivity for devices with Android 10+.

PostAsync hanging in Xamarin Forms works on emulator but hangs on actual Mobile phone

I have Xamarin Forms project where I'm trying to POST and GET data to/from a Web API but when I'm making an async/await call, it works on the emulator (not without its original problems!) but when I try it on my actual phone mobile (Samsung S8+), it just hangs indefinitely.
Note that I'm only concentrating on the Android part right now, not iOS, not that the problem should make any difference in either.
This is the code I'm using:
IDataService.cs
Task<TResponse> PostDataAsync<TRequest, TResponse>(string uri, TRequest data)
where TRequest : class
where TResponse : class;
DataService.cs:
public async Task<TResponse> PostDataAsync<TRequest, TResponse>(string
additionalUri, TRequest data)
where TRequest : class
where TResponse : class
{
return await WebClient
.PostData<TRequest, TResponse>
(string.Concat(this.Uri, additionalUri), data);
}
WebClient.cs
using (var client = new HttpClient())
{
var jsonData = JsonConvert.SerializeObject(data);
using (var response = await client.PostAsync(
uri,
new StringContent(jsonData,
Encoding.UTF8,
"application/json" )))
{
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<TResponse>(content);
}
}
}
Method 1:
LoginPageViewModel.cs
public DelegateCommand SignInCommand => _signInCommand ??
(this._signInCommand = new DelegateCommand(SignInCommandAction));
private async void SignInCommandAction()
{
try
{
....
var user = await this._dataService
.PostDataAsync<LoginRequestDto,
LoginResponseDto>(#"Accounts/Login", loginRequestDto);
....
}
...
}
Method2:
LoginPageViewModel.cs
public DelegateCommand SignInCommand => _signInCommand ??
(this._signInCommand =
new DelegateCommand(async () => await SignInCommandAction()));
private async Task SignInCommandAction()
{
try
{
....
var user = await this._dataService
.PostDataAsync<LoginRequestDto,
LoginResponseDto>(#"Accounts/Login", loginRequestDto);
....
}
...
}
The PostDataAsync works with both methods when I call my local web API i.e. http://10.0.2.2/MyApp/api/ but both methods still hangs when calling external my web service from web provider i.e. http://myapp-123-site.atempurl.com/api/ which is a temp url for testing purpose.
The same apply to my GetDataAsync which is not demonstrated in question but I just thought I'd mention it.
Based on the above, you would think that my async/await code is correct since it works when calling the local web api but then what's causing it to hang when calling the remote web api.
As mentioned, I did enable my INTERNET permission in the manifest.
Any suggestions welcomed?
Thanks.
UPDATE-1:
Note that I've just tried to call a GET opertation within the same function and this is working in the emulator but hanging with the actual mobile.
using (var client = new HttpClient())
{
using (var response = await client.GetAsync(uri))
{
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
return Newtonsoft.Json.JsonConvert
.DeserializeObject<TResponse>(content);
}
}
}
UPDATE-2:
This is somehow working and I have no idea why! The only thing that comes to mind is that I upgraded my libraries. This included PRISM which may have been at the source of the problem but I have no idea.
Sorry I can't provide more details. I could role back my code and try to see if it's hanging again but I just don't have the time to go and experiment some more considering the amount of time I've already spent on this. Sorry.
The requested url is an IP or a domain name.
If it is ip, only the IP of the public network can be accessed by devices on multiple network segments.
If it is a domain name, it needs to support the domain name resolution service.
If you do not have these environments for a while, you need the IP of the device and the IP of the server on the same network segment.
The PostDataAsync works with both methods when I call my local web API i.e. http://10.0.2.2/MyApp/api/ but both methods still hangs when calling external my web service from web provider i.e. http://myapp-123-site.atempurl.com/api/ which is a temp url for testing purpose.
From this phenomenon , the reason should be the temp url. From this domain name (myapp-123-site.atempurl.com) can not find the right local IP (10.0.2.2).And when you test in local network , I guess this will work.However the network of actual mobile can be not the same with local network , such as using 3G/4G network , then this will not working.

UWP VPN - VpnPlugin connect implementation throws exception in StartWithMainTransport

Kindly see the UWP code snippet below tried on Windows 10 desktop using Visual Studio 2017 community edition.
The code implements Custom IVpnPlugin module. When system's VPN configuration is selected to this app and connect is done, the application's task gets triggered and VPN plugin's "Connect()" method gets invoked.
However, following code steps face exception while executing StartWithMainTransport(…).
("The operation was cancelled by user") on Visual Studio.
On the system's VPN settings following error is seen - "remote access service ip configuration is unusable"
I think I am passing correctly v4 and v6 address to the channel->StartWithMainTransport(…) API which are bound to my m/c network I/f. What other validations may have caused this issue. I do not want to configure certificates etc for the VpnChannel as I plan to implement encapsulate and decapsulate myself in VpnPlugin.
// Sample Plugin's connect implementation
void TunnelPlugin::Connect(Windows::Networking::Vpn::VpnChannel^ channel)
{
this->dSock = ref new DatagramSocket();
channel->AssociateTransport(this->dSock, nullptr); // No difference even if this statement is moved after ConnectAsync().
Platform::String^ svcName = "22111";
auto result = create_task(dSock->BindServiceNameAsync(svcName));
result.get();
// Connect to the destination tunnel address on UDP socket.
HostName^ remoteTunnelIP = ref new HostName("192.168.1.137");
Platform::String^ remoteTunnelPort = "22112";
result = create_task(this->dSock->ConnectAsync(remoteTunnelIP, remoteTunnelPort));
result.get();
VpnChannelConfiguration^ chanCfg = channel->Configuration;
// IP destinations to be routed via VPN
VpnRouteAssignment^ routeScope = ref new VpnRouteAssignment();
routeScope->Ipv4InclusionRoutes->Append(ref new VpnRoute(ref new HostName("192.168.1.111"), 32));
Vector<HostName^>^ localV4Addrs = ref new Vector<HostName^>;
localV4Addrs->Append(ref new HostName("192.168.1.133")); // Local host name to be bound.
Vector<HostName^>^ localV6Addrs = ref new Vector<HostName^>;
localV6Addrs->Append(ref new HostName("fc00::44fd:d3ed:b02a:a05e"));
Vector<HostName^>^ dnsServers = ref new Vector<HostName^>;
dnsServers->Append(ref new HostName("1.1.1.1"));
VpnDomainNameInfo^ dnsInfo = ref new VpnDomainNameInfo(".", VpnDomainNameType::Suffix, dnsServers, ref new Vector<HostName^>);
VpnDomainNameAssignment^ dnsAssignment = ref new VpnDomainNameAssignment;
dnsAssignment->DomainNameList->Append(dnsInfo);
try
{
// Throws exception here.
channel->StartWithMainTransport(localV4Addrs->GetView(), localV6Addrs->GetView(), nullptr, routeScope, dnsAssignment, 1400, 1412, false, this->dSock);
}
catch (Exception^ exc)
{
auto type = exc->GetType();
Platform::String^ str = exc->ToString();
}
}

Detect network changes in Xamarin Forms

I want to detect when the user is online or offline.
I am using CrossConnectivity package to detect connectivity changes.
I have to connect to VPN (Sonic Wall to be exact) in order to connect to my server.
My problem is this: When I am connecting to my server, I need to switch apps in order for me to connect to my server. When I switch back to my app the function SyncFunction.SyncUser(host, database, contact, ipaddress, pingipaddress) is not executing. The connectivity changed function is not on my App.xaml.cs it is on my Main Menu Content page because I need the sync function to be executed in my main menu not the whole app. How can I fix this?
CrossConnectivity.Current.ConnectivityChanged += async (sender, args) =>
{
var appdate = Preferences.Get("appdatetime", String.Empty, "private_prefs");
if (string.IsNullOrEmpty(appdate))
{
Preferences.Set("appdatetime", DateTime.Now.ToString(), "private_prefs");
}
else
{
if (DateTime.Now >= DateTime.Parse(Preferences.Get("appdatetime", String.Empty, "private_prefs")))
{
Preferences.Set("appdatetime", DateTime.Now.ToString(), "private_prefs");
if (CrossConnectivity.Current.IsConnected)
{
var ping = new Ping();
var reply = ping.Send(new IPAddress(pingipaddress), 5000);
if (reply.Status == IPStatus.Success)
{
lblStatus.Text = "Syncing data to server";
lblStatus.BackgroundColor = Color.FromHex("#2bcbba");
await Task.Delay(5000);
SyncFunction.SyncUser(host, database, contact, ipaddress, pingipaddress);
lblStatus.Text = "Online - Connected to server";
lblStatus.BackgroundColor = Color.FromHex("#2ecc71");
}
else
{
lblStatus.Text = "Online - Server unreachable. Connect to VPN";
lblStatus.BackgroundColor = Color.FromHex("#e67e22");
}
}
else
{
lblStatus.Text = "Offline - Connect to internet";
lblStatus.BackgroundColor = Color.FromHex("#e74c3c");
}
}
else
{
await DisplayAlert("Application Error", "It appears you change the time/date of your phone. Please restore the correct time/date", "Got it");
await Navigation.PopToRootAsync();
}
}
};
Detecting connectivity change across a VPN is not easy.
A workaround solution is to use a webservice as ping.
If you have a backend with API, this "ping" can be executed regularly to ensure the network AND the API are accessible.
This solution is to be used in addition to the connectivity check
Subscribe to connectivity changed
When conectivity looks OK, check the "ping service"
Typically in a mob app, this "ping endpoint" can be something like "/about".
Moreover, this specific service can be use to perform the compatibility version check beetween App Mob version and API version.
(look also Xamarin.Essentials to replace CrossConnectivity by Xamarin.Essentials: Connectivity, https://learn.microsoft.com/fr-fr/xamarin/essentials/connectivity?context=xamarin%2Fxamarin-forms&tabs=android)

Edge extension: BackgroundTaskInstance cancels with SystemPolicy reason when DesktopBridge app tries to open WebSocket

I created an Edge browser extension which uses Native Messaging to a native app running via a Desktop Bridge technology. I used the SecureInput as a sample, which contains the Edge extension, UWP host and a Win32 Desktop Bridge app.
I need the Win32 Desktop Bridge app to connect to a web service using HTTP and WebSocket, so I added an internetClientServer and a privateNetworkClientServer capabilities to the package manifest, beside the already existed runFullTrust one.
The Win32 Desktop Bridge app activates just fine, and it is able to connect to the web server using HTTP. But as soon as it tries to open a WebSocket connection, the BackgroundTaskInstance on the UWP host receives a cancellation request with a BackgroundTaskCancellationReason.SystemPolicy as a reason, and the Desktop Bridge application closes. Unfortunately, the documentation for the BackgroundTaskCancellationReason.SystemPolicy does not explain much about true reasons of the cancellation request.
I tried to use two WebSocket classes: the System.Net.WebSockets.ClientWebSocket and the Windows.Networking.Sockets.MessageWebSocket, with the same result. No fancy code, just regular
var socket = new MessageWebSocket();
...
await socket.ConnectAsync(new Uri("wss://127.0.0.1:9001/myservice"));
The same WebSocket service endpoint is available from other WS clients, so I guess there is no server/firewall/antivirus issue here.
I also played with the CheckNetIsolation tool, adding loopback exemption for the Edge browser and for the package, with no effect. The HTTP works fine without the loopback exemption.
What may be a true reason of the task cancellation, and what can be a possible way to prevent it?
Ok, I resolved the issue. Thanks to this comment by Tom Shane I stumbled upon, I realized that the BackgroundTaskCancellationReason.SystemPolicy tells that the background task is closed by the system to release some system resources, and that in my case it happened because I didn't obtain a deferral in my async event handler. When the event handler yielded without a deferral, the system decided it can shut the task down. Below is a digested version of the code:
static class Program
{
static AppServiceConnection connection = null;
[STAThread]
static void Main(string[] args)
{
Thread appServiceThread = new Thread(new ThreadStart(ThreadProc));
appServiceThread.Start();
Application.Run();
}
static async void ThreadProc()
{
try {
connection = new AppServiceConnection();
connection.AppServiceName = "...";
connection.PackageFamilyName = Windows.ApplicationModel.Package.Current.Id.FamilyName;
connection.RequestReceived += OnRequestReceived;
connection.ServiceClosed += OnServiceClosed;
var status = await connection.OpenAsync();
....
}
catch (Exception e) { ... }
}
private static async void OnRequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args)
{
var defer = args.GetDeferral(); // <== that was missing, rookie mistake!
try {
var msg = ParseMessage(args.Request.Message);
if (msg.type.Equals("ws")) {
// this method was truly async
// and every time it yielded the issue was revealed
await HandleWsMessage(request, msg);
}
else if (msg.type.Equals("http")) {
// but this method was actually synchronous despite being marked as "async"
// and it never yielded, masking the issue for HTTP client
await HandleHttpMessage(request, msg);
}
}
catch (Exception e) { ... }
finally {
defer.Complete();
}
}
}

Resources