publicdns

package module
v0.0.0-...-f226d17 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 8, 2019 License: MIT Imports: 9 Imported by: 2

README

Build Status codecov Code Climate Issue Count

Public DNS Info

This package allows you to interact with the information about Nameservers worldwide contained in the website public-dns-info. It allows you to download the content of the CSV files that public-dns.info makes available and dump its content into a queryable database (in the tests SQLite is used).

Its primary use case is to allow automatic server selection as well as health checking to my other project where you can check the propagation of DNS records worldwide. Some nameservers are in locations with unstable connections so this library is a way to always obtain the most reliable server. In Africa, for example, it's common that servers go offline or new, more reliable ones come up.

Due to the fact that the library has a very specific use case its features are merely the minimum required for the purposes of the DNS propagation project.

Usage

The main workflow to use this library is the following:

  1. Get the file with the list of nameservers from a URL or use a cached one
  2. Parse the contents of the loaded file (done during the fetch phase)
  3. Dump the contents into a database of your choice. The database is always destroyed in every dump
  4. Query the database using the helper method from the package
import "github.com/rvelhote/go-public-dns"

servers, _ := publicdns.LoadFromFile("nameservers.test.csv")
servers2, _ := publicdns.LoadFromFile("nameservers.test.csv.does.not.exist")

// Open a database connection. Feel free to use whatever driver you desire
// NOTE: Only tested in SQLite so far
db, _ := sql.Open("sqlite3", "nameservers.test.db")
defer db.Close()

total, _ := publicdns.DumpToDatabase(db, servers)

dnsquery := publicdns.PublicDNS{db: db}
info, _ := dnsquery.GetBestFromCountry("DE")

fmt.Sprintf("IP: %s Country: %s", info.IPAddress, info.Country)

Further Developments

  • Test other SQL drivers to make sure we have freedom in using whatever database engine
  • Add more functions with useful queries

Contributing

You are very welcome to contribute with issues/requests and pull requests if you find this library useful.

Documentation

Overview

Package publicdns allows the user to obtain data from public-dns.info, query and manage the data

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DumpToDatabase

func DumpToDatabase(db *sql.DB, servers []*Nameserver) (int64, error)

DumpToDatabase dumps a complete server dataset into the selected database instance. It will create the database if it does not exist and insert all records present in the 'servers' variable. This function will insert all records in a single transaction. The test data indicates about 40000 records but the performance seems perfectly fine. Also consider that the table will be dropped.

The database schema amounts to the same fields as the CSV value that you can find at public-dns.info. - IP (the ipv4 address of the server) - Name (the hostname of the server if the server has a hostname) - Country (two-letter ISO 3166-1 alpha-2 code. probably an IP location lookup by public-dns.info) - City (the city name that the server is hosted on. probably an IP location lookup by public-dns.info) - Version (the software version of the dns daemon that the server is using) - Error (the error that the server returned. probably will be empty if you are using the valid nameserver dataset) - DNSSec (boolean to indicate if the server supports DNSSec or not) - Reliability (a reliability value - normalized from 0.0 - 1.0 - to indicate how stable the server is) - CheckedAt (a timestamp to indicate the date that the server was last checked) - CreatedAt (a timestamp to indicate when the server was inserted in the database)

TODO Create an index for Country, Reliability and IP TODO Fix the schema and the data types of each field to be something meaningful instead of 100% varchar

Types

type Nameserver

type Nameserver struct {
	// IPAddress is the ipv4 address of the server
	IPAddress string `csv:"ip"`

	// Name is the hostname of the server if the server has a hostname
	Name string `csv:"name"`

	// Country is the two-letter ISO 3166-1 alpha-2 code of the country
	Country string `csv:"country_id"`

	// City specifies the city that the server is hosted on
	City string `csv:"city"`

	// Version is the software version of the dns daemon that the server is using
	Version string `csv:"version"`

	// Error is the error that the server returned. Probably will be empty if you use the valid nameserver dataset
	Error string `csv:"error"`

	// DNSSec is a boolean to indicate if the server supports DNSSec or not
	DNSSec bool `csv:"dnssec"`

	// Realiability is a normalized value - from 0.0 - 1.0 - to indicate how stable the server is
	Reliability string `csv:"reliability"`

	// CheckedAt is a timestamp to indicate the date that the server was last checked
	CheckedAt time.Time `csv:"checked_at"`

	// CreatedAt is a timestamp to indicate when the server was inserted in the database
	CreatedAt time.Time `csv:"created_at"`
}

Nameserver is the structure that mimics the fields that belong CSV file that can be obtained from public-dns.info.

func LoadFromFile

func LoadFromFile(filename string) ([]*Nameserver, error)

LoadFromFile takes a filename (assumed to be a CSV) and loads the server data contained in that file.

func LoadFromURL

func LoadFromURL(url string, filename string) ([]*Nameserver, error)

LoadFromURL takes a URL with a CSV file, downloads the file and attempts to load the file contents using the previously refered LoadFromFile. A filename called nameservers.temp.csv will be created.

type NameserverCountryTally

type NameserverCountryTally struct {
	Country string
	Total   int
}

NameserverCountryTally is a structure that will hold the result of the GetTotalServersPerCountry func

type PublicDNS

type PublicDNS struct {
	DB *sql.DB
}

PublicDNS is the structure that is used to perform queries on the nameservers dataset that was stored in a database. The only parameter is an SQL connection instance. You can use any server that is supported by Golang.

func (*PublicDNS) GetAllFromCountry

func (p *PublicDNS) GetAllFromCountry(country string) ([]*Nameserver, error)

GetAllFromCountry obtains all the DNS servers registered in the database for a specific country. The country letter must be a two-letter ISO 3166-1 alpha-2 code i.e. US, PT, JP. TODO Do we really need to count the amount of records?

func (*PublicDNS) GetBestFromCountries

func (p *PublicDNS) GetBestFromCountries(countries []interface{}) ([]*Nameserver, error)

GetBestFromCountries takes a list of countries (two-letter ISO 3166-1 alpha-2 code) and obtains the best servers for each of the requested countries.

func (*PublicDNS) GetBestFromCountry

func (p *PublicDNS) GetBestFromCountry(country string) (*Nameserver, error)

GetBestFromCountry obtains the best DNS server from a specific country. This is measured by the reliability parameter so for many countries it will always return the same server (for the US it's always Google's DNS server). For countries that have less reliable DNS servers (such as those located in Africa) this could be more useful.

func (*PublicDNS) GetNameserverPerCountryTally

func (p *PublicDNS) GetNameserverPerCountryTally() ([]*NameserverCountryTally, error)

GetNameserverPerCountryTally obtains a list the total of "good" nameservers that exist per country. In this context "good" means that the server as a hostname (reverse lookup) has city name and its reliability score is 1 (maximum).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL