-
Notifications
You must be signed in to change notification settings - Fork 62
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
[Windows 10] A message sent on a datagram socket was larger than the internal message buffer #34
Comments
Same error but only on Windows Server 2022 (github actions runner |
getting this same error for what should be a successful ipv6 ping as well. |
I have the same problem on Windows 11 and it seems to have been around for a long time.
|
Is anyone here? It's really urgent. Whether you can solve this problem or not, I hope to get a reply. I hope to know your plan. Please. |
Hi folks, I've been looking into this issue myself and largely agree with the suggestions made by @d-Rickyy-b on the original issue linked above. I was able to reproduce this myself and did some digging into the actual packets returned to this code. First, I modified the library to have a large read buffer. Finally, I modified the library to output both the ICMP packet written and the data we received. See the results below: Sent DataRaw ICMP Echo Break Down ICMP Echo Data: Received DataRaw Destination Unreachable Break Down Raw Request IPv4 Header: Parsed Request IPv4 Header: ICMP Destination Unreachable Data: ^Note that this is the same as the full ICMP echo request ConclusionBased on this, what we see on this system is that the response is in line with RFC 1812. We get the ICMP header which identifies the message as Destination Unreachable, the IPv4 header of the original echo request, and the entirety of the original ICMP Echo Request. In the case of this configuration of For my testing, I did not modify So, our original ICMP Echo Request was composed of:
Thus, the total size of the original ICMP Echo Request was: 8 (ICMP Header) + 24 (p.Size) = 32 All that remains then is the ICMP header of the error response and the IP header of the Echo Request: 32 (original ICMP Echo Request) + 20 (original IP header) + 8 (ICMP Response header) = 60 bytes However, the library doesn’t account for this and instead creates a buffer: 24 ( SolutionBased on what was observed above, the library hasn't accounted for the header of both the ICMP echo request and the ICMP error response. The least heavy handed approach then is to simply modify the calculation: // Returns the length of an ICMP error response
// Calculated as:
// len(ICMP response header) + len(original IP header)
// + len(ICMP request header) + len(ICMP request data)
func (p *Pinger) getMessageLength() int {
if p.ipv4 {
return 8 + ipv4.HeaderLen + 8 + p.Size
}
return 8 + ipv6.HeaderLen + 8 + p.Size
} Ideally, this approach would allow us to correctly size the buffer every time. However, I'm not a network engineer and don't know if we can count on routers to always behave in line with the RFCs. What if, for example, a router replies with the entire datagram, but pads the message with 0s up to the RFC 1812's suggested maximum of 576? In that case, this would break and there’s no reason it couldn’t pad it with even more 0s. Another option would be to set the buffer size to 576. This also doesn’t work as one Github user pointed out in the As pointed out in the Final SuggestionIf we want a constant value, I suggest either 576 to be consistent with the suggested max size of an ICMP message or 2048 as this is a sufficiently large buffer consistent with RFC 1812’s suggestions for the MTU. Alternatively, we could be more conservative and dynamically size the buffer using math.Max like so: const (
minimumSize = 576 // or 2048
)
// Returns the length of an ICMP error response
// Calculated as:
// len(ICMP response header) + len(original IP header)
// + len(ICMP request header) + len(ICMP request data)
func (p *Pinger) getMessageLength() int {
if p.ipv4 {
calculatedSize := 8 + ipv4.HeaderLen + 8 + p.Size
return int(math.Max(float64(calculatedSize), float64(minimumSize))
}
calculatedSize := 8 + ipv6.HeaderLen + 8 + p.Size
return int(math.Max(float64(calculatedSize), float64(minimumSize))
} I'm going to open a pull request with last suggest I've made shortly, but I'm open to further discussion/feedback. |
Ran a few more tests, looks like the internal buffer needs to be large enough to hold the IP header of the response as well. I've updated my PR to reflect this: calculatedSize := p.Size + (ipv4.HeaderLen + 8) * 2 |
I get same error in windows 10 by use go-ping. can pro-bing fix this?
go-ping/ping#168
The text was updated successfully, but these errors were encountered: