Files
kubernetes/staging
Kubernetes Submit Queue 8787b13d75 Merge pull request #43922 from cezarsa/spdy-fix
Automatic merge from submit-queue

prevent corrupted spdy stream after hijacking connection

This PR fixes corner case in spdy stream code where some bytes would never arrive at the server.

Reading directly from a hijacked connection isn't safe because some data may have already been read by the server before `Hijack` was called. To ensure all data will be received it's safer to read from the returned `bufio.Reader`. This problem seem to happen more frequently when using Go 1.8.
This is described in https://golang.org/pkg/net/http/#Hijacker:

> // The returned bufio.Reader may contain unprocessed buffered
   // data from the client.

I came across this while debugging a flaky test that used code from the `k8s.io/apimachinery/pkg/util/httpstream/spdy` package. After filling the code with debug logs and long hours running the tests in loop in the hope of catching the error I finally caught something weird.

The first word on the first spdy frame [read by the server here](b625085230/vendor/github.com/docker/spdystream/spdy/read.go (L148)) had the value `0x03000100`. See, the first frame to arrive on the server was supposed to be a control frame indicating the creation of a new stream, but all control frames need the high-order bit set to 1, which was not the case here, so the saver mistakenly assumed this was a data frame and the stream would never be created. The correct value for the first word of a SYN_STREAM frame was supposed to be `0x80030001` and this lead me on the path of finding who had consumed the first 1 byte prior to the frame reader being called and finally finding the problem with the Hijack call.

I added a new test to try stressing this condition and ensuring that this bug doesn't happen anymore. However, it's quite ugly as it loops 1000 times creating streams on servers to increase the chances of this bug happening. So, I'm not sure whether it's worth it to keep this test or if I should remove it from the PR. Please let me know what you guys think and I'll be happy to update this.

Fixes #45093 #45089 #45078 #45075 #45072 #45066 #45023
2017-04-28 07:40:03 -07:00
..
2016-12-02 09:54:16 +08:00

This staging/src/k8s.io/client-go directory is the staging area of the client repo. It contains a versioned client, tools built around the client like the reflector, and all the client dependencies. The content will be periodically published to k8s.io/client-go repo. The staged content is copied from the main repo, i.e., k8s.io/kubernetes, with directory rearrangement and necessary rewritings. To sync the content with the latest code in your local k8s.io/kubernetes, you need to run godep restore in k8s root directory, then run staging/copy.sh. vendor/k8s.io/client-go is a symlink pointing to this staging area, so to use the packages in the staging area, you can import it as "vendor/client-go/", as if the client were vendored. The client will be vendored from k8s.io/client-go for real after the test matrix is converted to vendor k8s components.