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); }