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

potential failure on Windows if UDP payload > 1472 bytes #3956

Closed
marten-seemann opened this issue Jul 14, 2023 · 6 comments · Fixed by #3982
Closed

potential failure on Windows if UDP payload > 1472 bytes #3956

marten-seemann opened this issue Jul 14, 2023 · 6 comments · Fixed by #3982
Milestone

Comments

@marten-seemann
Copy link
Member

I've found at least one place where Temporary() isn't doing the right thing now:

If you send a UDP packet with a payload of 1472 bytes to a quic-go listener (where listener.Accept() is being called) on Windows, the packetconn read call returns windows.WSAEMSGSIZE, which is apparently not .Temporary(). The Accept call fails, and It would seem that a lot of quic-go-using applications panic at this point.

A payload larger than MaxPacketBufferSize=1452 bytes is only possible when using IPv4 (or probably with ethernet jumbo frames, too), because IPv4 headers are smaller than IPv6 headers, and the math involved in coming up with MaxPacketBufferSize apparently assumes all packets are IPv6? I would argue that MaxPacketBufferSize is in fact wrong for this reason, but this is beside the point.

On Linux and other unix-y OSes, recvfrom doesn't return an error when the incoming packet is too large, so there's no problem there.

One way to solve the problem on Windows would be by adding a few lines to (*Transport).listen() after checking nerr.Temporary():

    if isMsgSizeErr(err) {
        continue
    }

But I imagine you might not want to get the function overly cluttered up with special checks like this, so I don't know if that's the "right" solution.

Originally posted by @thepaul in #1737 (comment)

@marten-seemann marten-seemann changed the title Windows fails if UDP payload > 1472 bytes potential failure on Windows if UDP payload > 1472 bytes Jul 14, 2023
@marten-seemann
Copy link
Member Author

@thepaul I tried to reproduce this issue by adding a test case in 7f2248a, but for some reason it passes CI. Any idea what's going on?

@thepaul
Copy link

thepaul commented Jul 14, 2023

I'm not sure how the tests are set up, but from the naming I infer that the connection is already set up before the test happens. For this problem, the packets have to arrive while Accept() is waiting for new connections.

@marten-seemann
Copy link
Member Author

For this problem, the packets have to arrive while Accept() is waiting for new connections.

Why’s that? They all go through the same listen loop.

@thepaul
Copy link

thepaul commented Jul 19, 2023

Oh, I see. I didn't realize that was the same listen loop.

I tried running your test case, and it does fail for me on Windows 10 Home. I'll attach the output of ginkgo run --focus 'very large packets' -v ./integrationtests/self.

test-out.txt

@thepaul
Copy link

thepaul commented Jul 19, 2023

I wonder if your Windows installation might have a lower MTU set on the loopback interface? Maybe the packet is getting truncated or fragmented before it reaches the read side?

@marten-seemann
Copy link
Member Author

I didn't realize we're not running our integration tests on Windows in CI 🤦🏻‍♂️ Sorry for that!

I enabled them on Windows, and sure enough, they fail now as well: https://github.com/quic-go/quic-go/actions/runs/5603406031/jobs/10249977347.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants