Query executes a DNS query received from the given address. The query is provided in bs as a wire-encoded DNS query without any transport header. This method is called for requests arriving over UDP and TCP. The "family" parameter should indicate what type of DNS query this is: either "tcp" or "udp
(ctx context.Context, bs []byte, family string, from netip.AddrPort)
| 479 | // The "family" parameter should indicate what type of DNS query this is: |
| 480 | // either "tcp" or "udp". |
| 481 | func (m *Manager) Query(ctx context.Context, bs []byte, family string, from netip.AddrPort) ([]byte, error) { |
| 482 | select { |
| 483 | case <-m.ctx.Done(): |
| 484 | return nil, net.ErrClosed |
| 485 | default: |
| 486 | // continue |
| 487 | } |
| 488 | |
| 489 | if n := atomic.AddInt32(&m.activeQueriesAtomic, 1); n > maxActiveQueries { |
| 490 | atomic.AddInt32(&m.activeQueriesAtomic, -1) |
| 491 | metricDNSQueryErrorQueue.Add(1) |
| 492 | return nil, errFullQueue |
| 493 | } |
| 494 | defer atomic.AddInt32(&m.activeQueriesAtomic, -1) |
| 495 | outbs, err := m.resolver.Query(ctx, bs, family, from) |
| 496 | if err != nil { |
| 497 | return outbs, err |
| 498 | } |
| 499 | m.mu.Lock() |
| 500 | defer m.mu.Unlock() |
| 501 | if m.queryResponseMapper != nil { |
| 502 | outbs = m.queryResponseMapper(outbs) |
| 503 | } |
| 504 | return outbs, err |
| 505 | } |
| 506 | |
| 507 | const ( |
| 508 | // RFC 7766 6.2 recommends connection reuse & request pipelining |