StunClient3489Test.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. using Dns.Net.Abstractions;
  2. using Dns.Net.Clients;
  3. using Microsoft.VisualStudio.TestTools.UnitTesting;
  4. using Moq;
  5. using STUN.Client;
  6. using STUN.Enums;
  7. using STUN.Messages;
  8. using STUN.Utils;
  9. using System.Net;
  10. using System.Threading;
  11. using System.Threading.Tasks;
  12. using static STUN.Utils.AttributeExtensions;
  13. namespace UnitTest
  14. {
  15. [TestClass]
  16. public class StunClient3489Test
  17. {
  18. private readonly IDnsClient _dnsClient = new DefaultDnsClient();
  19. private const string Server = @"stun.syncthing.net";
  20. private const ushort Port = 3478;
  21. private static readonly IPEndPoint Any = new(IPAddress.Any, 0);
  22. private static readonly IPEndPoint MappedAddress1 = IPEndPoint.Parse(@"1.1.1.1:114");
  23. private static readonly IPEndPoint MappedAddress2 = IPEndPoint.Parse(@"1.1.1.1:514");
  24. private static readonly IPEndPoint ServerAddress = IPEndPoint.Parse(@"2.2.2.2:1919");
  25. private static readonly IPEndPoint ChangedAddress1 = IPEndPoint.Parse(@"3.3.3.3:23333");
  26. private static readonly IPEndPoint ChangedAddress2 = IPEndPoint.Parse(@"2.2.2.2:810");
  27. private static readonly StunMessage5389 DefaultStunMessage = new();
  28. [TestMethod]
  29. public async Task UdpBlockedTestAsync()
  30. {
  31. var nullMessage = new StunResponse { Message = null, Remote = Any };
  32. var nullRemote = new StunResponse { Message = DefaultStunMessage, Remote = null };
  33. var mock = new Mock<StunClient3489>(IPAddress.Any, Port, null, null);
  34. var client = mock.Object;
  35. mock.Setup(x => x.Test1Async(It.IsAny<CancellationToken>())).Returns(null);
  36. await TestAsync();
  37. mock.Setup(x => x.Test1Async(It.IsAny<CancellationToken>())).ReturnsAsync(nullMessage);
  38. await TestAsync();
  39. mock.Setup(x => x.Test1Async(It.IsAny<CancellationToken>())).ReturnsAsync(nullRemote);
  40. await TestAsync();
  41. async Task TestAsync()
  42. {
  43. Assert.AreEqual(NatType.Unknown, client.Status.NatType);
  44. await client.QueryAsync();
  45. Assert.AreEqual(NatType.UdpBlocked, client.Status.NatType);
  46. client.Status.Reset();
  47. }
  48. }
  49. [TestMethod]
  50. public async Task UnsupportedServerTest1Async()
  51. {
  52. var mock = new Mock<StunClient3489>(IPAddress.Any, Port, null, null);
  53. var client = mock.Object;
  54. var unknownResponse = new StunResponse { Message = DefaultStunMessage, Remote = Any };
  55. mock.Setup(x => x.Test1Async(It.IsAny<CancellationToken>())).ReturnsAsync(unknownResponse);
  56. await TestAsync();
  57. var r1 = new StunResponse
  58. {
  59. Message = new StunMessage5389
  60. {
  61. Attributes = new[]
  62. {
  63. BuildMapping(IpFamily.IPv4, MappedAddress1.Address, (ushort)MappedAddress1.Port)
  64. }
  65. },
  66. Remote = Any
  67. };
  68. mock.Setup(x => x.Test1Async(It.IsAny<CancellationToken>())).ReturnsAsync(r1);
  69. await TestAsync();
  70. var r2 = new StunResponse
  71. {
  72. Message = new StunMessage5389
  73. {
  74. Attributes = new[]
  75. {
  76. BuildChangeAddress(IpFamily.IPv4, ChangedAddress1.Address, (ushort)ChangedAddress1.Port)
  77. }
  78. },
  79. Remote = Any
  80. };
  81. mock.Setup(x => x.Test1Async(It.IsAny<CancellationToken>())).ReturnsAsync(r2);
  82. await TestAsync();
  83. var r3 = new StunResponse
  84. {
  85. Message = new StunMessage5389
  86. {
  87. Attributes = new[]
  88. {
  89. BuildMapping(IpFamily.IPv4, MappedAddress1.Address, (ushort)MappedAddress1.Port),
  90. BuildChangeAddress(IpFamily.IPv4, ServerAddress.Address, (ushort)ChangedAddress1.Port)
  91. }
  92. },
  93. Remote = ServerAddress
  94. };
  95. mock.Setup(x => x.Test1Async(It.IsAny<CancellationToken>())).ReturnsAsync(r3);
  96. await TestAsync();
  97. var r4 = new StunResponse
  98. {
  99. Message = new StunMessage5389
  100. {
  101. Attributes = new[]
  102. {
  103. BuildMapping(IpFamily.IPv4, MappedAddress1.Address, (ushort)MappedAddress1.Port),
  104. BuildChangeAddress(IpFamily.IPv4, ChangedAddress1.Address, (ushort)ServerAddress.Port)
  105. }
  106. },
  107. Remote = ServerAddress
  108. };
  109. mock.Setup(x => x.Test1Async(It.IsAny<CancellationToken>())).ReturnsAsync(r4);
  110. await TestAsync();
  111. async Task TestAsync()
  112. {
  113. Assert.AreEqual(NatType.Unknown, client.Status.NatType);
  114. await client.QueryAsync();
  115. Assert.AreEqual(NatType.UnsupportedServer, client.Status.NatType);
  116. client.Status.Reset();
  117. }
  118. }
  119. [TestMethod]
  120. public async Task Test1Async()
  121. {
  122. var ip = await _dnsClient.QueryAsync(Server);
  123. using var client = new StunClient3489(ip);
  124. var response = await client.Test1Async(default);
  125. Assert.IsNotNull(response);
  126. Assert.IsNotNull(response.Message);
  127. Assert.IsNotNull(response.Remote);
  128. Assert.IsNotNull(response.LocalAddress);
  129. Assert.AreEqual(ip, response.Remote.Address);
  130. Assert.AreEqual(Port, response.Remote.Port);
  131. var mappedAddress = response.Message.GetMappedAddressAttribute();
  132. var changedAddress = response.Message.GetChangedAddressAttribute();
  133. Assert.IsNotNull(mappedAddress);
  134. Assert.IsNotNull(changedAddress);
  135. Assert.AreNotEqual(ip, changedAddress.Address);
  136. Assert.AreNotEqual(Port, changedAddress.Port);
  137. }
  138. }
  139. }