aboutsummaryrefslogtreecommitdiff
path: root/Mono.Nat
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2016-10-27 19:53:57 -0400
committerLuke Pulverenti <luke.pulverenti@gmail.com>2016-10-27 19:53:57 -0400
commit8e57296f6986f13578f37647640fcaf49c9981f1 (patch)
tree4762b6c0f260802b95c73f1fe1edcf1782b6cec4 /Mono.Nat
parent0c663a99dc617869f591e97dd2e4ca6f3bd8b207 (diff)
lighten up nat project
Diffstat (limited to 'Mono.Nat')
-rw-r--r--Mono.Nat/Exceptions/MappingException.cs19
-rw-r--r--Mono.Nat/NatUtility.cs43
-rw-r--r--Mono.Nat/Upnp/Mappers/UpnpMapper.cs10
-rw-r--r--Mono.Nat/Upnp/Messages/GetServicesMessage.cs9
-rw-r--r--Mono.Nat/Upnp/Searchers/UpnpSearcher.cs193
-rw-r--r--Mono.Nat/Upnp/Upnp.cs10
-rw-r--r--Mono.Nat/Upnp/UpnpNatDevice.cs19
7 files changed, 41 insertions, 262 deletions
diff --git a/Mono.Nat/Exceptions/MappingException.cs b/Mono.Nat/Exceptions/MappingException.cs
index bb2e6a69d..9c0c4f122 100644
--- a/Mono.Nat/Exceptions/MappingException.cs
+++ b/Mono.Nat/Exceptions/MappingException.cs
@@ -25,11 +25,9 @@
//
using System;
-using System.Security.Permissions;
namespace Mono.Nat
{
- [Serializable]
public class MappingException : Exception
{
private int errorCode;
@@ -45,7 +43,6 @@ namespace Mono.Nat
get { return this.errorText; }
}
- #region Constructors
public MappingException()
: base()
{
@@ -67,21 +64,5 @@ namespace Mono.Nat
: base(message, innerException)
{
}
-
- protected MappingException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
- : base(info, context)
- {
- }
- #endregion
-
- [SecurityPermission(SecurityAction.Demand, SerializationFormatter=true)]
- public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
- {
- if(info==null) throw new ArgumentNullException("info");
-
- this.errorCode = info.GetInt32("errorCode");
- this.errorText = info.GetString("errorText");
- base.GetObjectData(info, context);
- }
}
}
diff --git a/Mono.Nat/NatUtility.cs b/Mono.Nat/NatUtility.cs
index 6d91d2513..b886b87cf 100644
--- a/Mono.Nat/NatUtility.cs
+++ b/Mono.Nat/NatUtility.cs
@@ -66,14 +66,12 @@ namespace Mono.Nat
{
EnabledProtocols = new List<NatProtocol>
{
- NatProtocol.Upnp,
NatProtocol.Pmp
};
searching = new ManualResetEvent(false);
controllers = new List<ISearcher>();
- controllers.Add(UpnpSearcher.Instance);
controllers.Add(PmpSearcher.Instance);
controllers.ForEach(searcher =>
@@ -111,10 +109,6 @@ namespace Mono.Nat
{
var enabledProtocols = EnabledProtocols.ToList();
- if (enabledProtocols.Contains(UpnpSearcher.Instance.Protocol))
- {
- Receive(UpnpSearcher.Instance, UpnpSearcher.sockets);
- }
if (enabledProtocols.Contains(PmpSearcher.Instance.Protocol))
{
Receive(PmpSearcher.Instance, PmpSearcher.sockets);
@@ -149,20 +143,6 @@ namespace Mono.Nat
}
}
}
-
- static void Receive(IMapper mapper, List<UdpClient> clients)
- {
- IPEndPoint received = new IPEndPoint(IPAddress.Parse("192.168.0.1"), 5351);
- foreach (UdpClient client in clients)
- {
- if (client.Available > 0)
- {
- IPAddress localAddress = ((IPEndPoint)client.Client.LocalEndPoint).Address;
- byte[] data = client.Receive(ref received);
- mapper.Handle(localAddress, data);
- }
- }
- }
public static void StartDiscovery ()
{
@@ -184,7 +164,7 @@ namespace Mono.Nat
mapper = new PmpMapper();
break;
case MapperType.Upnp:
- mapper = new UpnpMapper();
+ mapper = new UpnpMapper(Logger);
mapper.DeviceFound += (sender, args) =>
{
if (DeviceFound != null)
@@ -199,23 +179,6 @@ namespace Mono.Nat
searching.Reset();
}
-
- //So then why is it here? -Nick
- [Obsolete ("This method serves no purpose and shouldn't be used")]
- public static IPAddress[] GetLocalAddresses (bool includeIPv6)
- {
- List<IPAddress> addresses = new List<IPAddress> ();
-
- IPHostEntry hostInfo = Dns.GetHostEntry (Dns.GetHostName ());
- foreach (IPAddress address in hostInfo.AddressList) {
- if (address.AddressFamily == AddressFamily.InterNetwork ||
- (includeIPv6 && address.AddressFamily == AddressFamily.InterNetworkV6)) {
- addresses.Add (address);
- }
- }
-
- return addresses.ToArray ();
- }
//checks if an IP address is a private address space as defined by RFC 1918
public static bool IsPrivateAddressSpace (IPAddress address)
@@ -239,7 +202,7 @@ namespace Mono.Nat
switch (protocol)
{
case NatProtocol.Upnp:
- UpnpSearcher.Instance.Handle(localAddress, response, endpoint);
+ //UpnpSearcher.Instance.Handle(localAddress, response, endpoint);
break;
case NatProtocol.Pmp:
PmpSearcher.Instance.Handle(localAddress, response, endpoint);
@@ -254,7 +217,7 @@ namespace Mono.Nat
switch (protocol)
{
case NatProtocol.Upnp:
- UpnpSearcher.Instance.Handle(localAddress, deviceInfo, endpoint);
+ new UpnpSearcher(Logger).Handle(localAddress, deviceInfo, endpoint);
break;
default:
throw new ArgumentException("Unexpected protocol: " + protocol);
diff --git a/Mono.Nat/Upnp/Mappers/UpnpMapper.cs b/Mono.Nat/Upnp/Mappers/UpnpMapper.cs
index 6f2716805..9169d3f40 100644
--- a/Mono.Nat/Upnp/Mappers/UpnpMapper.cs
+++ b/Mono.Nat/Upnp/Mappers/UpnpMapper.cs
@@ -32,6 +32,7 @@ using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
+using MediaBrowser.Model.Logging;
namespace Mono.Nat.Upnp.Mappers
{
@@ -42,7 +43,8 @@ namespace Mono.Nat.Upnp.Mappers
public UdpClient Client { get; set; }
- public UpnpMapper()
+ public UpnpMapper(ILogger logger)
+ : base(logger)
{
//Bind to local port 1900 for ssdp responses
Client = new UdpClient(1900);
@@ -88,11 +90,7 @@ namespace Mono.Nat.Upnp.Mappers
}
catch (Exception ex)
{
- Trace.WriteLine("Unhandled exception when trying to decode a device's response Send me the following data: ");
- Trace.WriteLine("ErrorMessage:");
- Trace.WriteLine(ex.Message);
- Trace.WriteLine("Data string:");
- Trace.WriteLine(Encoding.UTF8.GetString(response));
+ Logger.ErrorException("Error mapping port. Data string: {0}", ex, Encoding.UTF8.GetString(response));
}
}
diff --git a/Mono.Nat/Upnp/Messages/GetServicesMessage.cs b/Mono.Nat/Upnp/Messages/GetServicesMessage.cs
index c5d7bce70..8cc0221be 100644
--- a/Mono.Nat/Upnp/Messages/GetServicesMessage.cs
+++ b/Mono.Nat/Upnp/Messages/GetServicesMessage.cs
@@ -27,6 +27,7 @@
using System;
using System.Diagnostics;
using System.Net;
+using MediaBrowser.Model.Logging;
namespace Mono.Nat.Upnp
{
@@ -34,18 +35,20 @@ namespace Mono.Nat.Upnp
{
private string servicesDescriptionUrl;
private EndPoint hostAddress;
+ private readonly ILogger _logger;
- public GetServicesMessage(string description, EndPoint hostAddress)
+ public GetServicesMessage(string description, EndPoint hostAddress, ILogger logger)
:base(null)
{
if (string.IsNullOrEmpty(description))
- Trace.WriteLine("Description is null");
+ _logger.Warn("Description is null");
if (hostAddress == null)
- Trace.WriteLine("hostaddress is null");
+ _logger.Warn("hostaddress is null");
this.servicesDescriptionUrl = description;
this.hostAddress = hostAddress;
+ _logger = logger;
}
diff --git a/Mono.Nat/Upnp/Searchers/UpnpSearcher.cs b/Mono.Nat/Upnp/Searchers/UpnpSearcher.cs
index edc5a5d76..3d9df012a 100644
--- a/Mono.Nat/Upnp/Searchers/UpnpSearcher.cs
+++ b/Mono.Nat/Upnp/Searchers/UpnpSearcher.cs
@@ -37,96 +37,27 @@ using System.Diagnostics;
using System.Net.Sockets;
using System.Net.NetworkInformation;
using MediaBrowser.Controller.Dlna;
+using MediaBrowser.Model.Logging;
namespace Mono.Nat
{
internal class UpnpSearcher : ISearcher
{
- private const int SearchPeriod = 5 * 60; // The time in seconds between each search
- static UpnpSearcher instance = new UpnpSearcher();
- public static List<UdpClient> sockets = CreateSockets();
-
- public static UpnpSearcher Instance
- {
- get { return instance; }
- }
-
public event EventHandler<DeviceEventArgs> DeviceFound;
public event EventHandler<DeviceEventArgs> DeviceLost;
- private List<INatDevice> devices;
- private Dictionary<IPAddress, DateTime> lastFetched;
private DateTime nextSearch;
- private IPEndPoint searchEndpoint;
+ private readonly ILogger _logger;
- UpnpSearcher()
+ public UpnpSearcher(ILogger logger)
{
- devices = new List<INatDevice>();
- lastFetched = new Dictionary<IPAddress, DateTime>();
- //searchEndpoint = new IPEndPoint(IPAddress.Parse("239.255.255.250"), 1900);
- searchEndpoint = new IPEndPoint(IPAddress.Parse("239.255.255.250"), 1900);
+ _logger = logger;
}
- static List<UdpClient> CreateSockets()
- {
- List<UdpClient> clients = new List<UdpClient>();
- try
- {
- foreach (NetworkInterface n in NetworkInterface.GetAllNetworkInterfaces())
- {
- foreach (UnicastIPAddressInformation address in n.GetIPProperties().UnicastAddresses)
- {
- if (address.Address.AddressFamily == AddressFamily.InterNetwork)
- {
- try
- {
- clients.Add(new UdpClient(new IPEndPoint(address.Address, 0)));
- }
- catch
- {
- continue; // Move on to the next address.
- }
- }
- }
- }
- }
- catch (Exception)
- {
- clients.Add(new UdpClient(0));
- }
- return clients;
- }
-
public void Search()
{
- foreach (UdpClient s in sockets)
- {
- try
- {
- Search(s);
- }
- catch
- {
- // Ignore any search errors
- }
- }
}
- void Search(UdpClient client)
- {
- nextSearch = DateTime.Now.AddSeconds(SearchPeriod);
- byte[] data = DiscoverDeviceMessage.EncodeSSDP();
-
- // UDP is unreliable, so send 3 requests at a time (per Upnp spec, sec 1.1.2)
- for (int i = 0; i < 3; i++)
- client.Send(data, data.Length, searchEndpoint);
- }
-
- public IPEndPoint SearchEndpoint
- {
- get { return searchEndpoint; }
- }
-
public void Handle(IPAddress localAddress, UpnpDeviceInfo deviceInfo, IPEndPoint endpoint)
{
// No matter what, this method should never throw an exception. If something goes wrong
@@ -145,113 +76,19 @@ namespace Mono.Nat
prefix. */
// We have an internet gateway device now
- UpnpNatDevice d = new UpnpNatDevice(localAddress, deviceInfo, endpoint, string.Empty);
+ UpnpNatDevice d = new UpnpNatDevice(localAddress, deviceInfo, endpoint, string.Empty, _logger);
- if (devices.Contains(d))
- {
- // We already have found this device, so we just refresh it to let people know it's
- // Still alive. If a device doesn't respond to a search, we dump it.
- devices[devices.IndexOf(d)].LastSeen = DateTime.Now;
- }
- else
- {
-
- // If we send 3 requests at a time, ensure we only fetch the services list once
- // even if three responses are received
- if (lastFetched.ContainsKey(endpoint.Address))
- {
- DateTime last = lastFetched[endpoint.Address];
- if ((DateTime.Now - last) < TimeSpan.FromSeconds(20))
- return;
- }
- lastFetched[endpoint.Address] = DateTime.Now;
-
- // Once we've parsed the information we need, we tell the device to retrieve it's service list
- // Once we successfully receive the service list, the callback provided will be invoked.
- NatUtility.Log("Fetching service list: {0}", d.HostEndPoint);
- d.GetServicesList(DeviceSetupComplete);
- }
+ NatUtility.Log("Fetching service list: {0}", d.HostEndPoint);
+ OnDeviceFound(new DeviceEventArgs(d));
}
catch (Exception ex)
{
- NatUtility.Log("Unhandled exception when trying to decode a device's response Send me the following data: ");
- NatUtility.Log("ErrorMessage:");
- NatUtility.Log(ex.Message);
+ _logger.ErrorException("Error decoding device response", ex);
}
}
public void Handle(IPAddress localAddress, byte[] response, IPEndPoint endpoint)
{
- // Convert it to a string for easy parsing
- string dataString = null;
-
- // No matter what, this method should never throw an exception. If something goes wrong
- // we should still be in a position to handle the next reply correctly.
- try {
- string urn;
- dataString = Encoding.UTF8.GetString(response);
-
- if (NatUtility.Verbose)
- NatUtility.Log("UPnP Response: {0}", dataString);
-
- /* For UPnP Port Mapping we need ot find either WANPPPConnection or WANIPConnection.
- Any other device type is no good to us for this purpose. See the IGP overview paper
- page 5 for an overview of device types and their hierarchy.
- http://upnp.org/specs/gw/UPnP-gw-InternetGatewayDevice-v1-Device.pdf */
-
- /* TODO: Currently we are assuming version 1 of the protocol. We should figure out which
- version it is and apply the correct URN. */
-
- /* Some routers don't correctly implement the version ID on the URN, so we only search for the type
- prefix. */
-
- string log = "UPnP Response: Router advertised a '{0}' service";
- StringComparison c = StringComparison.OrdinalIgnoreCase;
- if (dataString.IndexOf("urn:schemas-upnp-org:service:WANIPConnection:", c) != -1) {
- urn = "urn:schemas-upnp-org:service:WANIPConnection:1";
- NatUtility.Log(log, "urn:schemas-upnp-org:service:WANIPConnection:1");
- } else if (dataString.IndexOf("urn:schemas-upnp-org:service:WANPPPConnection:", c) != -1) {
- urn = "urn:schemas-upnp-org:service:WANPPPConnection:1";
- NatUtility.Log(log, "urn:schemas-upnp-org:service:WANPPPConnection:");
- } else
- return;
-
- // We have an internet gateway device now
- UpnpNatDevice d = new UpnpNatDevice(localAddress, dataString, urn);
-
- if (devices.Contains(d))
- {
- // We already have found this device, so we just refresh it to let people know it's
- // Still alive. If a device doesn't respond to a search, we dump it.
- devices[devices.IndexOf(d)].LastSeen = DateTime.Now;
- }
- else
- {
-
- // If we send 3 requests at a time, ensure we only fetch the services list once
- // even if three responses are received
- if (lastFetched.ContainsKey(endpoint.Address))
- {
- DateTime last = lastFetched[endpoint.Address];
- if ((DateTime.Now - last) < TimeSpan.FromSeconds(20))
- return;
- }
- lastFetched[endpoint.Address] = DateTime.Now;
-
- // Once we've parsed the information we need, we tell the device to retrieve it's service list
- // Once we successfully receive the service list, the callback provided will be invoked.
- NatUtility.Log("Fetching service list: {0}", d.HostEndPoint);
- d.GetServicesList(DeviceSetupComplete);
- }
- }
- catch (Exception ex)
- {
- Trace.WriteLine("Unhandled exception when trying to decode a device's response Send me the following data: ");
- Trace.WriteLine("ErrorMessage:");
- Trace.WriteLine(ex.Message);
- Trace.WriteLine("Data string:");
- Trace.WriteLine(dataString);
- }
}
public DateTime NextSearch
@@ -259,20 +96,6 @@ namespace Mono.Nat
get { return nextSearch; }
}
- private void DeviceSetupComplete(INatDevice device)
- {
- lock (this.devices)
- {
- // We don't want the same device in there twice
- if (devices.Contains(device))
- return;
-
- devices.Add(device);
- }
-
- OnDeviceFound(new DeviceEventArgs(device));
- }
-
private void OnDeviceFound(DeviceEventArgs args)
{
if (DeviceFound != null)
diff --git a/Mono.Nat/Upnp/Upnp.cs b/Mono.Nat/Upnp/Upnp.cs
index e44a51c24..75e2ade8b 100644
--- a/Mono.Nat/Upnp/Upnp.cs
+++ b/Mono.Nat/Upnp/Upnp.cs
@@ -33,11 +33,19 @@ using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
+using MediaBrowser.Model.Logging;
namespace Mono.Nat.Upnp
{
internal class Upnp
{
+ protected readonly ILogger Logger;
+
+ public Upnp(ILogger logger)
+ {
+ Logger = logger;
+ }
+
public UpnpNatDevice Handle(IPAddress localAddress, byte[] response, IPEndPoint endpoint)
{
// Convert it to a string for easy parsing
@@ -77,7 +85,7 @@ namespace Mono.Nat.Upnp
throw new NotSupportedException("Received non-supported device type");
// We have an internet gateway device now
- return new UpnpNatDevice(localAddress, dataString, urn);
+ return new UpnpNatDevice(localAddress, dataString, urn, Logger);
}
}
}
diff --git a/Mono.Nat/Upnp/UpnpNatDevice.cs b/Mono.Nat/Upnp/UpnpNatDevice.cs
index 1160d3ac2..b7d779994 100644
--- a/Mono.Nat/Upnp/UpnpNatDevice.cs
+++ b/Mono.Nat/Upnp/UpnpNatDevice.cs
@@ -33,6 +33,7 @@ using System.Xml;
using System.Text;
using System.Diagnostics;
using MediaBrowser.Controller.Dlna;
+using MediaBrowser.Model.Logging;
namespace Mono.Nat.Upnp
{
@@ -43,8 +44,9 @@ namespace Mono.Nat.Upnp
private string serviceDescriptionUrl;
private string controlUrl;
private string serviceType;
+ private readonly ILogger _logger;
- public override IPAddress LocalAddress
+ public override IPAddress LocalAddress
{
get { return localAddress; }
}
@@ -54,7 +56,7 @@ namespace Mono.Nat.Upnp
/// </summary>
private NatDeviceCallback callback;
- internal UpnpNatDevice(IPAddress localAddress, UpnpDeviceInfo deviceInfo, IPEndPoint hostEndPoint, string serviceType)
+ internal UpnpNatDevice(IPAddress localAddress, UpnpDeviceInfo deviceInfo, IPEndPoint hostEndPoint, string serviceType, ILogger logger)
{
this.LastSeen = DateTime.Now;
this.localAddress = localAddress;
@@ -62,6 +64,7 @@ namespace Mono.Nat.Upnp
// Split the string at the "location" section so i can extract the ipaddress and service description url
string locationDetails = deviceInfo.Location.ToString();
this.serviceType = serviceType;
+ _logger = logger;
// Make sure we have no excess whitespace
locationDetails = locationDetails.Trim();
@@ -88,16 +91,17 @@ namespace Mono.Nat.Upnp
}
}
- internal UpnpNatDevice (IPAddress localAddress, string deviceDetails, string serviceType)
+ internal UpnpNatDevice (IPAddress localAddress, string deviceDetails, string serviceType, ILogger logger)
{
- this.LastSeen = DateTime.Now;
+ _logger = logger;
+ this.LastSeen = DateTime.Now;
this.localAddress = localAddress;
// Split the string at the "location" section so i can extract the ipaddress and service description url
string locationDetails = deviceDetails.Substring(deviceDetails.IndexOf("Location", StringComparison.InvariantCultureIgnoreCase) + 9).Split('\r')[0];
this.serviceType = serviceType;
- // Make sure we have no excess whitespace
+ // Make sure we have no excess whitespace
locationDetails = locationDetails.Trim();
// FIXME: Is this reliable enough. What if we get a hostname as opposed to a proper http address
@@ -131,8 +135,7 @@ namespace Mono.Nat.Upnp
}
else
{
- Trace.WriteLine("Couldn't decode address. Please send following string to the developer: ");
- Trace.WriteLine(deviceDetails);
+ logger.Warn("Couldn't decode address: " + deviceDetails);
}
}
@@ -527,7 +530,7 @@ namespace Mono.Nat.Upnp
// Create a HTTPWebRequest to download the list of services the device offers
byte[] body;
- WebRequest request = new GetServicesMessage(this.serviceDescriptionUrl, this.hostEndPoint).Encode(out body);
+ WebRequest request = new GetServicesMessage(this.serviceDescriptionUrl, this.hostEndPoint, _logger).Encode(out body);
if (body.Length > 0)
NatUtility.Log("Error: Services Message contained a body");
request.BeginGetResponse(this.ServicesReceived, request);