RFC5780ViewModel.cs 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. using Dns.Net.Abstractions;
  2. using JetBrains.Annotations;
  3. using NatTypeTester.Models;
  4. using ReactiveUI;
  5. using ReactiveUI.Fody.Helpers;
  6. using STUN.Client;
  7. using STUN.Proxy;
  8. using STUN.StunResult;
  9. using STUN.Utils;
  10. using System;
  11. using System.Net;
  12. using System.Reactive;
  13. using System.Reactive.Linq;
  14. using System.Threading;
  15. using System.Threading.Tasks;
  16. namespace NatTypeTester.ViewModels
  17. {
  18. [UsedImplicitly]
  19. public class RFC5780ViewModel : ViewModelBase, IRoutableViewModel
  20. {
  21. public string UrlPathSegment => @"RFC5780";
  22. public IScreen HostScreen => LazyServiceProvider.LazyGetRequiredService<IScreen>();
  23. private Config Config => LazyServiceProvider.LazyGetRequiredService<Config>();
  24. private IDnsClient DnsClient => LazyServiceProvider.LazyGetRequiredService<IDnsClient>();
  25. [Reactive]
  26. public StunResult5389 Result5389 { get; set; }
  27. public ReactiveCommand<Unit, Unit> DiscoveryNatType { get; }
  28. public RFC5780ViewModel()
  29. {
  30. Result5389 = new StunResult5389 { LocalEndPoint = new IPEndPoint(IPAddress.Any, 0) };
  31. DiscoveryNatType = ReactiveCommand.CreateFromTask(DiscoveryNatTypeImpl);
  32. }
  33. private async Task DiscoveryNatTypeImpl(CancellationToken token)
  34. {
  35. var server = new StunServer();
  36. if (!server.Parse(Config.StunServer))
  37. {
  38. throw new Exception(@"Wrong STUN Server!");
  39. }
  40. using var proxy = ProxyFactory.CreateProxy(
  41. Config.ProxyType,
  42. Result5389.LocalEndPoint,
  43. IPEndPoint.Parse(Config.ProxyServer),
  44. Config.ProxyUser, Config.ProxyPassword
  45. );
  46. using var client = new StunClient5389UDP(DnsClient, server.Hostname, server.Port, Result5389.LocalEndPoint, proxy);
  47. Result5389 = client.Status;
  48. using (Observable.Interval(TimeSpan.FromSeconds(0.1))
  49. .ObserveOn(RxApp.MainThreadScheduler)
  50. .Subscribe(_ => this.RaisePropertyChanged(nameof(Result5389))))
  51. {
  52. await client.QueryAsync();
  53. }
  54. var cache = new StunResult5389();
  55. cache.Clone(client.Status);
  56. cache.LocalEndPoint = client.LocalEndPoint;
  57. Result5389 = cache;
  58. this.RaisePropertyChanged(nameof(Result5389));
  59. }
  60. }
  61. }