chore: better dns batchExchange

This commit is contained in:
wwqgtxx 2023-10-25 20:16:44 +08:00
parent 431d52f250
commit 55f626424f

View file

@ -290,11 +290,14 @@ func listenPacket(ctx context.Context, proxyAdapter C.ProxyAdapter, proxyName st
return proxyAdapter.ListenPacketContext(ctx, metadata, opts...) return proxyAdapter.ListenPacketContext(ctx, metadata, opts...)
} }
var errIPNotFound = errors.New("couldn't find ip")
func batchExchange(ctx context.Context, clients []dnsClient, m *D.Msg) (msg *D.Msg, cache bool, err error) { func batchExchange(ctx context.Context, clients []dnsClient, m *D.Msg) (msg *D.Msg, cache bool, err error) {
cache = true cache = true
fast, ctx := picker.WithTimeout[*D.Msg](ctx, resolver.DefaultDNSTimeout) fast, ctx := picker.WithTimeout[*D.Msg](ctx, resolver.DefaultDNSTimeout)
defer fast.Close() defer fast.Close()
domain := msgToDomain(m) domain := msgToDomain(m)
var noIpMsg *D.Msg
for _, client := range clients { for _, client := range clients {
if _, isRCodeClient := client.(rcodeClient); isRCodeClient { if _, isRCodeClient := client.(rcodeClient); isRCodeClient {
msg, err = client.ExchangeContext(ctx, m) msg, err = client.ExchangeContext(ctx, m)
@ -311,13 +314,31 @@ func batchExchange(ctx context.Context, clients []dnsClient, m *D.Msg) (msg *D.M
// so we would ignore RCode errors from RCode clients. // so we would ignore RCode errors from RCode clients.
return nil, errors.New("server failure: " + D.RcodeToString[m.Rcode]) return nil, errors.New("server failure: " + D.RcodeToString[m.Rcode])
} }
log.Debugln("[DNS] %s --> %s, from %s", domain, msgToIP(m), client.Address()) if ips := msgToIP(m); len(m.Question) > 0 {
qType := m.Question[0].Qtype
log.Debugln("[DNS] %s --> %s %s from %s", domain, ips, D.Type(qType), client.Address())
switch qType {
case D.TypeAAAA:
if len(ips) == 0 {
noIpMsg = m
return nil, errIPNotFound
}
case D.TypeA:
if len(ips) == 0 {
noIpMsg = m
return nil, errIPNotFound
}
}
}
return m, nil return m, nil
}) })
} }
msg = fast.Wait() msg = fast.Wait()
if msg == nil { if msg == nil {
if noIpMsg != nil {
return noIpMsg, false, nil
}
err = errors.New("all DNS requests failed") err = errors.New("all DNS requests failed")
if fErr := fast.Error(); fErr != nil { if fErr := fast.Error(); fErr != nil {
err = fmt.Errorf("%w, first error: %w", err, fErr) err = fmt.Errorf("%w, first error: %w", err, fErr)