-
Notifications
You must be signed in to change notification settings - Fork 132
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
TLS connections hang after PR #86 #89
Comments
I think what's happening here is that the change from PR #86 has affected the |
I've never even debugged a Go application, believe it or not. :-) But, the debugger worked for me and luckily the code was pretty easy to track down. All of this is in On line 158 of Tracing into
|
I agree that a returned packet length of 16MB is pretty fishy. The
But, notice the error handling: if step 1 or 2 returns an error, the routine just does a |
Running through the debugger, notes:
From
... so the values are definitely funky. |
Ran the debug session again, pasted in the old loop into The loop in
So... is packet length 4 or 5 bytes? Or is there a different part of the header (maybe a protocol version or something) hidden in there? |
Finally, just in case this is useful, I created an Echo connection with a basic
The output is like this (byte sequences, each line is a
(it hung at the Not certain why there is an initial |
As another experiment, I ran a simple program with a socket connection followed by the TLS connection. The echo output suggests that the initial
If I then swallow that initial byte, it seems to work:
Is this something with TLS I need to deal with? I can't figure out where that little bit of noise is coming from... |
It sure looks to me like that leftover byte comes from the TLS handshake, and should have been consumed by the TLS library before it completed. I did some googling to see if there were any bugs reported against the golang TLS library that looked like this, but I came up empty. What version of go are you using? One approach would be to run tcpdump and observe the packets transferred during the TLS handshake. The last one would have to end in a byte with a value of 0x01, and that value would have to not be consumed by the TLS library. Another possibility would be a bug in libvirtd, but such a bug would probably affect non-TLS connections too, so that seems unlikely. Here's the documentation on the wire protocol libvirt uses: https://libvirt.org/internals/rpc.html. Hope this helps! |
I guess that's possible. But what confuses me is that prior to PR #86, everything works fine. However, I think my debugging might suggest the original code was buggy (instead of reading 4 bytes, that I don't think it's Libvirt, as
As far as libraries, I'm using Go 1.12. Current version is:
Originally, this was 1.12.6, but I updated based on the suggestion there may be a bug. Is there sample code somewhere that I can review for making a correct TLS connection? Maybe I've got something wonked, but I don't see it. |
I tried Wireshark and was able to capture the sequence. There are 3 packets, the initiating packet, this 0x01 packet and then the expected packet. Uncertain what specifically to capture, but this packet comes after the initiation packet to Libvirt (includes the
|
I've reproduced this with a go program that doesn't import go-libvirt. After the call to This is either a bug in libvirt, or a bug in the go TLS library. The old version of go-libvirt masked this bug - it accidentally ignored that odd 1-byte packet. I should have some more time to look at this tomorrow. |
Good to hear I'm not crazy! (Although it would be easier if I just had a bug in my code.) Let me know if you need me to test anything or look into something. |
It looks like @trapgate's investigation points to an upstream bug in libvirtd/tls. I'm going to close the issue as I don't think we should handle the problem here in |
@a2geek @benlemasurier @trapgate Gents, I face this issue recently. I use latest go 1.15.6 and Ubuntu 20.04.
Any chance to test other OSes like centos ? |
That older version of go-libvirt does avoid this particular bug, but it suffers from crashes when responses from libvirt are fragmented into multiple packets - that's the issue fixed by #86. I have no reason to believe that this bug is OS-dependent. The workaround to this problem would be to drain any packets that are received by the client after the |
@trapgate thanks a lot. per you suggestion, I add a line before
it works fine now |
This is not a bug, it is part of the libvirt RPC protocol when running over TLS.
And on the client side
Yes, we can argue this extra byte is pretty much redundant, but its there in the protocol for coming on for 15 years, so we can't remove it due to backcompat. A compliant client must read this single byte after TLS handshake is done and verify that it is the value 0x1. |
Uncertain exactly why this occurs, but between the 6/26 commit and 7/15 commit (PR #86) the TLS connectivity no longer works. Commit hashes are shown in the
go.mod
file below if that assists.Please let me know if I need to alter behavior of the code. For now, I'll lock into the 6/26 code.
My environment:
Bad run sample output (the hang lasts for hours - we left town today and it was still hanging when I returned):
Good run sample output:
go.mod
file:main.go
sample code (sorry, a bit long and hard-coded to locations on my filesystem):The text was updated successfully, but these errors were encountered: