mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-24 04:06:03 +00:00
Merge pull request #58520 from porridge/fix-connreset
Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Make IsConnectionReset work with more error implementations. **What this PR does / why we need it**: This fixes the code to correctly navigate error hierarchy, and actually work. **Which issue(s) this PR fixes** An improvement for #55860 **Special notes for your reviewer**: Integration-testing this code is somewhat hard. What I did to reproduce this condition reliably was: 1. use iptables to let the TCP handshake packets through but reject payload-carrying packets with: ``` sudo iptables -t raw -I PREROUTING -d localhost --protocol tcp --dport 443 -j NOTRACK sudo iptables -t filter -I INPUT -d localhost --protocol tcp --dport 443 -m string --algo bm --string http -j REJECT --reject-with tcp-reset ``` 2. start a dummy server with: `nc -l -4 localhost 443` 3. make the client issue a GET on localhost:443 Then I added instrumentation to the place in k8s.io/client-go/rest/request.go which calls this code, to discover the actual error hierarchy. I think another way to test this would be to run a dummy server which would listen() on a socket, accept() and then close() the incoming connection straight away. **Release note**: ```release-note Correctly handle transient connection reset errors on GET requests from client library. ```
This commit is contained in:
commit
c9c6901303
@ -18,6 +18,8 @@ package net
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/url"
|
||||
"os"
|
||||
"reflect"
|
||||
"syscall"
|
||||
)
|
||||
@ -38,8 +40,16 @@ func IPNetEqual(ipnet1, ipnet2 *net.IPNet) bool {
|
||||
|
||||
// Returns if the given err is "connection reset by peer" error.
|
||||
func IsConnectionReset(err error) bool {
|
||||
opErr, ok := err.(*net.OpError)
|
||||
if ok && opErr.Err.Error() == syscall.ECONNRESET.Error() {
|
||||
if urlErr, ok := err.(*url.Error); ok {
|
||||
err = urlErr.Err
|
||||
}
|
||||
if opErr, ok := err.(*net.OpError); ok {
|
||||
err = opErr.Err
|
||||
}
|
||||
if osErr, ok := err.(*os.SyscallError); ok {
|
||||
err = osErr.Err
|
||||
}
|
||||
if errno, ok := err.(syscall.Errno); ok && errno == syscall.ECONNRESET {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
Loading…
Reference in New Issue
Block a user