-
Notifications
You must be signed in to change notification settings - Fork 1k
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
I use quic transmission,but sometimes quic will close all network connections. #519
Comments
Thanks for spotting this. This is a common bug around UDP use with Go on Windows. We should move this issue to either the QUIC transport wrapper, or report it directly to the Go QUIC implementation if the mistake is there. @marten-seemann can you assist? |
We had an issue for this in quic-go: quic-go/quic-go#1737. Being pretty inexperienced with Windows, I assumed that wsarecvfrom was some an error code of another library wrapped around quic-go, which is why I closed this issue without action, and unfortunately never got any response. I'm running all unit and some of the integration tests on AppVeyor on Windows, and everything seems to work fine there. I'll need some guidance in how to reproduce this issue. |
@djdv, any ideas? |
Disclaimer: I lack experience with UDP on Windows. Mostly familiar with TCP and Named Pipe connections. This appears to be I'm lacking context here though. During an accept or send, what's probably happening is that data was buffered, the remote host became unreachable, and the next read call errors. Whatever is wrapping these operations is then picking up on this and closing the socket. But I'm not sure the inner workings here or the dependency chain. With context from @anacrolix it looks like we can receive innocuous or potentially incorrect (library fault) errors from Read() that are probably tripping something to close the socket prematurely. In the linked torrent issue it seems appropriate to disregard the error entirely or adjust the buffers (depending on what error was actually received. My best guess is that if these errors aren't already exposed, we need to explode them out and switch on them using |
Yep, spot on.
I'd love to see how you solve that. It's difficult to pin down specific errors in Go due to the very loose typing inside the error interface. |
It's true. Go can make this pretty ugly if the libs don't export error variables for us. In this case it likely originates from Once we know the source and concrete type of the error, it's just a matter of unwrapping it. It's messy but likely necessary if the abstractions don't already provide a way to do something like err := ambiguousErr()
if netErr, ok := err.(net.OpError); ok {
if netErr.Temporary() {
// drop err; break|return
}
log.Errorf("Fatal net error: {%T}%#v", netErr.Err, netErr.Err)
}
log.Errorf("Unexpected/Unhandled error: {%T}%#v", err, err) Depending on the source of the error and the level of control needed, you could repeat the pattern to continue unwrapping. In the case of a ...
if netErr.Temporary() {
...
}
if platformErr, ok := netErr.Err.(syscall.Errno); ok {
if platformErr == SomeConst {
// drop err; break|return
}
} Edit: no more code changes 🤞 |
It's looking like the error is generated here: func (fd *netFD) readFrom(buf []byte) (int, syscall.Sockaddr, error) {
n, sa, err := fd.pfd.ReadFrom(buf)
runtime.KeepAlive(fd)
return n, sa, wrapSyscallError("wsarecvfrom", err)
} https://golang.org/src/net/error_posix.go If needed you could insert this into one of them to see the whole call stack and see who's generating this error when it happens. var i int
for {
pc, fn, line, ok := runtime.Caller(i)
if !ok {
break
}
fmt.Printf("[%d] %s[%s:%d]\n", i, runtime.FuncForPC(pc).Name(), fn, line)
i++
} |
Closing in favor of quic-go/quic-go#1737. |
source code:
ts, err := c.conn.AcceptStream()
i detecte error
InternalError: read udp4 0.0.0.0:55289: wsarecvfrom: The connection has been broken due to keep-alive activity detecting a failure while the operation was in progress
The text was updated successfully, but these errors were encountered: