Example #1
0
        public override NatDevice AnalyseReceivedResponse(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
            {
                dataString = Encoding.UTF8.GetString(response);
                DiscoveryResponseMessage message = new DiscoveryResponseMessage(dataString);
                string serviceType = message["ST"];

                if (!IsValidControllerService(serviceType))
                {
                    NatDiscoverer.TraceSource.LogWarn("Invalid controller service. Ignoring.");

                    return(null);
                }
                NatDiscoverer.TraceSource.LogInfo("UPnP Response: Router advertised a '{0}' service!!!", serviceType);

                string location    = message["Location"] ?? message["AL"];
                Uri    locationUri = new Uri(location);
                NatDiscoverer.TraceSource.LogInfo("Found device at: {0}", locationUri.ToString());

                if (_devices.ContainsKey(locationUri))
                {
                    NatDiscoverer.TraceSource.LogInfo("Already found - Ignored");
                    _devices[locationUri].Touch();
                    return(null);
                }

                // 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(null);
                    }
                }
                _lastFetched[endpoint.Address] = DateTime.Now;

                NatDiscoverer.TraceSource.LogInfo("{0}:{1}: Fetching service list", locationUri.Host, locationUri.Port);

                UpnpNatDeviceInfo deviceInfo = BuildUpnpNatDeviceInfo(localAddress, locationUri);

                UpnpNatDevice device;
                lock (_devices)
                {
                    device = new UpnpNatDevice(deviceInfo);
                    if (!_devices.ContainsKey(locationUri))
                    {
                        _devices.Add(locationUri, device);
                    }
                }
                return(device);
            }
            catch (Exception ex)
            {
                NatDiscoverer.TraceSource.LogError("Unhandled exception when trying to decode a device's response. ");
                NatDiscoverer.TraceSource.LogError("Report the issue in https://github.com/lontivero/LiteNetLib4Mirror.Open.Nat/issues");
                NatDiscoverer.TraceSource.LogError("Also copy and paste the following info:");
                NatDiscoverer.TraceSource.LogError("-- beging ---------------------------------");
                NatDiscoverer.TraceSource.LogError(ex.Message);
                NatDiscoverer.TraceSource.LogError("Data string:");
                NatDiscoverer.TraceSource.LogError(dataString ?? "No data available");
                NatDiscoverer.TraceSource.LogError("-- end ------------------------------------");
            }
            return(null);
        }
 internal UpnpNatDevice(UpnpNatDeviceInfo deviceInfo)
 {
     Touch();
     DeviceInfo  = deviceInfo;
     _soapClient = new SoapClient(DeviceInfo.ServiceControlUri, DeviceInfo.ServiceType);
 }