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
potential 2.0.0 incompatibility: message.from_wire() #480
Comments
I think the old behavior made more sense because there are use-cases where TC=1 answers need to be analyzed beyond "TC=1 is present". |
Which use cases are you thinking of? Also, if the authority has truncated in the bad way, e.g. in the middle of something, from_wire() would still be likely to raise an exception. More dangerous are the cases where the authority has created a partial RRset. Perhaps we should have a raise_on_truncation flag to from_wire() with a default of True, and possibly to dns.query.udp()? Then people who wanted to do extra processing of a TC message, could but the normal use case would be safer. I think in typical use cases, if we don't raise by default then people will probably forget to check TC and possibly get a partial RRset without knowing it. |
Use-cases: Integration and interoperability testing for DNS software:
New flag is fine with me, if you are okay with breaking API. Personally I consider this more invasive change than removing search list processing :-) |
Thinking about it a bit more, I think that for |
As #284 shows, it's not a simple thing if query.udp() "returns the message as it arrived" as from_wire of a TC'd message may itself cause exceptions, and if we let those exceptions escape it messes up the resolver and also prevents the caller from understanding the "truncatedness" of the response. I suppose we could have a "raise_on_truncated" default=False flag to dns.query.udp() and dns.message.from_wire(), and then have the resolver set it to True. That would be backwards compatible and still solve the problem for the resolver, but it's still really the wrong default for most uses. I considered making from_wire smarter, but this is hard as the code currently has no way to tell the difference between a FormError caused by truncation and one caused by other badness. It might be possible to fix that, but I'm not certain how hard it would be. I suppose if we adopt "you must ask for the Truncated" exception now, that leaves us room to get smarter in the future. |
Okay, now I can see the concern. The way how we handle this kind of mess in Knot DNS is that we parse header first and only if it seems "sensible enough" we continue parsing the rest. That might be one option how to handle TC bit in resolver code, but it might be too convoluted and we could stick to flag in from_wire() as you suggest. Again, I'm okay with making it incompatible change and going ahead with safe default, i.e. raise_on_truncated=True. I just wanted to highlight it so we can consciously decide we are okay with breaking this particular API. |
Oh wait, I have even better idea ;-) What about providing wrapper function, something like I've coded exactly this function several times already in various projects... and apparently #370 (comment) I'm not the only one who could use it. If we had this |
Just brainstorming here, but another thing we could do is put the partially parsed response into the truncated exception. Basically
This is still incompatible, but is safe and information rich, in that we are returning as much info as we could get from the message in the Truncated case. It also doesn't require any extra flags, which is nice. A slight drawback is that it doesn't differentiate between "we saw a proper FormError before we got to the part that was truncated" and "we saw a FormError due to truncation". I don't think that matters much as that's unlikely to happen and retry on TC in such a case is pretty harmless. |
Your wrapper idea could be convenient, but it doesn't change the inherent danger of partial RRsets in all the code that's doing dns.query.udp() and not checking TC or falling back to TCP. No idea how much code that is, but... |
Well, all the old code has the problem for years now and either dealt with it somehow or never saw truncated answer. For new code we can simply document "you should use udp_fallback_tcp unless you want to see partial answers", which is I believe sufficient. |
I meant to make a branch with proposed changes and submit a PR but I goofed with git and pushed it to master, so everyone can review it there. If we hate it, I will revert. |
Summarizing: Default behavior is same as before 1.16.0 I haven't changed the resolver to use udp_with_fallback yet |
TC handling now seems to work on acc5693. I'm going to close this and open a new issue for other incompatibilities. |
I will attempt to list incompatibilities found while testing master branch (to-be-2.0.0).
This does not mean it has to be fixed, but we should think about each on case-by-case basis.
The text was updated successfully, but these errors were encountered: