Skip to content
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

msg.Len() disagrees with Pack() #453

Closed
gpaul opened this issue Feb 13, 2017 · 13 comments
Closed

msg.Len() disagrees with Pack() #453

gpaul opened this issue Feb 13, 2017 · 13 comments

Comments

@gpaul
Copy link

gpaul commented Feb 13, 2017

Here's a test that fails:


func TestMsgCompressLength2(t *testing.T) {
	msg := new(Msg)
	msg.Compress = true
	msg.SetQuestion(Fqdn("_foo._tcp.bar."), TypeANY)
	msg.Answer = append(msg.Answer, &SRV{Hdr: RR_Header{Name: "_foo._tcp.bar.", Rrtype: 0x21, Class: 0x1, Ttl: 0x3c}, Port: 0x4c57, Target: "foo.bar."})
	msg.Answer = append(msg.Answer, &SRV{Hdr: RR_Header{Name: "_foo._tcp.bar.", Rrtype: 0x21, Class: 0x1, Ttl: 0x3c}, Port: 0x3307, Target: "foo.bar."})
	msg.Answer = append(msg.Answer, &SRV{Hdr: RR_Header{Name: "_foo._tcp.bar.", Rrtype: 0x21, Class: 0x1, Ttl: 0x3c}, Port: 0x35b0, Target: "foo.bar."})
	msg.Answer = append(msg.Answer, &SRV{Hdr: RR_Header{Name: "_foo._tcp.bar.", Rrtype: 0x21, Class: 0x1, Ttl: 0x3c}, Port: 0x5a7a, Target: "foo.bar."})
	msg.Answer = append(msg.Answer, &SRV{Hdr: RR_Header{Name: "_foo._tcp.bar.", Rrtype: 0x21, Class: 0x1, Ttl: 0x3c}, Port: 0x211a, Target: "foo.bar."})
	msg.Extra = append(msg.Extra, &A{Hdr: RR_Header{Name: "foo.bar.", Rrtype: 0x1, Class: 0x1, Ttl: 0x3c}, A: net.IP{0xac, 0x11, 0x0, 0x3}})
	msg.Extra = append(msg.Extra, &A{Hdr: RR_Header{Name: "foo.bar.", Rrtype: 0x1, Class: 0x1, Ttl: 0x3c}, A: net.IP{0xac, 0x11, 0x0, 0x3}})
	msg.Extra = append(msg.Extra, &A{Hdr: RR_Header{Name: "foo.bar.", Rrtype: 0x1, Class: 0x1, Ttl: 0x3c}, A: net.IP{0xac, 0x11, 0x0, 0x3}})
	msg.Extra = append(msg.Extra, &A{Hdr: RR_Header{Name: "foo.bar.", Rrtype: 0x1, Class: 0x1, Ttl: 0x3c}, A: net.IP{0xac, 0x11, 0x0, 0x3}})
	msg.Extra = append(msg.Extra, &A{Hdr: RR_Header{Name: "foo.bar.", Rrtype: 0x1, Class: 0x1, Ttl: 0x3c}, A: net.IP{0xac, 0x11, 0x0, 0x3}})
	predicted := msg.Len()
	buf, err := msg.Pack()
	if err != nil {
		t.Error(err)
	}
	if predicted != len(buf) {
		t.Errorf("predicted compressed length is wrong: predicted %s (len=%d) %d, actual %d",
			msg.Question[0].Name, len(msg.Answer), predicted, len(buf))
	}
}

Results in

=== RUN   TestMsgCompressLength2
--- FAIL: TestMsgCompressLength2 (0.00s)
	dns_test.go:215: predicted compressed length is wrong: predicted _foo._tcp.bar. (len=5) 246, actual 250

@miekg
Copy link
Owner

miekg commented Feb 13, 2017

Thanks for the test case.

This is tricky to get right as Len and Pack use 2 diff. algorithms, i.e. you don't want to Pack for every Len you do, and then throw away the buffer.

@gpaul
Copy link
Author

gpaul commented Feb 13, 2017

Totally, this is why I posted a test case and didn't submit a PR :)

@gpaul
Copy link
Author

gpaul commented Feb 13, 2017

Do you think you'll get around to this in the near future? If not I could have a look.

@miekg
Copy link
Owner

miekg commented Feb 14, 2017

This is the problem: https://github.com/miekg/dns/blob/master/msg.go#L994

Didn't want to use reflection at the time, but now that we "go gen" the packs and unpacks this needs to be generated as well. Although looking through the list, SRV is in there

@miekg
Copy link
Owner

miekg commented Feb 14, 2017

Can you make your example smaller?

@miekg
Copy link
Owner

miekg commented Feb 14, 2017

func TestMsgCompressLength2(t *testing.T) {
	msg := new(Msg)
	msg.Compress = true
	msg.SetQuestion(Fqdn("_foo._tcp.bar."), TypeANY)
	msg.Answer = append(msg.Answer, &SRV{Hdr: RR_Header{Name: "_foo._tcp.bar.", Rrtype: 0x21, Class: 0x1, Ttl: 0x3c}, Port: 0x4c57, Target: "foo.bar."})
	msg.Extra = append(msg.Extra, &A{Hdr: RR_Header{Name: "foo.bar.", Rrtype: 0x1, Class: 0x1, Ttl: 0x3c}, A: net.IP{0xac, 0x11, 0x0, 0x3}})
	predicted := msg.Len()
	buf, err := msg.Pack()
	if err != nil {
		t.Error(err)
	}
	if predicted != len(buf) {
		t.Errorf("predicted compressed length is wrong: predicted %s (len=%d) %d, actual %d",
			msg.Question[0].Name, len(msg.Answer), predicted, len(buf))
	}
}

shows the problem as well.

@miekg
Copy link
Owner

miekg commented Feb 14, 2017

compressionLenSearchType does not have SRV; i.e. yes we should gen these functions.

@miekg
Copy link
Owner

miekg commented Feb 14, 2017

This is prolly also: skynetservices/skydns#313

@miekg
Copy link
Owner

miekg commented Feb 14, 2017

#454 does not fix it, but is still good to have.

@miekg
Copy link
Owner

miekg commented Feb 14, 2017

Updated that PR which fixes the issue. Does that work/help you?

@gpaul
Copy link
Author

gpaul commented Feb 15, 2017

I'll have a look asap - thanks for the fast turn-around

@gpaul
Copy link
Author

gpaul commented Feb 15, 2017

I confirm that this PR fixes the issue for me.

@miekg
Copy link
Owner

miekg commented Feb 17, 2017

Fixed by #454

@miekg miekg closed this as completed Feb 17, 2017
pierresouchay added a commit to pierresouchay/consul that referenced this issue Mar 21, 2018
See hashicorp#3977

While trying to improve furthermore hashicorp#3948 (This pull request is still valid since we are not using Compression to compute the result anyway).

I saw a strange behaviour of dns library.
Basically, msg.Len() and len(msg.Pack()) disagree on Message len.

Thus, calculation of DNS response is false consul relies on msg.Len() instead of the result of Pack()

This is linked to miekg/dns#453 and a fix has been provided with miekg/dns#454

Would it be possible to upgrade miekg/dns to a more recent function ?

Consul might for instance upgrade to a post 1.0 release such as https://github.com/miekg/dns/releases/tag/v1.0.4
preetapan pushed a commit to hashicorp/consul that referenced this issue Mar 28, 2018
See #3977

While trying to improve furthermore #3948 (This pull request is still valid since we are not using Compression to compute the result anyway).

I saw a strange behaviour of dns library.
Basically, msg.Len() and len(msg.Pack()) disagree on Message len.

Thus, calculation of DNS response is false consul relies on msg.Len() instead of the result of Pack()

This is linked to miekg/dns#453 and a fix has been provided with miekg/dns#454

Would it be possible to upgrade miekg/dns to a more recent function ?

Consul might for instance upgrade to a post 1.0 release such as https://github.com/miekg/dns/releases/tag/v1.0.4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants