Two findings from the “another day, another yak shaved” department:
1. MiniDNS can’t resolve CNAMEs
I have a test domain for IDNA and some other things, and apparently the network I’m in fails at SRV, so Smack4 is falling back to the direct hostname resolution instead:
_xmpp-client._tcp.ツ.op-co.de. 3585 IN SRV 5 0 5222 xmpp.op-co.de.
_xmpp-server._tcp.ツ.op-co.de. 3585 IN SRV 5 0 5269 xmpp.op-co.de.
ツ.op-co.de. 3585 IN CNAME op-co.de.
op-co.de. 2165 IN A 83.223.75.24
The resolver returns the last two lines (CNAME and IN/A), then Record.isAnswer() is called on each of those. First it checks the CNAME response, which is not accepted as an answer because CNAME is neither of A, AAAA or ANY. Then it checks the A response, which is not an accepted answer because the name doesn’t match:
Wait, how could it ever pass through the assert? Both lists are empty! That can’t ever happen! Except, you need to perform some badly documented black magic to make assert work (adb shell setprop debug.assert 1, but then the assert still will pass!?).
Please pretty please just replace it with a checked(!) exception already. Just because this is not allowed to happen doesn’t mean you can either silently ignore the condition or crash my whole application.
(1) A SRV RR pointing to a CNAME is invalid as per RFC 2782
Target
The domain name of the target host. There MUST be one or more address records for this name, the name MUST NOT be an alias (in the sense of RFC 1034 or RFC 2181).
(2) The asserts in this case check if the used components obey the API contract. In this case they apparently do not. I avoid performing those checks unconditionally.
If you have another look at my DNS paste, the SRV is not pointing to a CNAME. Those are different records. The CNAME is merely a fallback for clients that can’t do SRV lookup, for whatever reason. You can consider the SRV records as non-existent for the reproduction of this ticket. If you wish, I can even remove them for you to be able to reproduce the setup. Otherwise, feel free to manually set ツ.op-co.de:5222 as the host:port for a Smack connection.
The asserts in this case check if the used components obey the API contract. In this case they apparently do not. I avoid performing those checks unconditionally.
We’ve had this discussion back in 2014. Asserts haven’t become less harmfull since then. You are prematurely optimizing two integer comparisons at a huge cost to the debug-ability of your library.
The fact that the assert is silently passed despite being incorrent (and that I sunk another hour of my time into single-stepping this problem) is probably not enough to convince you anyway. Of the arguments that I made back in 2014, only #2 applies in this specific situation:
assert is the wrong tool for checking the validity of external inputs.
you will have inconsistent library behavior that is dependant on JRE runtime configuration
somebody will be able to profanity masked KILL YOUR APPLICATION by sending invalid XML
even by using assert() in a place where it does no harm you will create a bad example ready to be copied into places where it can do actual damage.
However, just a short grep for assert in the current code base made my eyes bleed (in XMPPTCPConnection):
Ahh right sorry. As you didn’t mention what the input for the resolve function is, I assumed it to be op-co.de. Yes CNAME chasing is not yet implemented in MiniDNS. See
If you know someone suitable and interested, then this could be a project for this years GSoC.