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

fix: immediately rebind after WSAECONNRESET #59

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion net/neterror/neterror.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@ func TreatAsLostUDP(err error) bool {
return false
}

var packetWasTruncated func(error) bool // non-nil on Windows at least
var (
packetWasTruncated func(error) bool // non-nil on Windows at least
socketWasReset func(error) bool // non-nil on Windows at least
)

// PacketWasTruncated reports whether err indicates truncation but the RecvFrom
// that generated err was otherwise successful. On Windows, Go's UDP RecvFrom
Expand All @@ -59,6 +62,17 @@ func PacketWasTruncated(err error) bool {
return packetWasTruncated(err)
}

// SocketWasReset reports whether err is an error from a TCP or UDP send/recv
// operation that should be treated as a connection reset. On Windows,
// WSARecvFrom can return WSAECONNRESET when the remote side sends an ICMP error
// message.
func SocketWasReset(err error) bool {
if socketWasReset == nil {
return false
}
return socketWasReset(err)
}

var shouldDisableUDPGSO func(error) bool // non-nil on Linux

func ShouldDisableUDPGSO(err error) bool {
Expand Down
4 changes: 4 additions & 0 deletions net/neterror/neterror_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,8 @@ func init() {
packetWasTruncated = func(err error) bool {
return errors.Is(err, windows.WSAEMSGSIZE)
}

socketWasReset = func(err error) bool {
return errors.Is(err, windows.WSAECONNRESET)
}
}
6 changes: 6 additions & 0 deletions wgengine/magicsock/magicsock.go
Original file line number Diff line number Diff line change
Expand Up @@ -1236,6 +1236,12 @@ func (c *Conn) mkReceiveFunc(ruc *RebindingUDPConn, healthItem *health.ReceiveFu
if neterror.PacketWasTruncated(err) {
continue
}
if neterror.SocketWasReset(err) {
c.logf("magicsock: receive: rebind required due to socket reset: %v", err)
c.Rebind()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docs for Rebind() say that we need to call ReSTUN() after rebinding.

c.ReSTUN("socket-reset")
}

return 0, err
}

Expand Down
Loading