Created
April 3, 2024 14:17
-
-
Save stek29/f0654275014495f5d75a60d9aebddecd to your computer and use it in GitHub Desktop.
dnstest -- query dns from different source ports range to debug network card losing packets from specific 5tuples
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"flag" | |
"fmt" | |
"net" | |
"sync" | |
"github.com/miekg/dns" | |
) | |
var ( | |
domain string | |
dnsServer string | |
sourcePortMin int | |
sourcePortMax int | |
maxJobs int | |
maxAttempts int | |
) | |
func main() { | |
flag.IntVar(&sourcePortMin, "sport-min", 50000, "min source port (inclusive)") | |
flag.IntVar(&sourcePortMax, "sport-max", 50002, "min source port (exclusive)") | |
flag.IntVar(&maxJobs, "J", 16, "max parallell requests") | |
flag.IntVar(&maxAttempts, "max-attempts", 3, "max attempts to resolve from one sport") | |
flag.StringVar(&dnsServer, "S", "0.0.0.0:53", "dns server to use") | |
flag.StringVar(&domain, "D", "ya.ru", "domain to resolve") | |
flag.Parse() | |
sem := make(chan struct{}, maxJobs) | |
var wg sync.WaitGroup | |
for sourcePort := sourcePortMin; sourcePort < sourcePortMax; sourcePort++ { | |
wg.Add(1) | |
go func(sPort int) { | |
sem <- struct{}{} | |
var err error | |
for attempt := 0; attempt < maxAttempts; attempt++ { | |
_, err = resolveARecord(domain, dnsServer, sPort) | |
if err == nil { | |
break | |
} | |
} | |
if err != nil { | |
fmt.Printf("sPort: %d err: %v\n", sPort, err) | |
} | |
<-sem | |
wg.Done() | |
}(sourcePort) | |
} | |
wg.Wait() | |
} | |
// resolveARecord resolves the A record of a given domain using the specified DNS server and UDP source port | |
func resolveARecord(domain, dnsServer string, sourcePort int) (string, error) { | |
client := dns.Client{Net: "udp", Dialer: &net.Dialer{LocalAddr: &net.UDPAddr{IP: net.IPv4zero, Port: sourcePort}}} | |
// Prepare DNS message | |
msg := new(dns.Msg) | |
msg.SetQuestion(domain+".", dns.TypeA) | |
// Send DNS query message | |
response, _, err := client.Exchange(msg, dnsServer) | |
if err != nil { | |
return "", err | |
} | |
// Check if response contains answers | |
if len(response.Answer) == 0 { | |
return "", fmt.Errorf("No answer records found") | |
} | |
// Extract IP address from the first answer | |
ipAddress := response.Answer[0].(*dns.A).A.String() | |
return ipAddress, nil | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module dnstest | |
go 1.21.4 | |
require github.com/miekg/dns v1.1.58 | |
require ( | |
golang.org/x/mod v0.14.0 // indirect | |
golang.org/x/net v0.20.0 // indirect | |
golang.org/x/sys v0.16.0 // indirect | |
golang.org/x/tools v0.17.0 // indirect | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4= | |
github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY= | |
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= | |
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= | |
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= | |
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= | |
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= | |
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= | |
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= | |
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= | |
golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= | |
golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment