-
Notifications
You must be signed in to change notification settings - Fork 18.1k
crypto/tls: (*tls.Conn).Read() can return (0, nil) #5309
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
Labels
Milestone
Comments
I've attached a tcpdump of the connection. Attachments:
|
This is actually reproducible using a trivial testcase (although again with Freenode on the other end). http://play.golang.org/p/FWTWmjs3uc package main import ( "crypto/tls" "fmt" "io" ) func main() { conn, err := tls.Dial("tcp", "chat.freenode.net:6697", nil) if err != nil { fmt.Println(err) return } io.WriteString(conn, "NICK :goirc") io.WriteString(conn, "USER goirc 8 * :goirc") buf := make([]byte, 4096) for { n, err := conn.Read(buf) fmt.Println(n, err) if err == nil { fmt.Println(string(buf[:n])) } else { break } } } |
So far it appears that this requires cipher 0x0035 (TLS_RSA_WITH_AES_256_CBC_SHA) to reproduce, which is what Freenode is picking. If I force a different cipher, the problem goes away. I wrote a sample program which runs both ends of the connection. If I run it with the default ciphers everything is fine, but if I run it with TLS_RSA_WITH_AES_256_CBC_SHA, then each written line gets split into 2 pieces on the receiving end, with the first piece containing 1 byte and the second piece containing the rest of the message. I have to wonder if maybe longer writes end up starting with a 0-byte piece (or, alternatively, Freenode's implementation of the cipher produces a 0-byte piece instead of 1-byte piece). The program is up at http://play.golang.org/p/zMD0fQokCi (requires a server cert/key). |
Issue #5300 has been merged into this issue. |
Issue #5300 has been merged into this issue. |
Sorry for cross post. Now I quote my question from issue #5300: > Thank you. > > So what's the suggest action to this problem? Should I enclose the read within a loop? Or tls package will make some changes to follow the normal read behavior? |
Per http://tip.golang.org/pkg/io/#Reader, "Implementations of Read are discouraged from returning a zero byte count with a nil error, and callers should treat that situation as a no-op." This bug should be about crypto/tls not returning (0, nil), but your code should still handle it just in case, since we haven't always had that io.Reader warning, and you can't expect all Readers to conform. Status changed to Accepted. |
Adam fixed this in May but got the "fixes" syntax wrong. https://golang.org/cl/8852044 Status changed to Fixed. |
This issue was closed.
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
by kballard:
The text was updated successfully, but these errors were encountered: