mirror of
https://github.com/golang/go.git
synced 2025-11-10 13:41:05 +00:00
net: limit concurrent threads to limit on file descriptors
At least on Darwin, if getaddrinfo can't open a file descriptor it
returns EAI_NONAME ("no such host") rather than a meaningful error.
Limit the number of concurrent getaddrinfo calls to the number of file
descriptors we can open, to make that meaningless error less likely.
We don't apply the same limit to Go lookups, because for that we will
return a meaningful "too many open files" error.
Fixes #25694
Change-Id: I601857190aeb64f11e22b4a834c1c6a722a0788d
Reviewed-on: https://go-review.googlesource.com/121176
Reviewed-by: Bryan C. Mills <bcmills@google.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
7c4c87c015
commit
b749845067
5 changed files with 50 additions and 1 deletions
|
|
@ -9,6 +9,7 @@ package net
|
|||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"syscall"
|
||||
|
||||
"golang_org/x/net/dns/dnsmessage"
|
||||
)
|
||||
|
|
@ -315,3 +316,27 @@ func (r *Resolver) lookupAddr(ctx context.Context, addr string) ([]string, error
|
|||
}
|
||||
return r.goLookupPTR(ctx, addr)
|
||||
}
|
||||
|
||||
// concurrentThreadsLimit returns the number of threads we permit to
|
||||
// run concurrently doing DNS lookups via cgo. A DNS lookup may use a
|
||||
// file descriptor so we limit this to less than the number of
|
||||
// permitted open files. On some systems, notably Darwin, if
|
||||
// getaddrinfo is unable to open a file descriptor it simply returns
|
||||
// EAI_NONAME rather than a useful error. Limiting the number of
|
||||
// concurrent getaddrinfo calls to less than the permitted number of
|
||||
// file descriptors makes that error less likely. We don't bother to
|
||||
// apply the same limit to DNS lookups run directly from Go, because
|
||||
// there we will return a meaningful "too many open files" error.
|
||||
func concurrentThreadsLimit() int {
|
||||
var rlim syscall.Rlimit
|
||||
if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rlim); err != nil {
|
||||
return 500
|
||||
}
|
||||
r := int(rlim.Cur)
|
||||
if r > 500 {
|
||||
r = 500
|
||||
} else if r > 30 {
|
||||
r -= 30
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue