zeroconf
zeroconf copied to clipboard
What to do when only a TXT property changes in an mDNS record?
What does the mDNS spec say about publishing a mDNS record when only a TXT property has changed? Looking at the zeroconf code, I have to cancel the existing mDNS record before publishing a new one. I'm trying to find where this is defined in the spec - should I be able to re-publish the same service but with the modified TXT properties without cancelling the existing record? Thanks
After a bit of digging I think https://datatracker.ietf.org/doc/html/rfc6762#section-10.2 is the answer. That states when a record is invalidated, the "cache-flush" bit of the "rrclass" property should be set; that's the 16-bit "class" field. You'll see in the Record.java this as a constant value, 0x8001, so that bit it always set (the other set bit indicates the record is an "internet" class, see RFC 1035 for that)
So if you want to invalidate something you send a new record with that bit set, and the recipient must replace any existing record with the new one. I can't see any requirement to send a TTL=0 record before you cancel the old service - this is just a result of the API design.
I've taken a punt at a fix for this on the "reannounce" branch if you want to try it - there are two new methods in the Service class:
- boolean isMine() - returns true if this was created from the Builder, false if it was heard on the network
- boolean setText(Map<String,String> text) - for Services you've created (where isMine()==true), this method will update the text record, and if the service has been announced already will reannounce it.
Give it a test and let me know.
Awesome, thanks. Not sure when exactly I'll get to try it out, but it's to add a feature to our emulator that is sorely needed.
I just had to give it a go this morning!
Added code to my emulator:
if (!this.service.isMine()) {
return;
}
final Map<String, String> txt = this.buildTextProperties();
this.service.setText(txt);
But I always get this error:
Oct 31, 2025 6:31:24 A.M. com.bfo.zeroconf.Zeroconf log
SEVERE: ListenerThread exception
java.lang.IllegalStateException: Can't replace text on a record you didn't create
at com.bfo.zeroconf.Service.setText(Service.java:127)
at com.bfo.zeroconf.Zeroconf.processAnswer(Zeroconf.java:1127)
at com.bfo.zeroconf.Zeroconf.processAnswer(Zeroconf.java:1121)
at com.bfo.zeroconf.Zeroconf.processPacket(Zeroconf.java:833)
at com.bfo.zeroconf.Zeroconf$ListenerThread.run(Zeroconf.java:723)
Whoops. Pushed a fix, see if that helps.
Will do, thanks!
My first quick test is successful. I'll try more in depth testing later. Thanks.
I've only been able to do minimal testing, but so far it looks good. I don't think I'll be able to do more in-depth testing for a while.
I did some more testing and it works for me. So two thumbs up!