Change-Id: Ife1d7676f8a1d1f80d480e7734d6107c84d93621
This commit is contained in:
Mateusz Poliwczak 2023-11-07 10:51:12 +01:00
parent 3f7e7742b5
commit 9c93066809
3 changed files with 57 additions and 21 deletions

View File

@ -41,18 +41,12 @@ func (eai addrinfoErrno) isAddrinfoErrno() {}
// context is cancellable. It is intended for use with calls that don't support context
// cancellation (cgo, syscalls). blocking func may still be running after this function finishes.
// For the duration of the execution of the blocking function, the thread is 'acquired' using [acquireThread],
// blocking might not be executed when the context gets cancelled.
// blocking might not be executed when the context gets cancelled early.
func doBlockingWithCtx[T any](ctx context.Context, lookupName string, blocking func() (T, error)) (T, error) {
if err := acquireThread(ctx); err != nil {
var zero T
return zero, &DNSError{
Name: lookupName,
Err: mapErr(ctx.Err()).Error(),
IsTimeout: ctx.Err() == context.DeadlineExceeded,
}
}
if ctx.Done() == nil {
// Context is non-cancellable, so there is no need
// to handle the error from acquireThread.
acquireThread(ctx)
defer releaseThread()
return blocking()
}
@ -64,6 +58,16 @@ func doBlockingWithCtx[T any](ctx context.Context, lookupName string, blocking f
res := make(chan result, 1)
go func() {
if err := acquireThread(ctx); err != nil {
res <- result{
err: &DNSError{
Name: lookupName,
Err: mapErr(err).Error(),
IsTimeout: err == context.DeadlineExceeded,
},
}
return
}
defer releaseThread()
var r result
r.res, r.err = blocking()
@ -114,7 +118,7 @@ func cgoLookupPort(ctx context.Context, network, service string) (port int, err
*_C_ai_family(&hints) = _C_AF_INET6
}
return doBlockingWithCtx(ctx, network + "/" + service, func() (int, error) {
return doBlockingWithCtx(ctx, network+"/"+service, func() (int, error) {
return cgoLookupServicePort(&hints, network, service)
})
}

View File

@ -55,7 +55,7 @@ func lookupProtocol(ctx context.Context, name string) (int, error) {
ch := make(chan result) // unbuffered
go func() {
if err := acquireThread(ctx); err != nil {
ch <- result{err: err}
ch <- result{err: mapErr(err)}
return
}
defer releaseThread()
@ -115,7 +115,11 @@ func (r *Resolver) lookupIP(ctx context.Context, network, name string) ([]IPAddr
getaddr := func() ([]IPAddr, error) {
if err := acquireThread(ctx); err != nil {
return nil, err
return nil, &DNSError{
Name: name,
Err: mapErr(err).Error(),
IsTimeout: ctx.Err() == context.DeadlineExceeded,
}
}
defer releaseThread()
hints := syscall.AddrinfoW{
@ -207,7 +211,11 @@ func (r *Resolver) lookupPort(ctx context.Context, network, service string) (int
// TODO(bradfitz): finish ctx plumbing. Nothing currently depends on this.
if err := acquireThread(ctx); err != nil {
return 0, err
return 0, &DNSError{
Name: network + "/" + service,
Err: mapErr(err).Error(),
IsTimeout: ctx.Err() == context.DeadlineExceeded,
}
}
defer releaseThread()
@ -272,7 +280,11 @@ func (r *Resolver) lookupCNAME(ctx context.Context, name string) (string, error)
// TODO(bradfitz): finish ctx plumbing. Nothing currently depends on this.
if err := acquireThread(ctx); err != nil {
return "", err
return "", &DNSError{
Name: name,
Err: mapErr(err).Error(),
IsTimeout: ctx.Err() == context.DeadlineExceeded,
}
}
defer releaseThread()
var rec *syscall.DNSRecord
@ -299,7 +311,11 @@ func (r *Resolver) lookupSRV(ctx context.Context, service, proto, name string) (
}
// TODO(bradfitz): finish ctx plumbing. Nothing currently depends on this.
if err := acquireThread(ctx); err != nil {
return "", nil, err
return "", nil, &DNSError{
Name: name,
Err: mapErr(err).Error(),
IsTimeout: ctx.Err() == context.DeadlineExceeded,
}
}
defer releaseThread()
var target string
@ -331,7 +347,11 @@ func (r *Resolver) lookupMX(ctx context.Context, name string) ([]*MX, error) {
}
// TODO(bradfitz): finish ctx plumbing. Nothing currently depends on this.
if err := acquireThread(ctx); err != nil {
return nil, err
return nil, &DNSError{
Name: name,
Err: mapErr(err).Error(),
IsTimeout: ctx.Err() == context.DeadlineExceeded,
}
}
defer releaseThread()
var rec *syscall.DNSRecord
@ -357,7 +377,11 @@ func (r *Resolver) lookupNS(ctx context.Context, name string) ([]*NS, error) {
}
// TODO(bradfitz): finish ctx plumbing. Nothing currently depends on this.
if err := acquireThread(ctx); err != nil {
return nil, err
return nil, &DNSError{
Name: name,
Err: mapErr(err).Error(),
IsTimeout: ctx.Err() == context.DeadlineExceeded,
}
}
defer releaseThread()
var rec *syscall.DNSRecord
@ -382,7 +406,11 @@ func (r *Resolver) lookupTXT(ctx context.Context, name string) ([]string, error)
}
// TODO(bradfitz): finish ctx plumbing. Nothing currently depends on this.
if err := acquireThread(ctx); err != nil {
return nil, err
return nil, &DNSError{
Name: name,
Err: mapErr(err).Error(),
IsTimeout: ctx.Err() == context.DeadlineExceeded,
}
}
defer releaseThread()
var rec *syscall.DNSRecord
@ -412,7 +440,11 @@ func (r *Resolver) lookupAddr(ctx context.Context, addr string) ([]string, error
// TODO(bradfitz): finish ctx plumbing. Nothing currently depends on this.
if err := acquireThread(ctx); err != nil {
return nil, err
return nil, &DNSError{
Name: addr,
Err: mapErr(err).Error(),
IsTimeout: ctx.Err() == context.DeadlineExceeded,
}
}
defer releaseThread()
arpa, err := reverseaddr(addr)

View File

@ -731,7 +731,7 @@ func acquireThread(ctx context.Context) error {
case threadLimit <- struct{}{}:
return nil
case <-ctx.Done():
return mapErr(ctx.Err())
return ctx.Err()
}
}