ExternalPortForwarding.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. using MediaBrowser.Controller;
  2. using MediaBrowser.Controller.Configuration;
  3. using MediaBrowser.Controller.Plugins;
  4. using MediaBrowser.Model.Logging;
  5. using Mono.Nat;
  6. using Mono.Nat.Enums;
  7. using Mono.Nat.EventArgs;
  8. using System;
  9. using System.IO;
  10. using System.Text;
  11. namespace MediaBrowser.Server.Implementations.EntryPoints
  12. {
  13. public class ExternalPortForwarding : IServerEntryPoint
  14. {
  15. private readonly IServerApplicationHost _appHost;
  16. private readonly ILogger _logger;
  17. private readonly IServerConfigurationManager _config;
  18. private bool _isStarted;
  19. public ExternalPortForwarding(ILogger logger, IServerApplicationHost appHost, IServerConfigurationManager config)
  20. {
  21. _logger = logger;
  22. _appHost = appHost;
  23. _config = config;
  24. _config.ConfigurationUpdated += _config_ConfigurationUpdated;
  25. }
  26. void _config_ConfigurationUpdated(object sender, EventArgs e)
  27. {
  28. var enable = _config.Configuration.EnableUPnP;
  29. if (enable && !_isStarted)
  30. {
  31. Reload();
  32. }
  33. else if (!enable && _isStarted)
  34. {
  35. DisposeNat();
  36. }
  37. }
  38. public void Run()
  39. {
  40. //NatUtility.Logger = new LogWriter(_logger);
  41. Reload();
  42. }
  43. private void Reload()
  44. {
  45. if (_config.Configuration.EnableUPnP)
  46. {
  47. _logger.Debug("Starting NAT discovery");
  48. NatUtility.DeviceFound += NatUtility_DeviceFound;
  49. NatUtility.DeviceLost += NatUtility_DeviceLost;
  50. NatUtility.UnhandledException += NatUtility_UnhandledException;
  51. NatUtility.StartDiscovery();
  52. _isStarted = true;
  53. }
  54. }
  55. void NatUtility_UnhandledException(object sender, UnhandledExceptionEventArgs e)
  56. {
  57. //var ex = e.ExceptionObject as Exception;
  58. //if (ex == null)
  59. //{
  60. // _logger.Error("Unidentified error reported by Mono.Nat");
  61. //}
  62. //else
  63. //{
  64. // // Seeing some blank exceptions coming through here
  65. // _logger.ErrorException("Error reported by Mono.Nat: ", ex);
  66. //}
  67. }
  68. void NatUtility_DeviceFound(object sender, DeviceEventArgs e)
  69. {
  70. try
  71. {
  72. var device = e.Device;
  73. _logger.Debug("NAT device found: {0}", device.LocalAddress.ToString());
  74. CreateRules(device);
  75. }
  76. catch (Exception)
  77. {
  78. //_logger.ErrorException("Error creating port forwarding rules", ex);
  79. }
  80. }
  81. private void CreateRules(INatDevice device)
  82. {
  83. var info = _appHost.GetSystemInfo();
  84. CreatePortMap(device, info.HttpServerPortNumber);
  85. if (info.WebSocketPortNumber != info.HttpServerPortNumber)
  86. {
  87. CreatePortMap(device, info.WebSocketPortNumber);
  88. }
  89. }
  90. private void CreatePortMap(INatDevice device, int port)
  91. {
  92. _logger.Debug("Creating port map on port {0}", port);
  93. device.CreatePortMap(new Mapping(Protocol.Tcp, port, port)
  94. {
  95. Description = "Media Browser Server"
  96. });
  97. }
  98. void NatUtility_DeviceLost(object sender, DeviceEventArgs e)
  99. {
  100. var device = e.Device;
  101. _logger.Debug("NAT device lost: {0}", device.LocalAddress.ToString());
  102. }
  103. public void Dispose()
  104. {
  105. DisposeNat();
  106. }
  107. private void DisposeNat()
  108. {
  109. _logger.Debug("Stopping NAT discovery");
  110. try
  111. {
  112. NatUtility.DeviceFound -= NatUtility_DeviceFound;
  113. NatUtility.DeviceLost -= NatUtility_DeviceLost;
  114. NatUtility.UnhandledException -= NatUtility_UnhandledException;
  115. NatUtility.StopDiscovery();
  116. }
  117. catch (Exception ex)
  118. {
  119. _logger.ErrorException("Error stopping NAT Discovery", ex);
  120. }
  121. finally
  122. {
  123. _isStarted = false;
  124. }
  125. }
  126. private class LogWriter : TextWriter
  127. {
  128. private readonly ILogger _logger;
  129. public LogWriter(ILogger logger)
  130. {
  131. _logger = logger;
  132. }
  133. public override Encoding Encoding
  134. {
  135. get { return Encoding.UTF8; }
  136. }
  137. public override void WriteLine(string format, params object[] arg)
  138. {
  139. _logger.Debug(format, arg);
  140. }
  141. public override void WriteLine(string value)
  142. {
  143. _logger.Debug(value);
  144. }
  145. }
  146. }
  147. }