/// <summary> /// Triggered when a SSDP search result is received /// </summary> private void UPnPControlPointSearchSink(IPEndPoint source, IPEndPoint local, Uri LocationURL, String USN, String SearchTarget, int MaxAge) { // A bit like getting a SSDP notification, but we don't do automatic // source change in this case. The only valid scenario of a search // result is device creation. lock (deviceTableLock) { if (deviceTable.ContainsKey(USN) == false) { // Never saw this device before DeviceInfo deviceInfo = new DeviceInfo(); deviceInfo.Device = null; deviceInfo.UDN = USN; deviceInfo.NotifyTime = DateTime.Now; deviceInfo.BaseURL = LocationURL; deviceInfo.MaxAge = MaxAge; deviceInfo.LocalEP = local; deviceInfo.SourceEP = source; deviceTable[USN] = deviceInfo; deviceFactory.CreateDevice(deviceInfo.BaseURL, deviceInfo.MaxAge, local.Address, USN); } else { DeviceInfo deviceInfo = (DeviceInfo)deviceTable[USN]; if (deviceInfo.Device != null) // If the device is in creation mode, do nothing { if (deviceInfo.BaseURL.Equals(LocationURL)) { // Cancel a possible source change deviceUpdateClock.Remove(deviceInfo); deviceInfo.PendingBaseURL = null; deviceInfo.PendingMaxAge = 0; deviceInfo.PendingLocalEP = null; deviceInfo.PendingSourceEP = null; // Then simply update the lifetime deviceInfo.NotifyTime = DateTime.Now; deviceTable[USN] = deviceInfo; deviceLifeTimeClock.Add(deviceInfo.UDN, MaxAge); } else { // Wow, same device, different source - Check timing if (deviceInfo.NotifyTime.AddSeconds(10).Ticks < DateTime.Now.Ticks) { // This is a possible source change. Wait for 3 seconds and make the switch. deviceInfo.PendingBaseURL = LocationURL; deviceInfo.PendingMaxAge = MaxAge; deviceInfo.PendingLocalEP = local; deviceInfo.PendingSourceEP = source; deviceUpdateClock.Add(deviceInfo.UDN, 3); } } } } } }
public void Rescan() { ArrayList l; // We have to copy the list of keys here because we have reports of the hashtable being changed even when the lock is applied; lock (deviceTableLock) { l = new ArrayList(deviceTable.Keys); } foreach (string USN in l) { deviceLifeTimeClock.Add(USN, 20); } genericControlPoint.FindDeviceAsync("upnp:rootdevice"); }
/// <summary> /// Instantiates a new Monitor /// </summary> /// <param name="onNewInterfaceSink">Interface Callback</param> public NetworkInfo(InterfaceHandler onNewInterfaceSink) { //OpenSource.Utilities.InstanceTracker.Add(this); InterfacePoller.OnExpired += new LifeTimeMonitor.LifeTimeHandler(PollInterface); NetworkInterface[] interfaces = NetworkInterface.GetAllNetworkInterfaces(); foreach (NetworkInterface i in interfaces) { #if NETSTANDARD if (/*i.IsReceiveOnly == false &&*/ i.OperationalStatus == OperationalStatus.Up && i.SupportsMulticast == true) #else if (i.IsReceiveOnly == false && i.OperationalStatus == OperationalStatus.Up && i.SupportsMulticast == true) #endif { IPInterfaceProperties i2 = i.GetIPProperties(); foreach (UnicastIPAddressInformation i3 in i2.UnicastAddresses) { if (!AddressTable.Contains(i3.Address) && !i3.Address.Equals(IPAddress.IPv6Loopback)) { AddressTable.Add(i3.Address); } } } } /* * HostName = Dns.GetHostName(); * IPHostEntry HostInfo = Dns.GetHostEntry(HostName); * AddressTable = new ArrayList(HostInfo.AddressList); */ if (!AddressTable.Contains(IPAddress.Loopback)) { AddressTable.Add(IPAddress.Loopback); } if (onNewInterfaceSink != null) { OnNewInterface += onNewInterfaceSink; foreach (IPAddress address in AddressTable) { OnNewInterfaceEvent.Fire(this, address); } } InterfacePoller.Add(this, NetworkInfo.NetworkPollSeconds); }
/// <summary> /// Creates a device from a URL. [Depracated] use UPnPDeviceFactory /// </summary> /// <param name="DescriptionURL"></param> /// <param name="LifeTime"></param> public void CreateDeviceAsync(Uri DescriptionURL, int LifeTime) { //ToDo: Replace the failed callback UPnPDeviceFactory fac = new UPnPDeviceFactory(DescriptionURL, LifeTime, new UPnPDeviceFactory.UPnPDeviceHandler(HandleDeviceCreation), null, null, null); CreateTable[fac] = fac; Lifetime.Add(fac, 30); }
/// <summary> /// Instantiates a new MiniWebServer listenting on the given EndPoint /// </summary> /// <param name="local">IPEndPoint to listen on</param> public MiniWebServer(IPEndPoint local) { OpenSource.Utilities.InstanceTracker.Add(this); SessionTimer.OnExpired += new LifeTimeMonitor.LifeTimeHandler(SessionTimerSink); KeepAliveTimer.OnExpired += new LifeTimeMonitor.LifeTimeHandler(KeepAliveSink); endpoint_local = local; MainSocket = new Socket(local.AddressFamily, SocketType.Stream, ProtocolType.Tcp); MainSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1); MainSocket.Bind(local); if (MainSocket.LocalEndPoint != null) { endpoint_local = (IPEndPoint)MainSocket.LocalEndPoint; } MainSocket.Listen(25); MainSocket.BeginAccept(new AsyncCallback(Accept), null); KeepAliveTimer.Add(false, 7); }
private void HeaderSink(HTTPSession sender, HTTPMessage header, Stream TheStream) { _Source = sender.Source; StateData sd = null; if (TheStream != null) { // This is the result of post-headers in a chunked document sd = (StateData)sender.StateObject; object Tag = sd.Tag; if (sd.HeaderCB != null) { sd.HeaderCB(this, sender, header, TheStream, Tag); } sender.StateObject = null; KeepAliveTimer.Add(this.GetHashCode(), 10); } else { lock (TagQueue) { sd = (StateData)TagQueue.Dequeue(); } sender.StateObject = sd; object Tag = sd.Tag; if (sd.HeaderCB != null) { sd.HeaderCB(this, sender, header, TheStream, Tag); if (sender.UserStream != null && !sender.IsChunked) { // If I don't set this to null, this holds a strong reference, resulting in // possible memory leaks sender.StateObject = null; } } } }
private void Accept(IAsyncResult result) { HTTPSession WebSession = null; try { Socket AcceptedSocket = MainSocket.EndAccept(result); lock (SessionTable) { WebSession = new HTTPSession(this.LocalIPEndPoint, AcceptedSocket); WebSession.OnClosed += new HTTPSession.SessionHandler(CloseSink); WebSession.OnHeader += new HTTPSession.ReceiveHeaderHandler(HandleHeader); WebSession.OnReceive += new HTTPSession.ReceiveHandler(HandleRequest); SessionTable[WebSession] = WebSession; } SessionTimer.Add(WebSession, 3); OnSessionEvent.Fire(this, WebSession); WebSession.StartReading(); } catch (Exception err) { if (err.GetType() != typeof(System.ObjectDisposedException)) { // Error OpenSource.Utilities.EventLogger.Log(err); } } try { MainSocket.BeginAccept(new AsyncCallback(Accept), null); } catch (Exception ex) { OpenSource.Utilities.EventLogger.Log(ex); // Socket was closed } }
private void ProcessPacket(HTTPMessage msg, IPEndPoint src, IPEndPoint local) { if (OnSniffPacket != null) { OnSniffPacket(src, null, msg); } DText parser = new DText(); parser.ATTRMARK = "::"; bool Alive = false; String UDN = msg.GetTag("USN"); parser[0] = UDN; String USN = parser[1]; USN = USN.Substring(USN.IndexOf(":") + 1); String ST = parser[2]; int MaxAge = 0; String NTS = msg.GetTag("NTS").ToUpper(); if (NTS == "SSDP:ALIVE") { Alive = true; String ma = msg.GetTag("Cache-Control").Trim(); if (ma != "") { parser.ATTRMARK = ","; parser.MULTMARK = "="; parser[0] = ma; for (int i = 1; i <= parser.DCOUNT(); ++i) { if (parser[i, 1].Trim().ToUpper() == "MAX-AGE") { MaxAge = int.Parse(parser[i, 2].Trim()); break; } } } } if (msg.Directive == "NOTIFY" && OnNotify != null) { Uri locuri = null; string location = msg.GetTag("Location"); if (location != null && location.Length > 0) { try { locuri = new Uri(location); } catch (Exception ex) { OpenSource.Utilities.EventLogger.Log(ex); } } OnNotify(src, msg.LocalEndPoint, locuri, Alive, USN, ST, MaxAge, msg); } else if (msg.Directive == "M-SEARCH" && OnSearch != null) { if (ValidateSearchPacket(msg) == false) { return; } int MaxTimer = int.Parse(msg.GetTag("MX")); SearchStruct SearchData = new SearchStruct(); SearchData.ST = msg.GetTag("ST"); SearchData.Source = src; SearchData.Local = local; SearchTimer.Add(SearchData, RandomGenerator.Next(0, MaxTimer)); } }