StunServer.cs 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. using System;
  2. using System.Linq;
  3. using System.Net;
  4. using System.Net.Sockets;
  5. namespace STUN.Utils
  6. {
  7. public class StunServer
  8. {
  9. public string Hostname { get; set; }
  10. public ushort Port { get; set; }
  11. public StunServer()
  12. {
  13. Hostname = @"stun.syncthing.net";
  14. Port = 3478;
  15. }
  16. public bool Parse(string str)
  17. {
  18. var ipPort = str.Trim().Split(':', ':');
  19. switch (ipPort.Length)
  20. {
  21. case 0:
  22. return false;
  23. case 1:
  24. {
  25. var host = ipPort[0].Trim();
  26. if (Uri.CheckHostName(host) != UriHostNameType.Dns && !IPAddress.TryParse(host, out _))
  27. {
  28. return false;
  29. }
  30. Hostname = host;
  31. Port = 3478;
  32. return true;
  33. }
  34. case 2:
  35. {
  36. var host = ipPort[0].Trim();
  37. if (Uri.CheckHostName(host) != UriHostNameType.Dns && !IPAddress.TryParse(host, out _))
  38. {
  39. return false;
  40. }
  41. if (ushort.TryParse(ipPort[1], out var port))
  42. {
  43. Hostname = host;
  44. Port = port;
  45. return true;
  46. }
  47. break;
  48. }
  49. default:
  50. {
  51. if (IPAddress.TryParse(str.Trim(), out var ipv6))
  52. {
  53. Hostname = $@"{ipv6}";
  54. Port = ushort.TryParse(ipPort.Last(), out var portV6) ? portV6 : (ushort)3478;
  55. return true;
  56. }
  57. var ipStr = string.Join(@":", ipPort, 0, ipPort.Length - 1);
  58. if (!ipStr.StartsWith(@"[") || !ipStr.EndsWith(@"]") || !IPAddress.TryParse(ipStr, out _))
  59. {
  60. return false;
  61. }
  62. if (ushort.TryParse(ipPort.Last(), out var port))
  63. {
  64. Port = port;
  65. return true;
  66. }
  67. break;
  68. }
  69. }
  70. return false;
  71. }
  72. public override string ToString()
  73. {
  74. if (string.IsNullOrEmpty(Hostname))
  75. {
  76. return string.Empty;
  77. }
  78. if (Port == 3478)
  79. {
  80. return Hostname;
  81. }
  82. if (IPAddress.TryParse(Hostname, out var ip) && ip.AddressFamily != AddressFamily.InterNetwork)
  83. {
  84. return $@"[{Hostname}]:{Port}";
  85. }
  86. return $@"{Hostname}:{Port}";
  87. }
  88. }
  89. }