/// <summary> Close down jmdns. Release all resources and unregister all services.</summary> public virtual async Task Close() { if (state != DNSState.CANCELED) { Task t = CloseMulticastSocket(); lock (this) { // Synchronize only if we are not already in process to prevent dead locks // Stop JmDNS state = DNSState.CANCELED; // This protects against recursive calls UnregisterAllServices(); DisposeServiceCollectors(); // close socket // Stop the timer // TODO: how to replace this? //timer.cancel(); // remove the shutdown hook if (shutdown != null) { // TODO: need to replace this?? //Process.GetCurrentProcess().removeShutdownHook(shutdown.Instance); } } await t; } }
/// <summary> Sets the state and notifies all objects that wait on JmDNS.</summary> internal virtual void Cancel() { lock (this) { state = DNSState.CANCELED; Monitor.PulseAll(this); } }
/// <summary> Sets the state and notifies all objects that wait on JmDNS.</summary> internal virtual void RevertState() { lock (this) { state = state.Revert(); Monitor.PulseAll(this); } }
// State machine /// <summary> Sets the state and notifies all objects that wait on JmDNS.</summary> internal virtual void AdvanceState() { lock (this) { state = state.Advance(); Monitor.PulseAll(this); } }
private void Start(ICollection serviceInfos) { state = DNSState.PROBING_1; incomingListener.Start(); new Prober(this).start(); foreach (ServiceInfo info in serviceInfos) { try { RegisterService(new ServiceInfo(info)); } catch (Exception exception) { logger.Warn("start() Registration exception ", exception); } } }
/// <summary> Recover jmdns when there is an error.</summary> protected internal virtual void Recover() { logger.Debug("recover()"); // We have an IO error so lets try to recover if anything happens lets close it. // This should cover the case of the IP address changing under our feet if (DNSState.CANCELED != state) { lock (this) { // Synchronize only if we are not already in process to prevent dead locks // logger.Debug("recover() Cleanning up"); // Stop JmDNS state = DNSState.CANCELED; // This protects against recursive calls // We need to keep a copy for reregistration ICollection oldServiceInfos = new ArrayList(services.Values); // Cancel all services UnregisterAllServices(); DisposeServiceCollectors(); // // close multicast socket CloseMulticastSocket(); // cache.clear(); logger.Debug("recover() All is clean"); // // All is clear now start the services // try { OpenMulticastSocket(localHost, ipv6); Start(oldServiceInfos); } catch (Exception exception) { logger.Warn("recover() Start services exception ", exception); } logger.Warn("recover() We are back!"); } } }
public void Run(object state) { DNSOutgoing out_Renamed = null; try { // send probes for JmDNS itself if (Enclosing_Instance.State == taskState) { if (out_Renamed == null) { out_Renamed = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA); } DNSRecord answer = Enclosing_Instance.localHost.DNS4AddressRecord; if (answer != null) { out_Renamed.AddAnswer(answer, 0); } answer = Enclosing_Instance.localHost.DNS6AddressRecord; if (answer != null) { out_Renamed.AddAnswer(answer, 0); } Enclosing_Instance.AdvanceState(); } // send announces for services // Defensively copy the services into a local list, // to prevent race conditions with methods registerService // and unregisterService. IList list; lock (Enclosing_Instance) { list = new ArrayList(Enclosing_Instance.services.Values); } foreach (ServiceInfo info in list) { lock (info) { if (info.State == taskState && info.task == this) { info.AdvanceState(); logger.Debug("run() JmDNS announcing " + info.QualifiedName + " state " + info.State); if (out_Renamed == null) { out_Renamed = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA); } out_Renamed.AddAnswer(new Pointer(info.type, DNSConstants.TYPE_PTR, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, info.QualifiedName), 0); out_Renamed.AddAnswer(new Service(info.QualifiedName, DNSConstants.TYPE_SRV, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, info.priority, info.weight, info.port, Enclosing_Instance.localHost.Name), 0); out_Renamed.AddAnswer(new Text(info.QualifiedName, DNSConstants.TYPE_TXT, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, info.text), 0); } } } if (out_Renamed != null) { logger.Debug("run() JmDNS announcing #" + taskState); Enclosing_Instance.Send(out_Renamed); } else { // If we have nothing to send, another timer taskState ahead // of us has done the job for us. We can cancel. cancel(); } } catch (Exception e) { logger.Warn("run() exception ", e); Enclosing_Instance.Recover(); } taskState = taskState.Advance(); if (!taskState.Announcing) { cancel(); new Renewer(enclosingInstance).start(); } }
public void Run(object state) { DNSOutgoing out_Renamed = null; try { // send probes for JmDNS itself if (Enclosing_Instance.State == taskState) { if (out_Renamed == null) { out_Renamed = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA); } DNSRecord answer = Enclosing_Instance.localHost.DNS4AddressRecord; if (answer != null) out_Renamed.AddAnswer(answer, 0); answer = Enclosing_Instance.localHost.DNS6AddressRecord; if (answer != null) out_Renamed.AddAnswer(answer, 0); Enclosing_Instance.AdvanceState(); } // send announces for services // Defensively copy the services into a local list, // to prevent race conditions with methods registerService // and unregisterService. IList list; lock (Enclosing_Instance) { list = new ArrayList(Enclosing_Instance.services.Values); } foreach (ServiceInfo info in list) { lock (info) { if (info.State == taskState && info.task == this) { info.AdvanceState(); logger.Debug("run() JmDNS announced " + info.QualifiedName + " state " + info.State); if (out_Renamed == null) { out_Renamed = new DNSOutgoing(DNSConstants.FLAGS_QR_RESPONSE | DNSConstants.FLAGS_AA); } out_Renamed.AddAnswer(new Pointer(info.type, DNSConstants.TYPE_PTR, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, info.QualifiedName), 0); out_Renamed.AddAnswer(new Service(info.QualifiedName, DNSConstants.TYPE_SRV, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, info.priority, info.weight, info.port, Enclosing_Instance.localHost.Name), 0); out_Renamed.AddAnswer(new Text(info.QualifiedName, DNSConstants.TYPE_TXT, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, info.text), 0); } } } if (out_Renamed != null) { logger.Debug("run() JmDNS announced"); Enclosing_Instance.Send(out_Renamed); } else { // If we have nothing to send, another timer taskState ahead // of us has done the job for us. We can cancel. cancel(); } } catch (Exception e) { logger.Warn("run() exception ", e); Enclosing_Instance.Recover(); } taskState = taskState.Advance(); if (!taskState.Announced) { cancel(); } }
public void Run(object state) { lock (Enclosing_Instance.IOLock) { DNSOutgoing out_Renamed = null; try { // send probes for JmDNS itself if (Enclosing_Instance.State == taskState && Enclosing_Instance.Task == this) { if (out_Renamed == null) { out_Renamed = new DNSOutgoing(DNSConstants.FLAGS_QR_QUERY); } out_Renamed.AddQuestion(new DNSQuestion(Enclosing_Instance.localHost.Name, DNSConstants.TYPE_ANY, DNSConstants.CLASS_IN)); DNSRecord answer = Enclosing_Instance.localHost.DNS4AddressRecord; if (answer != null) out_Renamed.AddAuthorativeAnswer(answer); answer = Enclosing_Instance.localHost.DNS6AddressRecord; if (answer != null) out_Renamed.AddAuthorativeAnswer(answer); Enclosing_Instance.AdvanceState(); } // send probes for services // Defensively copy the services into a local list, // to prevent race conditions with methods registerService // and unregisterService. IList list; lock (Enclosing_Instance) { list = new ArrayList(Enclosing_Instance.services.Values); } foreach (ServiceInfo info in list) { lock (info) { if (info.State == taskState && info.task == this) { info.AdvanceState(); logger.Info("run() JmDNS probing " + info.QualifiedName + " state " + info.State); if (out_Renamed == null) { out_Renamed = new DNSOutgoing(DNSConstants.FLAGS_QR_QUERY); out_Renamed.AddQuestion(new DNSQuestion(info.QualifiedName, DNSConstants.TYPE_ANY, DNSConstants.CLASS_IN)); } out_Renamed.AddAuthorativeAnswer(new Service(info.QualifiedName, DNSConstants.TYPE_SRV, DNSConstants.CLASS_IN, DNSConstants.DNS_TTL, info.priority, info.weight, info.port, info.server)); } } } if (out_Renamed != null) { logger.Debug("run() JmDNS probing #" + taskState); Enclosing_Instance.Send(out_Renamed); } else { // If we have nothing to send, another timer taskState ahead // of us has done the job for us. We can cancel. cancel(); return ; } } catch (Exception e) { logger.Warn("run() exception ", e); Enclosing_Instance.Recover(); } taskState = taskState.Advance(); if (!taskState.Probing) { cancel(); new Announcer(enclosingInstance).start(); } } }