dnsify
is a lightweight DNS resolver client built in Go that allows you to resolve hostnames and retrieve DNS records (e.g., A, AAAA, NS, CNAME, etc.) efficiently. It supports retries, random resolver selection, and retrieving raw DNS responses.
- Random resolver selection for load balancing
- Configurable retry mechanism
- Resolve specific DNS record types (A, AAAA, NS, etc.)
- Fetch raw DNS responses for debugging or inspection
- Concurrency-safe with optimized read and write locks
To install the dnsify
package, run:
go get github.com/cyinnove/dnsify
Then, import it into your project:
import "github.com/cyinnove/dnsify"
Here’s how you can use dnsify
to resolve A records (IPv4 addresses) for a given hostname:
package main
import (
"fmt"
"log"
"github.com/cyinnove/dnsify"
)
func main() {
resolvers := []string{"8.8.8.8:53", "8.8.4.4:53"}
client := dnsify.New(resolvers, 3) // 3 retries
result, err := client.Resolve("example.com")
if err != nil {
log.Fatalf("Failed to resolve: %v", err)
}
fmt.Printf("Resolved IPs: %v, TTL: %d\n", result.IPs, result.TTL)
}
If you want to retrieve raw DNS records for debugging or advanced use cases, you can use the ResolveRaw
method:
package main
import (
"fmt"
"log"
"github.com/cyinnove/dnsify"
"github.com/miekg/dns"
)
func main() {
resolvers := []string{"8.8.8.8:53", "1.1.1.1:53"}
client := dnsify.New(resolvers, 3) // 3 retries
results, raw, err := client.ResolveRaw("example.com", dns.TypeMX) // Resolve MX records
if err != nil {
log.Fatalf("Failed to resolve: %v", err)
}
fmt.Printf("Raw response: \n%s\n", raw)
fmt.Printf("Parsed MX records: %v\n", results)
}
For advanced DNS queries, you can create a custom dns.Msg
and send it using the Do
method:
package main
import (
"fmt"
"log"
"github.com/cyinnove/dnsify"
"github.com/miekg/dns"
)
func main() {
resolvers := []string{"8.8.8.8:53", "1.1.1.1:53"}
client := dnsify.New(resolvers, 3) // 3 retries
msg := new(dns.Msg)
msg.SetQuestion(dns.Fqdn("example.com"), dns.TypeA)
resp, err := client.Do(msg)
if err != nil {
log.Fatalf("Failed to send custom DNS request: %v", err)
}
fmt.Printf("Custom DNS Response: \n%s\n", resp)
}
func New(baseResolvers []string, maxRetries int) *Client
- baseResolvers: A list of DNS resolver addresses (e.g.,
8.8.8.8:53
). - maxRetries: The number of retry attempts when resolving fails.
func (c *Client) Resolve(host string) (Result, error)
- host: The hostname to resolve (e.g.,
example.com
). - Result: A struct containing the IPs and TTL.
func (c *Client) ResolveRaw(host string, requestType uint16) ([]string, string, error)
- host: The hostname to resolve.
- requestType: The DNS record type (e.g.,
dns.TypeA
,dns.TypeMX
, etc.). - Returns: A list of parsed records, the raw response string, and any error encountered.
func (c *Client) Do(msg *dns.Msg) (*dns.Msg, error)
- msg: A custom
dns.Msg
message to send. - Returns: The raw DNS response and any error encountered.
type Result struct {
IPs []string
TTL int
}
The Result
struct contains:
- IPs: The list of resolved IP addresses.
- TTL: The time-to-live (TTL) of the DNS response.
This project is licensed under the MIT License. See the LICENSE file for more details.
Feel free to submit issues, fork the repository, and open pull requests to help improve dnsify
.