-
Notifications
You must be signed in to change notification settings - Fork 78
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Service Discovery goodbye message #47
Comments
Yes,
Are you interested in submitting a PR? |
On second thought, enhancing Perhaps a new method |
Well, maybe I got this wrong, but I thought that all is needed is to purge ServiceDiscovery.profiles and ServiceDiscovery.NameServer.Catalog collections of the service one wants to stop advertising or better yet first set them to TTL TimeSpan.Zero and then do the purge(?) |
Both of us are correct. I tend to use one When However, if you are using one Neither case will send So, this leads to two methods
|
Yeah, how you described possible solution at the end was how I was thinking about implementing it. I will try to cook something up but I will have to study/understand the inner workings of underlying Makaretu.DNS some more first. EDIT: |
Has there been any progress on this issue? |
I got busy with this in an attempt to exchange Apple's Bonjour by net-mdns. public void Unadvertise()
{
Message message = new Message();
foreach (KeyValuePair<string, Node> catEntry in NameServer.Catalog)
{
foreach(ResourceRecord resourceRecord in catEntry.Value.Resources)
{
resourceRecord.TTL = TimeSpan.Zero;
message.Answers.Add(resourceRecord);
}
}
this.Mdns.SendAnswer(message);
NameServer.Catalog.Clear();
} In Wireshark I can see that the previously announced services are 'answered' with a TTL of 0.
However, I assume I'm doing several things wrong here. For one thing the service 'z1' doesn't dissapear in my client (cache flush?), for another thing I'm not sure if I'm creating my unsolicited answers the right way. Any help is welcome. |
Thanks for spending your time on this!!! Your My reading of the spec indicates that the cache flush bit should NOT be set on a good-bye record. So the fault must be in "my client". Can you point me to the software. Also, has this software been tested to deal with TTL 0. Note that section 10.1 delays pruning by 1 second. |
I think that the good-bye record should NOT contain the |
Thanks for your support! The client application I'm using is Apple's own DNSServiceBrowser.NET (needs a running instance of Bonjour on your machine). It's been uploaded to github, too. DNSServiceBrowser.NET does successfully notice the removal of a service on goodbye (TTL 0). You're right, I wasn't too sure about purging all services like public void Unadvertise()
{
Message message = new Message();
foreach (ServiceProfile profile in this.profiles)
{
foreach(ResourceRecord resourceRecord in profile.Resources)
{
resourceRecord.TTL = TimeSpan.Zero;
message.Answers.Add(resourceRecord);
}
}
this.Mdns.SendAnswer(message.CreateResponse());
NameServer.Catalog.Clear();
} I'm using But now the actual answer-records are missing in the answer-packet (should unadvertise
Here's a valid/working goodbye-message, unadvertising the service
Is there a way I can create a response-message without loosing the answer-records? |
Ok, made some process. public void Unadvertise()
{
Message message = new Message().CreateResponse();//populate a response-msg with records.
foreach (ServiceProfile profile in this.profiles)
{
foreach (ResourceRecord resourceRecord in profile.Resources)
{
resourceRecord.TTL = TimeSpan.Zero;
message.Answers.Add(resourceRecord);
}
}
this.Mdns.SendAnswer(message);
NameServer.Catalog.Clear();
} Of course it made no sense to create a resonse-message after populating a different instance. So having records inside a response-message does work now. Trying to do some more investigation before writing to not spam the thread here (sorry). |
Great progress! the messsage documentation is in Makaretu.Dns https://richardschneider.github.io/net-dns/api/Makaretu.Dns.Message.html You want I suggest that you send one message per profile. Otherwise, the message length might be too big. |
No worries about spam. It's good to see how others are understanding the package. I just raised #57 |
Thanks a bunch for the encouragement! I got it solved in a very simplified temporary solution now. public void Unadvertise()
{
Message message = new Message { QR = true };//create a response message
foreach (ServiceProfile profile in this.profiles)
{
foreach (ResourceRecord resourceRecord in profile.Resources)
{
if (resourceRecord.Type == DnsType.SRV)//only consider announced Service-records
{
//Here's a dangerous hack: we strip 'instance' from 'instance._type._protocol._domain'
//This won't work as soon as a hostname is added, e.g. 'MyPC._instance._type._protocol._domain'
string name = resourceRecord.Name.Substring(resourceRecord.Name.IndexOf("._") + 1);
//At least for Bonjour the goodbye-message needs to be sent as a pointer.
PTRRecord pTRRecord = new PTRRecord { Name = name, DomainName = resourceRecord.Name };
pTRRecord.TTL = TimeSpan.Zero;
message.Answers.Add(pTRRecord);
}
}
}
this.Mdns.SendAnswer(message);
NameServer.Catalog.Clear();
} So, before I split this into And maybe I can find out how AVAHI behaves against this solution. It's also worth noting that pisker's solution does send goodbyes for Text, Pointer and Service. But all in all, that's how I got this working with a Bonjour client. Here's an accepted goodbye-record (coming from net-mdns this time ;) ):
|
Here are my thoughts on Unadvertise
The PTR to a service instance is
It would be nice if the PTR record is in the message Answers and the other resources are in the message AdditionalRecords, so that if the message length is too big the PTR record is guaranteed to be sent. Please make sure that the Bonjour client accepts this; the spec is unclear on this point, The last point on removing from Catalog, can be modifed. Since we are setting TTL to zero for all profile resources the NameServer will ignore them and eventually prune them. So just remove the service PTR record from the Catalog.
|
I think fully understand. I'll take care of this and come up with a patch or a new 'ServiceDiscovery.cs' asap. Regarding the removal from the NameServer: Are you saying I just have to remove the PTR by its service name instead of clearing the whole catalog? |
Ok, I've done the implementation as you suggested. Only sending a PTR per profile, adding the remaining records to the additional answers and only removing the PTR from the Nameserver by its QualifiedServiceName. However, I have a little issue with your suggestion on So I'd like to ask if you'd be okay with an architecture like this: /// <summary>
/// Sends a goodbye message for the provided
/// profile and removes its pointer from the name sever.
/// </summary>
/// <param name="profile">The profile to send a goodbye message for.</param>
/// <param name="message">An instance of <see cref="Makaretu.Dns.Message"/> to populate with goodbye-messages and to send them with.</param>
/// <param name="suppressAnswer">True if the goodbye messages should be prepared only, false to send them implicitly.</param>
public void UnadvertiseAsync(ServiceProfile profile, Message message, bool suppressAnswer = false)
{
PTRRecord pTRRecord = new PTRRecord { Name = profile.QualifiedServiceName, DomainName = profile.FullyQualifiedName };
pTRRecord.TTL = TimeSpan.Zero;
message.Answers.Add(pTRRecord);
profile.Resources.ForEach(resource => message.AdditionalRecords.Add(resource));
if (!suppressAnswer)
{
this.Mdns.SendAnswer(message);
}
NameServer.Catalog.TryRemove(profile.QualifiedServiceName, out Node _);
}
/// <summary>
/// Sends a goodbye message for each anounced service.
/// </summary>
public void Unadvertise()
{
Message message = new Message { QR = true };
foreach (ServiceProfile profile in this.profiles)
{
UnadvertiseAsync(profile, message);
}
this.Mdns.SendAnswer(message);
} |
Yes, I want one message per profile. We are now done with design issues and moving to implementation. So I suggest you now create a PR. +1 for XML comments!!! A few comments to speed things up
|
Raised #59 . Interesting thoughts on
But a consistent linting in an established project should be respected, of course. So I did the pull request with your preferred style. I'm not sure what you're suggesting with
If it's the lack of respective tests, I need some further advice on this. You were right about the TTL for the other resources and UnadvertiseAsync, I wasn't careful there. Fixed in the PR. *edit: typo on 'var' vs 'type name'. |
I'll create a new release, real soon, |
Hello,
looking at ServiceDiscovery.Advertise() method to announce new service I don't see any way how to deannounce announced service. Typical way of doing this is to send a type of "goodbye message" where the Time-To-Live property is set to zero so listeners can update theirs records and take these services out of the roster.
On the same line when disposing of ServiceDiscovery object, there is no clean up. So services will "appear" alive to the end ot TTL, which could be a while.
Theoretically I can do something dirty like this:
Hovewer then it will still stay in DNS server collection.
The text was updated successfully, but these errors were encountered: