RFC5780ViewModel.cs 1.6 KB

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