-
Notifications
You must be signed in to change notification settings - Fork 1
fix(ss): reduce Windows DLL buffer cap from 64 MiB to 5 MiB #147
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
Changes from all commits
183b096
950ef8a
5c76cb7
5ba379e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -34,7 +34,8 @@ const ( | |
| // calling GetExtendedTcpTable / GetExtendedUdpTable. This cap is | ||
| // intentionally defined here (where the DLL calls live) so that the limit | ||
| // stays co-located with the code that enforces it. | ||
| MaxBufSize = 64 << 20 // 64 MiB | ||
| // 5 MiB is sufficient for any realistic socket table on Windows. | ||
| MaxBufSize = 5 << 20 // 5 MiB | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Reducing Useful? React with 👍 / 👎.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i think this part is actually worth fixing:
the numbers provided in the previous comment are theoretical only (imho). cc @thieman
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will update it to fail entirely in that case, still seems unlikely we will go past the 5MB limit |
||
| ) | ||
|
|
||
| var ( | ||
|
|
@@ -61,41 +62,44 @@ var tcpStateNames = map[uint32]string{ | |
|
|
||
| // Collect enumerates all TCP and UDP sockets on Windows via iphlpapi.dll. | ||
| // The narrow use of unsafe.Pointer is limited to two DLL call sites only. | ||
| // If every sub-collection fails, the first error is returned so callers can | ||
| // distinguish a real API failure from an empty socket table. | ||
| // If any sub-collection fails, an error is returned immediately so callers | ||
| // always receive complete data or a clear failure — never silent partial results. | ||
| func Collect() ([]SocketEntry, error) { | ||
| var out []SocketEntry | ||
| var firstErr error | ||
|
|
||
| collect := func(e []SocketEntry, err error) { | ||
| if err != nil { | ||
| if firstErr == nil { | ||
| firstErr = err | ||
| } | ||
| return | ||
| } | ||
| out = append(out, e...) | ||
| // TCP IPv4 | ||
| e, err := collectTCP(afINET) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("tcp4: %w", err) | ||
| } | ||
| out = append(out, e...) | ||
|
|
||
| // TCP IPv4 | ||
| collect(collectTCP(afINET)) | ||
| // TCP IPv6 | ||
| collect(collectTCP(afINET6)) | ||
| e, err = collectTCP(afINET6) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("tcp6: %w", err) | ||
| } | ||
| out = append(out, e...) | ||
|
|
||
| // UDP IPv4 | ||
| collect(collectUDP(afINET)) | ||
| // UDP IPv6 | ||
| collect(collectUDP(afINET6)) | ||
| e, err = collectUDP(afINET) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("udp4: %w", err) | ||
| } | ||
| out = append(out, e...) | ||
|
|
||
| // Return an error only when every collection failed and nothing was returned. | ||
| // Partial results (e.g. IPv6 unavailable) are still returned without error. | ||
| if len(out) == 0 && firstErr != nil { | ||
| return nil, firstErr | ||
| // UDP IPv6 | ||
| e, err = collectUDP(afINET6) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("udp6: %w", err) | ||
| } | ||
| out = append(out, e...) | ||
|
|
||
| return out, nil | ||
| } | ||
|
|
||
| // callExtendedTable calls GetExtendedTcpTable or GetExtendedUdpTable with a | ||
| // grow-loop, capped at MaxWinBufSize. Returns the raw buffer on success. | ||
| // grow-loop, capped at MaxBufSize. Returns the raw buffer on success. | ||
| func callExtendedTable(proc *syscall.Proc, af, tableClass uintptr) ([]byte, error) { | ||
| size := uint32(4096) | ||
| for { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
callExtendedTablereferences wrong constant nameLine 98 just below this hunk reads:
MaxWinBufSizeis the mirror constant defined inbuiltins/ss/ss.go. The constant actually enforced in this function isMaxBufSize(defined here inwinnet_windows.go). The comment should read "capped atMaxBufSize".