mirror of
https://github.com/projectdiscovery/httpx.git
synced 2024-09-11 17:46:08 +03:00
Merge pull request #139 from projectdiscovery/feature-ipv6-dns
adding support for ipv6
This commit is contained in:
commit
c3962a518f
@ -554,7 +554,7 @@ retry:
|
||||
)
|
||||
dnsData, err := cache.GetDNSData(domain)
|
||||
if dnsData != nil && err == nil {
|
||||
ips = dnsData.IPs
|
||||
ips = append(dnsData.IP4s, dnsData.IP6s...)
|
||||
cnames = dnsData.CNAMEs
|
||||
} else {
|
||||
ips = append(ips, ip)
|
||||
|
7
common/cache/cache.go
vendored
7
common/cache/cache.go
vendored
@ -58,7 +58,12 @@ func New(options Options) (*Cache, error) {
|
||||
// Lookup a hostname
|
||||
func (c *Cache) Lookup(hostname string) (*dns.Result, error) {
|
||||
if ip := net.ParseIP(hostname); ip != nil {
|
||||
return &dns.Result{IPs: []string{hostname}}, nil
|
||||
if ip.To4() != nil {
|
||||
return &dns.Result{IP4s: []string{hostname}}, nil
|
||||
}
|
||||
if ip.To16() != nil {
|
||||
return &dns.Result{IP6s: []string{hostname}}, nil
|
||||
}
|
||||
}
|
||||
hostnameBytes := []byte(hostname)
|
||||
value, err := c.cache.Get(hostnameBytes)
|
||||
|
8
common/cache/dialer.go
vendored
8
common/cache/dialer.go
vendored
@ -44,10 +44,12 @@ func NewDialer(options Options) (DialerFunc, error) {
|
||||
// we need to filter out empty records
|
||||
hostname := address[:separator]
|
||||
dnsResult, err := cache.Lookup(hostname)
|
||||
if err != nil || len(dnsResult.IPs) == 0 {
|
||||
if err != nil || len(dnsResult.IP4s)+len(dnsResult.IP6s) == 0 {
|
||||
return nil, &NoAddressFoundError{}
|
||||
} // Dial to the IPs finally.
|
||||
for _, ip := range dnsResult.IPs {
|
||||
}
|
||||
|
||||
// Dial to the IPs finally.
|
||||
for _, ip := range append(dnsResult.IP4s, dnsResult.IP6s...) {
|
||||
conn, err = dialer.DialContext(ctx, network, ip+address[separator:])
|
||||
if err == nil {
|
||||
setErr := dialerHistory.Set([]byte(hostname), []byte(ip), 0)
|
||||
|
@ -21,7 +21,8 @@ type Client struct {
|
||||
|
||||
// Result containing ip and time to live
|
||||
type Result struct {
|
||||
IPs []string
|
||||
IP4s []string
|
||||
IP6s []string
|
||||
CNAMEs []string
|
||||
TTL int
|
||||
}
|
||||
@ -60,44 +61,61 @@ func New(baseResolvers []string, maxRetries int) (*Client, error) {
|
||||
}
|
||||
|
||||
// Resolve ips for a record
|
||||
func (c *Client) Resolve(host string) (Result, error) {
|
||||
func (c *Client) Resolve(host string) (result Result, err error) {
|
||||
// retrieve ipv4 addresses
|
||||
err = c.query(host, dns.TypeA, &result)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// retrieve ipv6 addresses
|
||||
err = c.query(host, dns.TypeAAAA, &result)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Client) query(host string, queryType uint16, result *Result) error {
|
||||
msg := new(dns.Msg)
|
||||
msg.Id = dns.Id()
|
||||
msg.RecursionDesired = true
|
||||
msg.Question = make([]dns.Question, 1)
|
||||
msg.Question[0] = dns.Question{
|
||||
Name: dns.Fqdn(host),
|
||||
Qtype: dns.TypeA,
|
||||
Qtype: queryType,
|
||||
Qclass: dns.ClassINET,
|
||||
}
|
||||
resolver := c.resolvers[rand.Intn(len(c.resolvers))]
|
||||
var err error
|
||||
var answer *dns.Msg
|
||||
result := Result{}
|
||||
for i := 0; i < c.maxRetries; i++ {
|
||||
answer, err = dns.Exchange(msg, resolver)
|
||||
answer, err := dns.Exchange(msg, resolver)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if answer != nil && answer.Rcode != dns.RcodeSuccess {
|
||||
return result, errors.New(dns.RcodeToString[answer.Rcode])
|
||||
return errors.New(dns.RcodeToString[answer.Rcode])
|
||||
}
|
||||
|
||||
for _, record := range answer.Answer {
|
||||
switch t := record.(type) {
|
||||
case *dns.A:
|
||||
ip := t.A.String()
|
||||
if ip != "" {
|
||||
result.IPs = append(result.IPs, t.A.String())
|
||||
result.IP4s = append(result.IP4s, t.A.String())
|
||||
result.TTL = int(t.Header().Ttl)
|
||||
}
|
||||
case *dns.AAAA:
|
||||
ip := t.AAAA.String()
|
||||
if ip != "" {
|
||||
result.IP6s = append(result.IP6s, t.AAAA.String())
|
||||
result.TTL = int(t.Header().Ttl)
|
||||
}
|
||||
case *dns.CNAME:
|
||||
if t.Target != "" {
|
||||
if queryType == dns.TypeA && t.Target != "" {
|
||||
result.CNAMEs = append(result.CNAMEs, strings.TrimSuffix(t.Target, "."))
|
||||
}
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
return result, err
|
||||
return nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user