diff --git a/Makefile b/Makefile index 51a1fb9c..c4d68436 100644 --- a/Makefile +++ b/Makefile @@ -16,6 +16,9 @@ appengine: cloudflare: go run ./cmd/ipcat/main.go -cloudflare +tor: + go run ./cmd/ipcat/main.go -tor -csvfile tor.csv -statsfile="" + test: find . -name '*.go' | xargs gofmt -w -s find . -name '*.go' | xargs goimports -w diff --git a/appengine.go b/appengine.go index 70a8f95b..f5b30012 100644 --- a/appengine.go +++ b/appengine.go @@ -30,22 +30,31 @@ func lookupSPFRecord(name string, f func(dir string) error) error { // DownloadAppEngine downloads and returns raw bytes of the Google App Engine ip // range list func DownloadAppEngine() ([]string, error) { - var ranges []string - if err := lookupSPFRecord("_cloud-netblocks.googleusercontent.com", func(dir string) error { - inc := strings.TrimPrefix(dir, "include:") - if dir == inc { - return nil - } + ranges := []string{} + domainList := []string{"_cloud-netblocks.googleusercontent.com"} - return lookupSPFRecord(inc, func(dir string) error { + for len(domainList) > 0 { + // Dequeue a domain from this list + var domain string + domain, domainList = domainList[0], domainList[1:] + err := lookupSPFRecord(domain, func(dir string) error { + // Enqueue domain from this record + if inc := strings.TrimPrefix(dir, "include:"); dir != inc { + domainList = append(domainList, inc) + } + // Add IPv4 range if ip4 := strings.TrimPrefix(dir, "ip4:"); dir != ip4 { ranges = append(ranges, ip4) } - + // Add IPv6 range + if ip6 := strings.TrimPrefix(dir, "ip6:"); dir != ip6 { + ranges = append(ranges, ip6) + } return nil }) - }); err != nil { - return nil, err + if err != nil { + return nil, err + } } return ranges, nil diff --git a/aws.go b/aws.go index a7be7b49..1cb19c85 100644 --- a/aws.go +++ b/aws.go @@ -13,16 +13,18 @@ var ( // AWSPrefix is AWS prefix in their IP ranges file type AWSPrefix struct { - IPPrefix string `json:"ip_prefix"` - Region string `json:"region"` - Service string `json:"service"` + IPPrefix string `json:"ip_prefix"` + IPv6Prefix string `json:"ipv6_prefix"` + Region string `json:"region"` + Service string `json:"service"` } // AWS is main record for AWS IP info type AWS struct { - SyncToken string `json:"syncToken"` - CreateDate string `json:"createDate"` - Prefixes []AWSPrefix `json:"prefixes"` + SyncToken string `json:"syncToken"` + CreateDate string `json:"createDate"` + Prefixes []AWSPrefix `json:"prefixes"` + IPv6Prefixes []AWSPrefix `json:"ipv6_prefixes"` } // DownloadAWS downloads the latest AWS IP ranges list @@ -60,9 +62,23 @@ func UpdateAWS(ipmap *IntervalSet, body []byte) error { ipmap.DeleteByName(awsName) // and add back - for _, rec := range aws.Prefixes { - if rec.Service == "EC2" { - err := ipmap.AddCIDR(rec.IPPrefix, awsName, awsURL) + for _, prefixList := range []*[]AWSPrefix{&aws.Prefixes, &aws.IPv6Prefixes} { + for _, rec := range *prefixList { + if rec.Service != "AMAZON" { + // Service is the subset of IP address ranges. Specify AMAZON to get + // all IP address ranges (for example, the ranges in the EC2 subset + // are also in the AMAZON subset). Note that some IP address ranges + // are only in the AMAZON subset. + // + continue + } + + prefix := rec.IPPrefix + if prefix == "" { + prefix = rec.IPv6Prefix + } + + err := ipmap.AddCIDR(prefix, awsName, awsURL) if err != nil { return err } diff --git a/aws_test.go b/aws_test.go index 0a371396..10af7c11 100644 --- a/aws_test.go +++ b/aws_test.go @@ -23,6 +23,16 @@ func TestAWS(t *testing.T) { "ip_prefix": "13.54.0.0/15", "region": "ap-southeast-2", "service": "EC2" + }, + { + "ipv6_prefix": "2a05:d016::/36", + "region": "eu-north-1", + "service": "AMAZON" + }, + { + "ipv6_prefix": "2a05:d018::/36", + "region": "eu-west-1", + "service": "EC2" } ] }`) @@ -39,19 +49,27 @@ func TestAWS(t *testing.T) { if err != nil { t.Fatalf("UpdateAWS error: %v", err) } - // UpdateAWS should only add EC2 IP ranges - rec, err := ipset.Contains("216.182.224.0") - if err != nil { - t.Fatalf("ipset.Contains(%q) error: %v", "216.182.224.0", err) - } - if rec != nil { - t.Errorf("ipset.Contains(%q) rec = %v, want nil", "216.182.224.0", rec) - } - rec, err = ipset.Contains("13.54.0.1") - if err != nil { - t.Fatalf("ipset.Contains(%q) error: %v", "13.54.0.0", err) + + tests := []struct { + IP string + Contains bool + }{ + {IP: "216.182.224.0", Contains: true}, + {IP: "2a05:d016::20", Contains: true}, + + // Only AMAZON services will be contained (superset of all) + {IP: "13.54.0.1", Contains: false}, + {IP: "2a05:d018::20", Contains: false}, } - if rec == nil { - t.Errorf("ipset.Contains(%q) rec = nil, want exists", "13.54.0.0") + + for _, test := range tests { + record, err := ipset.Contains(test.IP) + if err != nil { + t.Fatalf("ipset.Contains(%q) error: %v", test.IP, err) + } + if (record != nil) != test.Contains { + t.Errorf("ipset.Contains(%q) rec = %v, want rec != nil to be %v", + test.IP, record, test.Contains) + } } } diff --git a/azure.go b/azure.go index 09945f66..c9ce1cf2 100644 --- a/azure.go +++ b/azure.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "io/ioutil" - "log" "net/http" "regexp" ) @@ -58,7 +57,6 @@ func DownloadAzure() ([]byte, error) { return nil, fmt.Errorf("failed to find public IPs url during retry: %s", err) } - log.Printf("Attempting ip range download with url %s...", url) resp, err := http.Get(url) if err != nil { return nil, err diff --git a/cloudflare.go b/cloudflare.go index 94e79ba1..65fdc452 100644 --- a/cloudflare.go +++ b/cloudflare.go @@ -3,28 +3,44 @@ package ipcat import ( "bytes" "fmt" + "io" "io/ioutil" "net/http" ) var ( - cloudflareDownload = "https://www.cloudflare.com/ips-v4" + cloudflareDownload = []string{ + "https://www.cloudflare.com/ips-v4", + "https://www.cloudflare.com/ips-v6", + } ) // DownloadCloudflare downloads the latest Cloudflare IP ranges list func DownloadCloudflare() ([]byte, error) { - resp, err := http.Get(cloudflareDownload) - if err != nil { - return nil, err - } - if resp.StatusCode != 200 { - return nil, fmt.Errorf("Failed to download Cloudflare ranges: status code %s", resp.Status) + readers := make([]io.Reader, 0, len(cloudflareDownload)) + + defer func() { + for _, reader := range readers { + reader.(io.ReadCloser).Close() + } + }() + + for _, uri := range cloudflareDownload { + resp, err := http.Get(uri) + if err != nil { + return nil, err + } + readers = append(readers, resp.Body) + + if resp.StatusCode != 200 { + return nil, fmt.Errorf("Failed to download Cloudflare ranges: status code %s", resp.Status) + } } - body, err := ioutil.ReadAll(resp.Body) + + body, err := ioutil.ReadAll(io.MultiReader(readers...)) if err != nil { return nil, err } - resp.Body.Close() return bytes.TrimSpace(body), nil } diff --git a/cmd/ipcat/main.go b/cmd/ipcat/main.go index 9e6eb8ee..b5c45c18 100644 --- a/cmd/ipcat/main.go +++ b/cmd/ipcat/main.go @@ -4,6 +4,7 @@ import ( "flag" "fmt" "log" + "net" "os" "strings" @@ -16,6 +17,7 @@ func main() { updateAzure := flag.Bool("azure", false, "update Azure records") updateAppEngine := flag.Bool("appengine", false, "update AppEngine (Google App Engine) records") updateCloudflare := flag.Bool("cloudflare", false, "update Cloudflare records") + updateTor := flag.Bool("tor", false, "update Tor records") datafile := flag.String("csvfile", "datacenters.csv", "read/write from this file") statsfile := flag.String("statsfile", "datacenters-stats.csv", "write statistics to this file") addCIDR := flag.String("addcidr", "", "add this CIDR range to the data file [CIDR,name,url]") @@ -41,7 +43,7 @@ func main() { if rec == nil { log.Fatalf("Not found: %s", *lookup) } - fmt.Printf("[%s:%s] %s %s\n", rec.LeftDots, rec.RightDots, rec.Name, rec.URL) + fmt.Printf("[%s:%s] %s %s\n", net.IP(rec.Left[:]), net.IP(rec.Right[:]), rec.Name, rec.URL) return } @@ -89,6 +91,13 @@ func main() { } } + if *updateTor { + err = ipcat.UpdateTor(&set) + if err != nil { + log.Fatalf("Unable to update Tor IP ranges: %s", err) + } + } + if *addCIDR != "" { t := strings.Split(*addCIDR, ",") if len(t) != 3 { diff --git a/datacenters-stats.csv b/datacenters-stats.csv index 3f5bf934..45611313 100644 --- a/datacenters-stats.csv +++ b/datacenters-stats.csv @@ -1,10 +1,10 @@ Datacenter Name, Total IPs -Amazon AWS,29459456 +Amazon AWS,1542202570030687795110271325976 +Cloudflare Inc,1109194275199700726309617091584 +Google App Engine,9903520314283042199196141312 Microsoft Azure,13024127 Akamai,8145728 -Google App Engine,2431744 SoftLayer,1903104 -Cloudflare Inc,1786880 "ThePlanet.com Internet Services, Inc.",1638656 PEER 1,1462288 Ubiquity Server Solutions,1441792 diff --git a/datacenters.csv b/datacenters.csv index f595c020..af23de8e 100644 --- a/datacenters.csv +++ b/datacenters.csv @@ -54,6 +54,8 @@ 12.188.78.96,12.188.78.127,Media Temple,http://www.mediatemple.net/ 12.193.182.56,12.193.182.63,Ventu,http://Venyu.com/ 12.209.217.96,12.209.217.103,Media Temple,http://www.mediatemple.net/ +13.32.0.0,13.33.255.255,Amazon AWS,http://www.amazon.com/aws/ +13.35.0.0,13.35.255.255,Amazon AWS,http://www.amazon.com/aws/ 13.52.0.0,13.59.255.255,Amazon AWS,http://www.amazon.com/aws/ 13.64.0.0,13.71.255.255,Microsoft Azure,http://www.windowsazure.com/en-us/ 13.72.64.0,13.72.127.255,Microsoft Azure,http://www.windowsazure.com/en-us/ @@ -66,21 +68,24 @@ 13.124.0.0,13.127.255.255,Amazon AWS,http://www.amazon.com/aws/ 13.208.0.0,13.211.255.255,Amazon AWS,http://www.amazon.com/aws/ 13.228.0.0,13.239.255.255,Amazon AWS,http://www.amazon.com/aws/ +13.248.0.0,13.248.31.255,Amazon AWS,http://www.amazon.com/aws/ 13.250.0.0,13.251.255.255,Amazon AWS,http://www.amazon.com/aws/ 14.102.144.0,14.102.146.255,IP ServerOne,http://ipserverone.com/ 14.128.8.0,14.128.11.255,Servenet Solution Limited Partnership,http://servenet.co.th/ 18.130.0.0,18.130.255.255,Amazon AWS,http://www.amazon.com/aws/ 18.136.0.0,18.136.255.255,Amazon AWS,http://www.amazon.com/aws/ 18.144.0.0,18.145.255.255,Amazon AWS,http://www.amazon.com/aws/ +18.153.0.0,18.153.255.255,Amazon AWS,http://www.amazon.com/aws/ +18.175.0.0,18.175.255.255,Amazon AWS,http://www.amazon.com/aws/ 18.179.0.0,18.179.255.255,Amazon AWS,http://www.amazon.com/aws/ 18.182.0.0,18.182.255.255,Amazon AWS,http://www.amazon.com/aws/ 18.184.0.0,18.185.255.255,Amazon AWS,http://www.amazon.com/aws/ 18.188.0.0,18.188.255.255,Amazon AWS,http://www.amazon.com/aws/ 18.191.0.0,18.191.255.255,Amazon AWS,http://www.amazon.com/aws/ 18.194.0.0,18.197.255.255,Amazon AWS,http://www.amazon.com/aws/ -18.200.0.0,18.200.255.255,Amazon AWS,http://www.amazon.com/aws/ -18.204.0.0,18.228.255.255,Amazon AWS,http://www.amazon.com/aws/ +18.200.0.0,18.228.255.255,Amazon AWS,http://www.amazon.com/aws/ 18.231.0.0,18.237.255.255,Amazon AWS,http://www.amazon.com/aws/ +18.246.0.0,18.246.255.255,Amazon AWS,http://www.amazon.com/aws/ 18.253.0.0,18.253.255.255,Amazon AWS,http://www.amazon.com/aws/ 20.36.0.0,20.36.119.255,Microsoft Azure,http://www.windowsazure.com/en-us/ 20.36.128.0,20.37.63.255,Microsoft Azure,http://www.windowsazure.com/en-us/ @@ -132,6 +137,7 @@ 23.252.112.0,23.252.127.255,WebNX Internet Services,http://webnx.com/ 23.253.0.0,23.253.255.255,Rackspace,http://www.rackspace.com/ 23.254.0.0,23.254.127.255,B2 NET Solutions,http://www.servermania.com/ +27.0.0.0,27.0.3.255,Amazon AWS,http://www.amazon.com/aws/ 27.50.32.0,27.50.39.255,Hurricane Electric,http://www.he.net/ 27.131.64.0,27.131.127.254,Micron21,http://www.micron21.com/ 31.3.104.0,31.3.111.255,tuxis.nl,http://tuxis.nl/ @@ -187,8 +193,11 @@ 35.184.0.0,35.190.239.255,Google App Engine,https://cloud.google.com/appengine 35.192.0.0,35.199.191.255,Google App Engine,https://cloud.google.com/appengine 35.200.0.0,35.203.223.255,Google App Engine,https://cloud.google.com/appengine -35.203.240.0,35.207.255.255,Google App Engine,https://cloud.google.com/appengine -35.224.0.0,35.229.255.255,Google App Engine,https://cloud.google.com/appengine +35.203.232.0,35.207.255.255,Google App Engine,https://cloud.google.com/appengine +35.224.0.0,35.235.127.255,Google App Engine,https://cloud.google.com/appengine +35.235.192.0,35.235.207.255,Google App Engine,https://cloud.google.com/appengine +35.235.224.0,35.235.239.255,Google App Engine,https://cloud.google.com/appengine +35.236.0.0,35.241.63.255,Google App Engine,https://cloud.google.com/appengine 37.9.169.0,37.9.169.255,WebSupport,https://www.websupport.sk/ 37.9.224.0,37.9.228.223,seeweb.it,http://seeweb.it/ 37.10.0.0,37.10.127.255,Optimate Server,http://optimate-server.de/ @@ -363,6 +372,7 @@ 40.127.128.0,40.127.255.255,Microsoft Azure,http://www.windowsazure.com/en-us/ 42.1.60.0,42.1.63.255,Exa Bytes Network Sdn Bhd,http://exabytes.com/ 43.249.72.0,43.249.75.255,Fastly,https://www.fastly.com/ +43.250.192.0,43.250.193.255,Amazon AWS,http://www.amazon.com/aws/ 45.32.0.0,45.32.255.255,Choopa,https://www.choopa.com/ 45.33.0.0,45.33.127.255,Linode,http://www.linode.com/ 45.34.0.0,45.35.255.255,Psychz Networks,http://psychz.net/ @@ -468,16 +478,49 @@ 51.141.132.0,51.141.137.255,Microsoft Azure,http://www.windowsazure.com/en-us/ 51.141.144.0,51.145.255.255,Microsoft Azure,http://www.windowsazure.com/en-us/ 51.254.0.0,51.255.255.255,OVH,http://www.ovh.co.uk/ -52.0.0.0,52.45.255.255,Amazon AWS,http://www.amazon.com/aws/ -52.46.180.0,52.46.187.255,Amazon AWS,http://www.amazon.com/aws/ +52.0.0.0,52.46.159.255,Amazon AWS,http://www.amazon.com/aws/ +52.46.164.0,52.46.165.255,Amazon AWS,http://www.amazon.com/aws/ +52.46.168.0,52.46.187.255,Amazon AWS,http://www.amazon.com/aws/ +52.46.192.0,52.46.215.255,Amazon AWS,http://www.amazon.com/aws/ +52.46.220.0,52.46.243.255,Amazon AWS,http://www.amazon.com/aws/ 52.47.0.0,52.82.127.255,Amazon AWS,http://www.amazon.com/aws/ 52.82.176.0,52.82.183.255,Amazon AWS,http://www.amazon.com/aws/ -52.83.0.0,52.83.255.255,Amazon AWS,http://www.amazon.com/aws/ -52.86.0.0,52.91.255.255,Amazon AWS,http://www.amazon.com/aws/ -52.94.116.0,52.94.119.255,Amazon AWS,http://www.amazon.com/aws/ -52.94.248.0,52.94.248.239,Amazon AWS,http://www.amazon.com/aws/ +52.82.187.0,52.92.35.255,Amazon AWS,http://www.amazon.com/aws/ +52.92.39.0,52.92.91.255,Amazon AWS,http://www.amazon.com/aws/ +52.92.248.0,52.93.5.255,Amazon AWS,http://www.amazon.com/aws/ +52.93.8.0,52.93.11.255,Amazon AWS,http://www.amazon.com/aws/ +52.93.16.0,52.93.16.255,Amazon AWS,http://www.amazon.com/aws/ +52.93.17.16,52.93.17.17,Amazon AWS,http://www.amazon.com/aws/ +52.93.18.178,52.93.18.179,Amazon AWS,http://www.amazon.com/aws/ +52.93.19.236,52.93.19.237,Amazon AWS,http://www.amazon.com/aws/ +52.93.20.16,52.93.20.17,Amazon AWS,http://www.amazon.com/aws/ +52.93.21.14,52.93.21.15,Amazon AWS,http://www.amazon.com/aws/ +52.93.34.56,52.93.34.57,Amazon AWS,http://www.amazon.com/aws/ +52.93.37.222,52.93.37.223,Amazon AWS,http://www.amazon.com/aws/ +52.93.48.22,52.93.48.23,Amazon AWS,http://www.amazon.com/aws/ +52.93.51.28,52.93.51.29,Amazon AWS,http://www.amazon.com/aws/ +52.93.112.34,52.93.112.35,Amazon AWS,http://www.amazon.com/aws/ +52.93.249.0,52.93.249.255,Amazon AWS,http://www.amazon.com/aws/ +52.94.0.0,52.94.17.255,Amazon AWS,http://www.amazon.com/aws/ +52.94.19.0,52.94.20.255,Amazon AWS,http://www.amazon.com/aws/ +52.94.22.0,52.94.29.255,Amazon AWS,http://www.amazon.com/aws/ +52.94.32.0,52.94.69.255,Amazon AWS,http://www.amazon.com/aws/ +52.94.72.0,52.94.127.255,Amazon AWS,http://www.amazon.com/aws/ +52.94.192.0,52.94.198.159,Amazon AWS,http://www.amazon.com/aws/ +52.94.199.0,52.94.200.255,Amazon AWS,http://www.amazon.com/aws/ +52.94.204.0,52.94.248.239,Amazon AWS,http://www.amazon.com/aws/ 52.94.249.0,52.94.249.47,Amazon AWS,http://www.amazon.com/aws/ -52.94.249.64,52.94.249.127,Amazon AWS,http://www.amazon.com/aws/ +52.94.249.64,52.94.249.143,Amazon AWS,http://www.amazon.com/aws/ +52.94.252.0,52.95.28.255,Amazon AWS,http://www.amazon.com/aws/ +52.95.30.0,52.95.31.255,Amazon AWS,http://www.amazon.com/aws/ +52.95.34.0,52.95.40.255,Amazon AWS,http://www.amazon.com/aws/ +52.95.48.0,52.95.51.255,Amazon AWS,http://www.amazon.com/aws/ +52.95.56.0,52.95.138.255,Amazon AWS,http://www.amazon.com/aws/ +52.95.142.0,52.95.150.255,Amazon AWS,http://www.amazon.com/aws/ +52.95.154.0,52.95.159.255,Amazon AWS,http://www.amazon.com/aws/ +52.95.163.0,52.95.171.255,Amazon AWS,http://www.amazon.com/aws/ +52.95.192.0,52.95.207.255,Amazon AWS,http://www.amazon.com/aws/ +52.95.212.0,52.95.215.255,Amazon AWS,http://www.amazon.com/aws/ 52.95.225.0,52.95.225.255,Amazon AWS,http://www.amazon.com/aws/ 52.95.227.0,52.95.227.255,Amazon AWS,http://www.amazon.com/aws/ 52.95.240.0,52.95.255.159,Amazon AWS,http://www.amazon.com/aws/ @@ -503,13 +546,22 @@ 52.115.40.0,52.115.45.255,Microsoft Azure,http://www.windowsazure.com/en-us/ 52.115.48.0,52.115.53.255,Microsoft Azure,http://www.windowsazure.com/en-us/ 52.115.56.0,52.115.61.255,Microsoft Azure,http://www.windowsazure.com/en-us/ -52.119.205.0,52.119.205.255,Amazon AWS,http://www.amazon.com/aws/ +52.119.160.0,52.119.199.255,Amazon AWS,http://www.amazon.com/aws/ +52.119.205.0,52.119.247.255,Amazon AWS,http://www.amazon.com/aws/ +52.119.252.0,52.119.255.255,Amazon AWS,http://www.amazon.com/aws/ 52.136.0.0,52.136.7.255,Microsoft Azure,http://www.windowsazure.com/en-us/ 52.136.16.0,52.136.26.255,Microsoft Azure,http://www.windowsazure.com/en-us/ 52.136.28.0,52.136.30.255,Microsoft Azure,http://www.windowsazure.com/en-us/ 52.136.32.0,52.143.198.255,Microsoft Azure,http://www.windowsazure.com/en-us/ 52.143.208.0,52.143.219.255,Microsoft Azure,http://www.windowsazure.com/en-us/ 52.143.224.0,52.143.255.255,Microsoft Azure,http://www.windowsazure.com/en-us/ +52.144.192.0,52.144.193.191,Amazon AWS,http://www.amazon.com/aws/ +52.144.194.0,52.144.195.63,Amazon AWS,http://www.amazon.com/aws/ +52.144.196.192,52.144.196.255,Amazon AWS,http://www.amazon.com/aws/ +52.144.208.64,52.144.211.63,Amazon AWS,http://www.amazon.com/aws/ +52.144.211.128,52.144.211.191,Amazon AWS,http://www.amazon.com/aws/ +52.144.224.64,52.144.224.191,Amazon AWS,http://www.amazon.com/aws/ +52.144.225.64,52.144.225.191,Amazon AWS,http://www.amazon.com/aws/ 52.146.0.0,52.165.48.15,Microsoft Azure,http://www.windowsazure.com/en-us/ 52.165.49.0,52.165.49.255,Microsoft Azure,http://www.windowsazure.com/en-us/ 52.165.56.0,52.165.104.191,Microsoft Azure,http://www.windowsazure.com/en-us/ @@ -528,8 +580,9 @@ 52.185.120.0,52.191.104.31,Microsoft Azure,http://www.windowsazure.com/en-us/ 52.191.105.0,52.191.106.255,Microsoft Azure,http://www.windowsazure.com/en-us/ 52.191.112.0,52.191.255.255,Microsoft Azure,http://www.windowsazure.com/en-us/ -52.192.0.0,52.215.255.255,Amazon AWS,http://www.amazon.com/aws/ -52.220.0.0,52.222.127.255,Amazon AWS,http://www.amazon.com/aws/ +52.192.0.0,52.219.47.255,Amazon AWS,http://www.amazon.com/aws/ +52.219.56.0,52.219.111.255,Amazon AWS,http://www.amazon.com/aws/ +52.220.0.0,52.222.255.255,Amazon AWS,http://www.amazon.com/aws/ 52.224.0.0,52.225.136.79,Microsoft Azure,http://www.windowsazure.com/en-us/ 52.225.137.0,52.225.137.255,Microsoft Azure,http://www.windowsazure.com/en-us/ 52.225.144.0,52.226.255.255,Microsoft Azure,http://www.windowsazure.com/en-us/ @@ -559,13 +612,26 @@ 52.253.224.0,52.253.239.255,Microsoft Azure,http://www.windowsazure.com/en-us/ 52.254.0.0,52.255.255.255,Microsoft Azure,http://www.windowsazure.com/en-us/ 54.64.0.0,54.95.255.255,Amazon AWS,http://www.amazon.com/aws/ -54.144.0.0,54.179.255.255,Amazon AWS,http://www.amazon.com/aws/ -54.183.0.0,54.191.255.255,Amazon AWS,http://www.amazon.com/aws/ -54.193.0.0,54.221.255.255,Amazon AWS,http://www.amazon.com/aws/ -54.222.32.0,54.222.39.255,Amazon AWS,http://www.amazon.com/aws/ -54.222.128.0,54.229.255.255,Amazon AWS,http://www.amazon.com/aws/ -54.232.0.0,54.238.255.255,Amazon AWS,http://www.amazon.com/aws/ -54.241.0.0,54.255.255.255,Amazon AWS,http://www.amazon.com/aws/ +54.144.0.0,54.222.39.255,Amazon AWS,http://www.amazon.com/aws/ +54.222.48.0,54.222.51.255,Amazon AWS,http://www.amazon.com/aws/ +54.222.57.0,54.222.58.15,Amazon AWS,http://www.amazon.com/aws/ +54.222.128.0,54.231.207.255,Amazon AWS,http://www.amazon.com/aws/ +54.231.224.0,54.231.253.255,Amazon AWS,http://www.amazon.com/aws/ +54.232.0.0,54.239.1.31,Amazon AWS,http://www.amazon.com/aws/ +54.239.1.48,54.239.1.79,Amazon AWS,http://www.amazon.com/aws/ +54.239.2.0,54.239.39.255,Amazon AWS,http://www.amazon.com/aws/ +54.239.48.0,54.239.63.255,Amazon AWS,http://www.amazon.com/aws/ +54.239.96.0,54.239.96.255,Amazon AWS,http://www.amazon.com/aws/ +54.239.98.0,54.239.101.255,Amazon AWS,http://www.amazon.com/aws/ +54.239.104.0,54.239.105.255,Amazon AWS,http://www.amazon.com/aws/ +54.239.106.252,54.239.106.253,Amazon AWS,http://www.amazon.com/aws/ +54.239.107.252,54.239.107.253,Amazon AWS,http://www.amazon.com/aws/ +54.239.108.0,54.239.111.255,Amazon AWS,http://www.amazon.com/aws/ +54.239.116.0,54.239.223.255,Amazon AWS,http://www.amazon.com/aws/ +54.240.128.0,54.240.200.255,Amazon AWS,http://www.amazon.com/aws/ +54.240.202.0,54.240.223.255,Amazon AWS,http://www.amazon.com/aws/ +54.240.225.0,54.240.235.255,Amazon AWS,http://www.amazon.com/aws/ +54.240.244.0,54.255.255.255,Amazon AWS,http://www.amazon.com/aws/ 58.64.185.0,58.64.185.255,NWT iDC Data Service,http://www.newworldtel.com/ 59.151.0.0,59.151.127.255,21vianet,http://21vianet.com/ 59.151.128.0,59.151.191.255,Akamai,http://akamai.com/ @@ -587,6 +653,7 @@ 62.210.128.0,62.210.255.255,Iliad-Entreprises Business Hosting,http://iliad-entreprises.fr/ 62.212.64.0,62.212.95.255,Leaseweb,http://www.leaseweb.com/ 62.233.64.0,62.233.127.255,iomart,http://www.iomart.com/ +63.32.0.0,63.35.255.255,Amazon AWS,http://www.amazon.com/aws/ 63.131.128.0,63.131.159.255,Datapipe,http://www.datapipe.com/ 63.131.224.0,63.131.239.255,TierPoint,http://tierpoint.com/ 63.140.0.0,63.140.15.255,Fortress Integrated Technologies,http://fortressitx.com/ @@ -676,6 +743,7 @@ 64.246.0.0,64.246.63.255,"ThePlanet.com Internet Services, Inc.",http://theplanet.com 64.247.192.0,64.247.223.255,LightEdge,http://www.lightedge.com 64.251.0.0,64.251.31.255,ServerPronto,http://www.serverpronto.com/ +64.252.64.0,64.252.127.255,Amazon AWS,http://www.amazon.com/aws/ 65.17.192.0,65.17.255.255,Datapipe,http://www.datapipe.com/ 65.19.128.0,65.19.191.255,Hurricane Electric,http://www.he.net/ 65.36.128.0,65.36.255.255,HostMySite.com,http://www.webmysite.com/ @@ -968,7 +1036,9 @@ 70.39.64.0,70.39.127.255,SharkTECH Internet Services,http://sharktech.net/ 70.40.192.0,70.40.223.255,Bluehost.com,http://www.bluehost.com/ 70.84.0.0,70.87.255.255,"ThePlanet.com Internet Services, Inc.",http://theplanet.com +70.132.0.0,70.132.63.255,Amazon AWS,http://www.amazon.com/aws/ 71.6.128.0,71.6.255.255,cari.net,http://cari.net/ +71.152.0.0,71.152.127.255,Amazon AWS,http://www.amazon.com/aws/ 72.1.96.0,72.1.127.255,latisys,http://www.latisys.com/ 72.1.240.0,72.1.255.255,ndchost.com,http://www.ndchost.com/ 72.3.128.0,72.3.255.255,Rackspace,http://www.rackspace.com/ @@ -985,6 +1055,7 @@ 72.18.192.0,72.18.207.255,Premia Networks Corporation,http://www.premianet.com/ 72.20.0.0,72.20.63.255,Staminus Communications,http://staminus.net/ 72.21.32.0,72.21.63.255,Layered Technologies Inc,http://www.layeredtech.com/ +72.21.192.0,72.21.223.255,Amazon AWS,http://www.amazon.com/aws/ 72.22.66.0,72.22.67.255,The Endurance International Group Inc,http://www.enduranceinternational.com/ 72.22.69.0,72.22.73.255,The Endurance International Group Inc,http://www.enduranceinternational.com/ 72.22.75.0,72.22.76.255,The Endurance International Group Inc,http://www.enduranceinternational.com/ @@ -1282,6 +1353,7 @@ 87.233.0.0,87.233.255.255,trueserver.nl,http://trueserver.nl/ 87.236.215.0,87.236.215.255,1 Gbits,https://1gbits.com/ 87.237.208.0,87.237.215.255,FSdata,http://fsdata.se/ +87.238.80.0,87.238.87.255,Amazon AWS,http://www.amazon.com/aws/ 87.238.168.0,87.238.175.255,duocast,http://duocast.nl/ 87.242.64.0,87.242.127.255,masterhost.ru,http://masterhost.ru/ 87.253.128.0,87.253.159.255,transip,https://www.transip.nl/ @@ -1572,8 +1644,10 @@ 98.158.144.0,98.158.159.255,US Colo,http://uscolo.com/ 98.158.176.0,98.158.191.255,Midphase,http://www.midphase.com/ 98.158.224.0,98.158.239.255,AccelerateBiz Inc.,http://www.acceleratebiz.com/ +99.79.0.0,99.81.255.255,Amazon AWS,http://www.amazon.com/aws/ 99.192.128.0,99.192.255.255,MojoHost,http://www.mojohost.com 99.198.96.0,99.198.127.255,SingleHop,http://www.singlehop.com/ +100.20.0.0,100.31.255.255,Amazon AWS,http://www.amazon.com/aws/ 100.42.64.0,100.42.79.255,multacom.com,http://multacom.com/ 100.42.208.0,100.42.223.255,WebNX Internet Services,http://webnx.com/ 101.0.64.0,101.0.127.255,Digital Pacific,http://www.digitalpacific.com.au/ @@ -1589,6 +1663,7 @@ 103.5.12.0,103.5.13.255,OVH,http://www.ovh.co.uk/ 103.6.192.0,103.6.195.255,easyhost.com.hk,http://easyhost.com.hk/ 103.8.124.0,103.8.127.255,CtrlS,http://www.ctrls.in/ +103.8.172.0,103.8.175.255,Amazon AWS,http://www.amazon.com/aws/ 103.11.152.0,103.11.155.255,Web Werks,http://www.web-werks.com/ 103.11.244.0,103.11.247.255,easyhost.com.hk,http://easyhost.com.hk/ 103.21.58.0,103.21.59.255,Confluence Networks Inc,http://confluence-networks.com/ @@ -1602,6 +1677,7 @@ 103.197.148.0,103.197.148.255,Trabia,https://www.trabia.com/ 103.244.50.0,103.244.50.255,Fastly,https://www.fastly.com/ 103.245.222.0,103.245.224.255,Fastly,https://www.fastly.com/ +103.246.148.0,103.246.151.255,Amazon AWS,http://www.amazon.com/aws/ 103.246.248.0,103.246.248.255,quickweb.co.nz,http://quickweb.co.nz/ 103.246.250.0,103.246.251.255,quickweb.co.nz,http://quickweb.co.nz/ 104.16.0.0,104.31.255.255,Cloudflare Inc,https://www.cloudflare.com/ @@ -1773,7 +1849,7 @@ 128.204.208.0,128.204.215.255,ecritel.net,http://www.ecritel.net/ 130.185.144.0,130.185.151.255,Titan Internet Ltd,http://www.titaninternet.co.uk/index.cfm 130.185.152.0,130.185.155.255,webexxpurts.com,http://webexxpurts.com/ -130.211.8.0,130.211.255.255,Google App Engine,https://cloud.google.com/appengine +130.211.4.0,130.211.255.255,Google App Engine,https://cloud.google.com/appengine 131.0.72.0,131.0.75.255,Cloudflare Inc,https://www.cloudflare.com/ 131.253.12.8,131.253.12.31,Microsoft Azure,http://www.windowsazure.com/en-us/ 131.253.12.36,131.253.12.79,Microsoft Azure,http://www.windowsazure.com/en-us/ @@ -1815,6 +1891,7 @@ 142.54.160.0,142.54.191.255,Data Shack,https://www.datashack.net/ 142.91.0.0,142.91.255.255,Ubiquity Server Solutions,http://www.ubiquityservers.com/ 142.234.0.0,142.234.255.255,Ubiquity Server Solutions,http://www.ubiquityservers.com/ +143.204.0.0,143.204.255.255,Amazon AWS,http://www.amazon.com/aws/ 144.217.0.0,144.217.255.255,OVH CA,https://www.ovh.com/ca/en/ 146.0.72.0,146.0.79.255,HostKey,http://www.hostkey.com/ 146.0.231.216,146.0.231.223,AlphaRacks,https://www.alpharacks.com/ @@ -1966,6 +2043,7 @@ 169.56.64.0,169.56.159.255,SoftLayer,http://www.softlayer.com/ 169.57.0.0,169.57.255.255,SoftLayer,http://www.softlayer.com/ 172.64.0.0,172.71.255.255,Cloudflare Inc,https://www.cloudflare.com/ +172.96.97.0,172.96.98.255,Amazon AWS,http://www.amazon.com/aws/ 172.96.128.0,172.96.135.255,Versaweb,https://versaweb.com/ 172.98.64.0,172.98.95.255,Total Server Solutions,http://totalserversolutions.com/ 172.111.64.0,172.111.127.255,Fastly,https://www.fastly.com/ @@ -2055,7 +2133,8 @@ 176.28.0.0,176.28.63.255,Host Europe,http://www.hosteurope.de/ 176.28.96.0,176.28.127.255,acens Technologies S.L.,http://www.acens.com/ 176.31.0.0,176.31.255.255,OVH,http://www.ovh.co.uk/ -176.32.64.0,176.32.95.255,Amazon AWS,http://www.amazon.com/aws/ +176.32.64.0,176.32.123.255,Amazon AWS,http://www.amazon.com/aws/ +176.32.125.0,176.32.125.127,Amazon AWS,http://www.amazon.com/aws/ 176.34.0.0,176.34.255.255,Amazon AWS,http://www.amazon.com/aws/ 176.53.0.0,176.53.127.255,Radore Hosting,http://as42926.net/ 176.56.56.0,176.56.56.15,nimbushosting.co.uk,http://nimbushosting.co.uk/ @@ -2133,6 +2212,7 @@ 176.227.220.240,176.227.221.255,Redstation Limited,http://redstation.com/ 177.55.96.0,177.55.127.255,redehost.com.br,http://www.redehost.com.br/ 177.71.128.0,177.71.255.255,Amazon AWS,http://www.amazon.com/aws/ +177.72.240.0,177.72.247.255,Amazon AWS,http://www.amazon.com/aws/ 177.137.16.0,177.137.23.255,ipglobe.net,https://www.ipglobe.net/ 178.17.160.0,178.17.161.255,Trabia Network,https://www.trabia.com/ 178.17.168.0,178.17.175.255,Trabia Network,https://www.trabia.com/ @@ -2166,6 +2246,7 @@ 178.217.80.0,178.217.87.255,h4hosting.eu,http://h4hosting.eu/ 178.217.184.0,178.217.191.255,hosteam.pl,http://hosteam.pl/ 178.218.208.0,178.218.223.255,eserver.ru,http://www.eserver.ru/ +178.236.0.0,178.236.15.255,Amazon AWS,http://www.amazon.com/aws/ 178.236.64.0,178.236.79.255,Excellent Hosting Sweden AB,http://www.excellent-hosting.se/ 178.238.32.0,178.238.47.255,Master Internet S.R.O.,http://www.master.cz/ 178.238.96.0,178.238.111.255,datahouse.nl,http://datahouse.nl/ @@ -2268,6 +2349,7 @@ 185.108.84.0,185.108.85.255,Ardis Russia,https://ardis.ru/ 185.121.120.0,185.121.121.255,Trabia Network,https://www.trabia.com/ 185.139.144.0,185.139.147.255,BHost Inc,https://www.bhost.net/ +185.143.16.0,185.143.16.255,Amazon AWS,http://www.amazon.com/aws/ 185.158.112.0,185.158.115.255,IP Server,https://www.ipserver.su/ 186.227.162.128,186.227.162.191,Server Green,http://servergreen.com.br/ 186.251.128.0,186.251.139.255,ipglobe.net,https://www.ipglobe.net/ @@ -2759,6 +2841,7 @@ 203.19.59.0,203.19.59.255,Digital Pacific,http://www.digitalpacific.com.au/ 203.57.145.11,203.57.145.12,Fastly,https://www.fastly.com/ 203.77.184.0,203.77.191.255,Limelight Networks Inc,http://www.limelight.com/ +203.83.220.0,203.83.223.255,Amazon AWS,http://www.amazon.com/aws/ 203.84.240.0,203.84.255.255,kinx.net,http://idc.kinx.net/ 203.123.59.0,203.123.59.255,Digital Pacific,http://www.digitalpacific.com.au/ 203.142.0.0,203.142.31.255,webvisions.com,http://webvisions.com/ @@ -2802,6 +2885,8 @@ 204.232.128.0,204.232.255.255,Rackspace,http://www.rackspace.com/ 204.236.128.0,204.236.255.255,Amazon AWS,http://www.amazon.com/aws/ 204.246.32.0,204.246.63.255,Gearhost,http://www.gearhost.com/ +204.246.160.0,204.246.171.255,Amazon AWS,http://www.amazon.com/aws/ +204.246.174.0,204.246.191.255,Amazon AWS,http://www.amazon.com/aws/ 205.134.160.0,205.134.191.255,AiNET,http://www.ai.net/ 205.164.0.0,205.164.63.255,EGIHosting.com,http://www.egihosting.com/ 205.185.112.0,205.185.127.255,buyvm.net,http://buyvm.net/?from=frantech @@ -2813,6 +2898,7 @@ 205.214.64.0,205.214.95.255,latisys,http://www.latisys.com/ 205.234.96.0,205.234.111.255,Virtacore Systems,http://www.virtacore.com/ 205.234.128.0,205.234.255.255,ServerCentral,http://www.servercentral.net/ +205.251.192.0,205.251.254.255,Amazon AWS,http://www.amazon.com/aws/ 206.41.112.0,206.41.127.255,RisingNet,http://risingnet.net/ 206.41.192.0,206.41.223.255,Datapoint,http://www.datapointinc.com/ 206.51.224.0,206.51.239.255,Hivelocity Hosting,http://www.hivelocity.net/ @@ -2878,6 +2964,7 @@ 207.148.224.0,207.148.255.255,The Endurance International Group Inc,http://www.enduranceinternational.com/ 207.158.0.0,207.158.63.255,American Internet Services,http://americanis.net/ 207.159.128.0,207.159.159.255,PEER 1,http://www.peer1.com/ +207.171.160.0,207.171.191.255,Amazon AWS,http://www.amazon.com/aws/ 207.198.64.0,207.198.127.255,PEER 1,http://www.peer1.com/ 207.204.224.0,207.204.255.255,Reliable Hosting,http://reliablehosting.com/ 207.210.192.0,207.210.255.255,colo4dallas.com,http://colo4dallas.com/ @@ -3194,6 +3281,7 @@ 216.130.160.0,216.130.191.255,Webair Internet Development Inc,http://www.webair.com/ 216.131.64.0,216.131.127.255,Reliable Hosting,http://reliablehosting.com/ 216.134.192.0,216.134.223.255,Peak10,http://www.peak10.com/ +216.137.32.0,216.137.63.255,Amazon AWS,http://www.amazon.com/aws/ 216.137.64.0,216.137.95.255,LightEdge,http://www.lightedge.com 216.144.224.0,216.144.239.255,Secure Private Network,http://www.securedprivatenetwork.net/ 216.144.240.0,216.144.255.255,Limestone Networks,http://www.limestonenetworks.com/ @@ -3288,3 +3376,219 @@ 223.25.240.0,223.25.243.255,Gigabit Hosting Sdn Bhd,http://thegigabit.com/ 223.25.245.0,223.25.247.255,Gigabit Hosting Sdn Bhd,http://thegigabit.com/ 223.27.168.0,223.27.175.255,Voxel,http://www.voxel.net/ +2400:6500:0:7000::,2400:6500:0:72ff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2400:6500:0:7400::,2400:6500:0:75ff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2400:6500:100:7100::,2400:6500:100:72ff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2400:6500:ff00::,2400:6500:ff00:0:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2400:6700:ff00::,2400:6700:ff00:0:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2400:cb00::,2400:cb00:ffff:ffff:ffff:ffff:ffff:ffff,Cloudflare Inc,https://www.cloudflare.com/ +2403:b300:ff00::,2403:b300:ff00:0:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2405:8100::,2405:8100:ffff:ffff:ffff:ffff:ffff:ffff,Cloudflare Inc,https://www.cloudflare.com/ +2405:b500::,2405:b500:ffff:ffff:ffff:ffff:ffff:ffff,Cloudflare Inc,https://www.cloudflare.com/ +2406:da00:2000::,2406:da00:20ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:da00:4000::,2406:da00:40ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:da00:6000::,2406:da00:60ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:da00:8000::,2406:da00:80ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:da00:a000::,2406:da00:a0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:da00:c000::,2406:da00:c0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:da00:ff00::,2406:da00:ff00:0:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:da12::,2406:da12:fff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:da14::,2406:da14:fff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:da16::,2406:da16:fff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:da18::,2406:da18:fff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:da1a::,2406:da1a:fff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:da1c::,2406:da1c:fff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:daa0:2000::,2406:daa0:20ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:daa0:4000::,2406:daa0:40ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:daa0:6000::,2406:daa0:60ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:daa0:8000::,2406:daa0:80ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:daa0:a000::,2406:daa0:a0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:daa0:c000::,2406:daa0:c0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:daf8:2000::,2406:daf8:20ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:daf8:4000::,2406:daf8:40ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:daf8:6000::,2406:daf8:60ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:daf8:8000::,2406:daf8:80ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:daf8:a000::,2406:daf8:a0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:daf8:c000::,2406:daf8:c0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:daf9:2000::,2406:daf9:20ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:daf9:4000::,2406:daf9:40ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:daf9:6000::,2406:daf9:60ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:daf9:8000::,2406:daf9:80ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:daf9:a000::,2406:daf9:a0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:daf9:c000::,2406:daf9:c0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:dafa:2000::,2406:dafa:20ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:dafa:4000::,2406:dafa:40ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:dafa:6000::,2406:dafa:60ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:dafa:8000::,2406:dafa:80ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:dafa:a000::,2406:dafa:a0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:dafa:c000::,2406:dafa:c0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:dafc:2000::,2406:dafc:20ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:dafc:4000::,2406:dafc:40ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:dafc:6000::,2406:dafc:60ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:dafc:8000::,2406:dafc:80ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:dafc:a000::,2406:dafc:a0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:dafc:c000::,2406:dafc:c0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:dafe:2000::,2406:dafe:20ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:dafe:4000::,2406:dafe:40ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:dafe:6000::,2406:dafe:60ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:dafe:8000::,2406:dafe:80ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:dafe:a000::,2406:dafe:a0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:dafe:c000::,2406:dafe:c0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:daff:2000::,2406:daff:20ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:daff:4000::,2406:daff:40ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:daff:6000::,2406:daff:60ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:daff:8000::,2406:daff:80ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:daff:a000::,2406:daff:a0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2406:daff:c000::,2406:daff:c0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +240f:8000:4000::,240f:8000:40ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +240f:8000:8000::,240f:8000:80ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +240f:8014::,240f:8014:fff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +240f:8018::,240f:8018:fff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +240f:80a0:4000::,240f:80a0:40ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +240f:80a0:8000::,240f:80a0:80ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +240f:80f8:4000::,240f:80f8:40ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +240f:80f8:8000::,240f:80f8:80ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +240f:80f9:4000::,240f:80f9:40ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +240f:80f9:8000::,240f:80f9:80ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +240f:80fa:4000::,240f:80fa:40ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +240f:80fa:8000::,240f:80fa:80ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +240f:80fc:4000::,240f:80fc:40ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +240f:80fc:8000::,240f:80fc:80ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +240f:80fe:4000::,240f:80fe:40ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +240f:80fe:8000::,240f:80fe:80ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +240f:80ff:4000::,240f:80ff:40ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +240f:80ff:8000::,240f:80ff:80ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1900::,2600:1900:1fff:ffff:ffff:ffff:ffff:ffff,Google App Engine,https://cloud.google.com/appengine +2600:1f00:1000::,2600:1f00:10ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1f00:2000::,2600:1f00:20ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1f00:4000::,2600:1f00:40ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1f00:5000::,2600:1f00:50ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1f00:6000::,2600:1f00:60ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1f00:8000::,2600:1f00:80ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1f00:c000::,2600:1f00:c0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1f00:e000::,2600:1f00:e0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1f11::,2600:1f11:fff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1f12::,2600:1f12:fff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1f14::,2600:1f14:1fff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1f15::,2600:1f16:fff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1f18::,2600:1f18:7fff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1f1c::,2600:1f1c:fff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1f1e::,2600:1f1e:fff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1fa0:1000::,2600:1fa0:10ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1fa0:2000::,2600:1fa0:20ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1fa0:4000::,2600:1fa0:40ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1fa0:5000::,2600:1fa0:50ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1fa0:6000::,2600:1fa0:60ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1fa0:8000::,2600:1fa0:80ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1fa0:c000::,2600:1fa0:c0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1fa0:e000::,2600:1fa0:e0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ff8:1000::,2600:1ff8:10ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ff8:2000::,2600:1ff8:20ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ff8:4000::,2600:1ff8:40ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ff8:5000::,2600:1ff8:60ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ff8:8000::,2600:1ff8:80ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ff8:c000::,2600:1ff8:c0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ff8:e000::,2600:1ff8:e0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ff9:1000::,2600:1ff9:10ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ff9:2000::,2600:1ff9:20ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ff9:4000::,2600:1ff9:40ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ff9:5000::,2600:1ff9:50ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ff9:6000::,2600:1ff9:60ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ff9:8000::,2600:1ff9:80ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ff9:c000::,2600:1ff9:c0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ff9:e000::,2600:1ff9:e0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ffa:1000::,2600:1ffa:10ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ffa:2000::,2600:1ffa:20ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ffa:4000::,2600:1ffa:40ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ffa:5000::,2600:1ffa:50ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ffa:6000::,2600:1ffa:60ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ffa:8000::,2600:1ffa:80ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ffa:c000::,2600:1ffa:c0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ffa:e000::,2600:1ffa:e0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ffc:1000::,2600:1ffc:10ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ffc:2000::,2600:1ffc:20ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ffc:4000::,2600:1ffc:40ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ffc:5000::,2600:1ffc:50ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ffc:6000::,2600:1ffc:60ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ffc:8000::,2600:1ffc:80ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ffc:c000::,2600:1ffc:c0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ffc:e000::,2600:1ffc:e0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ffe:1000::,2600:1ffe:10ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ffe:2000::,2600:1ffe:20ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ffe:4000::,2600:1ffe:40ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ffe:5000::,2600:1ffe:50ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ffe:6000::,2600:1ffe:60ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ffe:8000::,2600:1ffe:80ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ffe:c000::,2600:1ffe:c0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1ffe:e000::,2600:1ffe:e0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1fff:1000::,2600:1fff:10ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1fff:2000::,2600:1fff:20ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1fff:4000::,2600:1fff:40ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1fff:5000::,2600:1fff:50ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1fff:6000::,2600:1fff:60ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1fff:8000::,2600:1fff:80ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1fff:c000::,2600:1fff:c0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:1fff:e000::,2600:1fff:e0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2600:9000::,2600:900f:ffff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2606:4700::,2606:4700:ffff:ffff:ffff:ffff:ffff:ffff,Cloudflare Inc,https://www.cloudflare.com/ +2620:107:300f::,2620:107:300f:0:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2620:107:4000:5::,2620:107:4000:5:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2620:107:4000:7000::,2620:107:4000:72ff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2620:107:4000:7400::,2620:107:4000:74ff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2620:107:4000:7700::,2620:107:4000:78ff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2620:107:4007::,2620:107:4007:0:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2620:108:7000::,2620:108:700f:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2620:108:d000::,2620:108:d00f:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2803:f800::,2803:f800:ffff:ffff:ffff:ffff:ffff:ffff,Cloudflare Inc,https://www.cloudflare.com/ +2804:800:0:7000::,2804:800:0:70ff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2804:800:ff00::,2804:800:ff00:0:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a01:578:0:7000::,2a01:578:0:72ff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a01:578:3::,2a01:578:3:0:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a01:578:13::,2a01:578:13:0:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d000:2000::,2a05:d000:20ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d000:4000::,2a05:d000:40ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d000:6000::,2a05:d000:60ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d000:8000::,2a05:d000:80ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d000:c000::,2a05:d000:c0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d012::,2a05:d012:fff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d014::,2a05:d014:fff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d016::,2a05:d016:fff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d018::,2a05:d018:fff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d01c::,2a05:d01c:fff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d050:2000::,2a05:d050:20ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d050:4000::,2a05:d050:40ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d050:6000::,2a05:d050:60ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d050:8000::,2a05:d050:80ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d050:c000::,2a05:d050:c0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d078:2000::,2a05:d078:20ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d078:4000::,2a05:d078:40ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d078:6000::,2a05:d078:60ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d078:8000::,2a05:d078:80ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d078:c000::,2a05:d078:c0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d079:2000::,2a05:d079:20ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d079:4000::,2a05:d079:40ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d079:6000::,2a05:d079:60ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d079:8000::,2a05:d079:80ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d079:c000::,2a05:d079:c0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d07a:2000::,2a05:d07a:20ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d07a:4000::,2a05:d07a:40ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d07a:6000::,2a05:d07a:60ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d07a:8000::,2a05:d07a:80ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d07a:c000::,2a05:d07a:c0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d07c:2000::,2a05:d07c:20ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d07c:4000::,2a05:d07c:40ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d07c:6000::,2a05:d07c:60ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d07c:8000::,2a05:d07c:80ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d07c:c000::,2a05:d07c:c0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d07e:2000::,2a05:d07e:20ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d07e:4000::,2a05:d07e:40ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d07e:6000::,2a05:d07e:60ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d07e:8000::,2a05:d07e:80ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d07e:c000::,2a05:d07e:c0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d07f:2000::,2a05:d07f:20ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d07f:4000::,2a05:d07f:40ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d07f:6000::,2a05:d07f:60ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d07f:8000::,2a05:d07f:80ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a05:d07f:c000::,2a05:d07f:c0ff:ffff:ffff:ffff:ffff:ffff,Amazon AWS,http://www.amazon.com/aws/ +2a06:98c0::,2a06:98c7:ffff:ffff:ffff:ffff:ffff:ffff,Cloudflare Inc,https://www.cloudflare.com/ +2c0f:f248::,2c0f:f248:ffff:ffff:ffff:ffff:ffff:ffff,Cloudflare Inc,https://www.cloudflare.com/ diff --git a/ipset.go b/ipset.go index bec5eb89..6760659d 100644 --- a/ipset.go +++ b/ipset.go @@ -1,66 +1,103 @@ package ipcat import ( + "bytes" "encoding/csv" "fmt" "io" + "math/big" "net" "sort" "strings" ) -// generic utility function -// returns 0 if not valid -func dots2uint32(dots string) uint32 { - ip := net.ParseIP(dots) - if ip == nil { - return 0 +// IPParse converts a string IP address to a byte slice, or nil on error. +func IPParse(dots string) []byte { + return net.ParseIP(dots) +} + +// IPString converts a byte slice representing an IP address to a string. +func IPString(ip []byte) string { + return net.IP(ip).String() +} + +// IPIsAdjacent returns true if the first IP + 1 equals the second. +func IPIsAdjacent(bytes, bytesinc []byte) bool { + if len(bytes) != len(bytesinc) { + return false } - ip = ip.To4() - if ip == nil { - return 0 + + // Iterate backwards + var carry byte = 1 + for i := len(bytes) - 1; i >= 0; i-- { + inc := bytes[i] + carry + if inc != bytesinc[i] { + return false + } + if carry == 1 && bytes[i] == 0xff { + carry = 1 + } else { + carry = 0 + } } - return uint32(ip[0])<<24 + uint32(ip[1])<<16 + uint32(ip[2])<<8 + uint32(ip[3]) + + return true } // CIDR2Range converts a CIDR to a dotted IP address pair, or empty strings and error // -// Generic.. does not care if ipv4 or ipv6 +// Generic.. does not care if ipv4 or ipv6 (for sure this time) func CIDR2Range(c string) (string, string, error) { - left, ipnet, err := net.ParseCIDR(c) + // Parse CIDR notation + addr, network, err := net.ParseCIDR(c) if err != nil { return "", "", err } - left4 := left.To4() - if left4 == nil { - return "", "", nil + + // Create new bounds addresses + left := make(net.IP, 16) + right := make(net.IP, 16) + + // Pad mask to 16 bytes with 1 bits + mask := make([]byte, 16) + for i := 0; i < 16; i++ { + mask[i] = 0xff } - right := net.IPv4(0, 0, 0, 0).To4() - right[0] = left4[0] | ^ipnet.Mask[0] - right[1] = left4[1] | ^ipnet.Mask[1] - right[2] = left4[2] | ^ipnet.Mask[2] - right[3] = left4[3] | ^ipnet.Mask[3] + copy(mask[16-len(network.Mask):], network.Mask) - return left4.String(), right.To4().String(), nil -} + // Mask address for left and right bounds + for i := range left { + left[i] = addr[i] & mask[i] + right[i] = addr[i] | ^mask[i] + } -// ToDots converts a uint32 to a IPv4 Dotted notation -func ToDots(val uint32) string { - return fmt.Sprintf("%d.%d.%d.%d", - val>>24, - (val>>16)&0xFF, - (val>>8)&0xFF, - val&0xFF) + return left.String(), right.String(), nil } -// Interval is a closed interval [a,b] of an IPv4 range +// Interval is a closed interval [a,b] of an IP range type Interval struct { - Left uint32 - Right uint32 - LeftDots string - RightDots string - Name string - URL string + Left [16]byte + Right [16]byte + Name string + URL string +} + +// Contains returns true if the IP address is found within the interval. +func (interval *Interval) Contains(ip []byte) bool { + return bytes.Compare(ip, interval.Left[:]) >= 0 && bytes.Compare(ip, interval.Right[:]) <= 0 +} + +// Size returns the number of IP addresses that fit in the range +func (interval *Interval) Size() *big.Int { + size := big.NewInt(1) + size.Add(size, new(big.Int).SetBytes(interval.Right[:])) + size.Sub(size, new(big.Int).SetBytes(interval.Left[:])) + return size +} + +func (interval Interval) String() string { + return IPString(interval.Left[:]) + " to " + IPString(interval.Right[:]) + " (" + + interval.Name + " <" + interval.URL + ">)" } type intervallist []Interval @@ -72,7 +109,7 @@ func (ipset intervallist) Len() int { // Less satisfies the sort.Sortable interface func (ipset intervallist) Less(i, j int) bool { - return ipset[i].Left < ipset[j].Left + return bytes.Compare(ipset[i].Left[:], ipset[j].Left[:]) < 0 } // Swap satisfies the sort.Sortable interface @@ -129,7 +166,7 @@ func (ipset *IntervalSet) ExportCSV(in io.Writer) error { } w := csv.NewWriter(in) for _, val := range ipset.btree { - rec := []string{ToDots(val.Left), ToDots(val.Right), val.Name, val.URL} + rec := []string{IPString(val.Left[:]), IPString(val.Right[:]), val.Name, val.URL} if err := w.Write(rec); err != nil { return err } @@ -153,17 +190,13 @@ func (ipset *IntervalSet) sort() error { last := Interval{} // check validity -- probably worth ripping out for pos, val := range ipset.btree { - if val.Left > val.Right { - return fmt.Errorf("left %d > right %d at pos %d", - val.Left, val.Right, pos) - } - if val.Right-val.Left > (uint32(255) << 24) { - return fmt.Errorf("Interval too large: [%d,%d]", - val.Left, val.Right) + if bytes.Compare(val.Left[:], val.Right[:]) > 0 { + return fmt.Errorf("left %s > right %s at pos %d", + IPString(val.Left[:]), IPString(val.Right[:]), pos) } if pos > 0 { - if val.Left <= last.Right || val.Right <= last.Right { - return fmt.Errorf("Overlapping regions %v vs. %v", last, val) + if bytes.Compare(val.Left[:], last.Right[:]) <= 0 || bytes.Compare(val.Right[:], last.Right[:]) <= 0 { + return fmt.Errorf("Overlapping regions %s and %s", last, val) } } last = val @@ -171,23 +204,21 @@ func (ipset *IntervalSet) sort() error { ipset.sorted = true // now merge adjacent items - newtree := make([]Interval, 0, len(ipset.btree)) - last = Interval{} - for pos, val := range ipset.btree { - if pos == 0 { - newtree = append(newtree, val) - last = val + merged := ipset.btree[:0] + for index, interval := range ipset.btree { + if index == 0 { + merged = append(merged, interval) continue } - if last.Right+1 == val.Left && last.Name == val.Name { - last.Right = val.Right - newtree[len(newtree)-1] = last + last := &merged[len(merged)-1] + if interval.Name == last.Name && IPIsAdjacent(last.Right[:], interval.Left[:]) { + last.Right = interval.Right continue } - newtree = append(newtree, val) - last = val + merged = append(merged, interval) } - ipset.btree = newtree + ipset.btree = merged + return nil } @@ -202,37 +233,36 @@ func (ipset *IntervalSet) AddCIDR(cidr, name, url string) error { // AddRange adds an entry based on an IP range func (ipset *IntervalSet) AddRange(dotsleft, dotsright, name, url string) error { - left := dots2uint32(dotsleft) - if left == 0 && dotsleft != "0.0.0.0" { + left := net.ParseIP(dotsleft) + if left == nil { return fmt.Errorf("Unable to convert %s", dotsleft) } - right := dots2uint32(dotsright) - if right == 0 && dotsright != "0.0.0.0" { + right := net.ParseIP(dotsright) + if right == nil { return fmt.Errorf("Unable to convert %s", dotsright) } - if left > right { + if bytes.Compare(left, right) > 0 { return fmt.Errorf("%s > %s", dotsleft, dotsright) } - if right-left >= uint32(1)<<24 { - return fmt.Errorf("Range too big for [%s %s] %s %s", dotsleft, dotsright, name, url) - } + ipset.sorted = false ipset.btree = append(ipset.btree, Interval{ - Left: left, - Right: right, - LeftDots: dotsleft, - RightDots: dotsright, - Name: name, - URL: url, + Name: name, + URL: url, }, ) + + index := len(ipset.btree) - 1 + copy(ipset.btree[index].Left[:], left) + copy(ipset.btree[index].Right[:], right) + return nil } // DeleteByName deletes all entries with the given name func (ipset *IntervalSet) DeleteByName(name string) { - newlist := intervallist{} + newlist := ipset.btree[:0] for _, entry := range ipset.btree { if entry.Name != name { newlist = append(newlist, entry) @@ -242,47 +272,55 @@ func (ipset *IntervalSet) DeleteByName(name string) { } // Len returns the number of elements in the set -func (ipset IntervalSet) Len() int { +func (ipset *IntervalSet) Len() int { return ipset.btree.Len() } // Contains returns the internal record if the IP address is in some // interval else nil or error. It returns a pointer to the internal // record, so be careful. -func (ipset IntervalSet) Contains(dots string) (*Interval, error) { - if !ipset.sorted { - err := ipset.sort() - if err != nil { - return nil, err - } +func (ipset *IntervalSet) Contains(dots string) (*Interval, error) { + if err := ipset.sort(); err != nil { + return nil, err } - val := dots2uint32(dots) - if val == 0 && dots != "0.0.0.0" { + ip := net.ParseIP(dots) + if ip == nil { return nil, fmt.Errorf("Invalid input: %q", dots) } - i := sort.Search(len(ipset.btree), func(i int) bool { - return ipset.btree[i].Left >= val + + len := ipset.Len() + + index := sort.Search(len, func(i int) bool { + left := ipset.btree[i].Left[:] + cmp := bytes.Compare(left, ip) + return cmp >= 0 }) - // lots of cases in the lookup here. - // if exactly equals, then compare with [i] - if i < ipset.Len() && ipset.btree[i].Left == val && val <= ipset.btree[i].Right { - return &ipset.btree[i], nil + if index < len { + // lots of cases in the lookup here. + // if exactly equals, then compare with [i] + interval := &ipset.btree[index] + if interval.Contains(ip) { + return interval, nil + } } // ok then it's the record before - i-- - if i >= 0 && ipset.btree[i].Left < val && val <= ipset.btree[i].Right { - return &ipset.btree[i], nil + if index > 0 { + interval := &ipset.btree[index-1] + if interval.Contains(ip) { + return interval, nil + } } + return nil, nil } // NameSize is a tuple mapping name with a size type NameSize struct { Name string - Size int + Size *big.Int } // NameSizeList is a list of NameSize @@ -357,17 +395,23 @@ func (ms *multiSorter) Less(i, j int) bool { // * Total number IP address // func (ipset IntervalSet) RankBySize() NameSizeList { - counts := make(map[string]int, ipset.Len()) + counts := make(map[string]*big.Int, ipset.Len()) for _, val := range ipset.btree { - counts[val.Name] += int(val.Right-val.Left) + 1 + count, ok := counts[val.Name] + if !ok { + count = big.NewInt(0) + counts[val.Name] = count + } + + count.Add(count, val.Size()) } rank := make(NameSizeList, 0, len(counts)) for k, v := range counts { rank = append(rank, NameSize{k, v}) } - size := func(l1, l2 *NameSize) bool { - return l1.Size > l2.Size + size := func(left, right *NameSize) bool { + return left.Size.Cmp(right.Size) > 0 } name := func(l1, l2 *NameSize) bool { diff --git a/ipset_test.go b/ipset_test.go index be079e01..e8912585 100644 --- a/ipset_test.go +++ b/ipset_test.go @@ -1,6 +1,8 @@ package ipcat -import "testing" +import ( + "testing" +) func TestSetting(t *testing.T) { const ( @@ -19,10 +21,6 @@ func TestSetting(t *testing.T) { t.Fatalf("Added entry but size %d != 1", set.Len()) } - if err := set.AddRange("10.0.0.0", "11.0.0.0", dcName, dcURL); err == nil { - t.Errorf("Allowed adding something larger than class A network") - } - if err := set.AddRange("1.0.0.0", "1.255.255.255", dcName, dcURL); err != nil { t.Errorf("Unable to add full class A network: %s", err) } @@ -44,18 +42,17 @@ func TestSetting(t *testing.T) { } } -var toDotsTests = []struct { - ip uint32 - want string -}{ - {67372036, "4.4.4.4"}, - {3232235777, "192.168.1.1"}, +var ipStringTests = []string{ + "4.4.4.4", + "192.168.1.1", + "fe80:cd00::211e:729c", } -func TestToDots(t *testing.T) { - for _, tt := range toDotsTests { - if got := ToDots(tt.ip); got != tt.want { - t.Errorf("ToDots(%d) = %q, want %q", tt.ip, got, tt.want) +func TestIPString(t *testing.T) { + for _, tt := range ipStringTests { + ip := IPParse(tt) + if got := IPString(ip); got != tt { + t.Errorf("IPString(%d) = %q, want %q", ip, got, tt) } } } @@ -84,6 +81,20 @@ func TestCIDR2Range(t *testing.T) { } } +func TestMergeAdjacent(t *testing.T) { + ipset := NewIntervalSet(256) + + ipset.AddCIDR("1.1.1.1/24", "Test Range", "url") + ipset.AddCIDR("1.1.2.1/24", "Test Range", "url") + ipset.AddCIDR("1.1.4.1/24", "Test Range", "url") + + ipset.Contains("1.1.1.1") // calls sort() + + if ipset.Len() != 2 { + t.Errorf("ipset contains %d items, want %d", ipset.Len(), 2) + } +} + func TestIntervalSet(t *testing.T) { ipset := NewIntervalSet(256) ipset.AddCIDR("1.1.1.1/24", "Test Range", "Test URL") diff --git a/tor.csv b/tor.csv new file mode 100644 index 00000000..d9f4d8f6 --- /dev/null +++ b/tor.csv @@ -0,0 +1,100 @@ +5.187.21.43,5.187.21.44,Tor Project,https://www.torproject.org/ +31.185.104.19,31.185.104.21,Tor Project,https://www.torproject.org/ +51.15.56.122,51.15.56.123,Tor Project,https://www.torproject.org/ +51.15.76.141,51.15.76.142,Tor Project,https://www.torproject.org/ +51.255.26.152,51.255.26.155,Tor Project,https://www.torproject.org/ +62.219.3.47,62.219.3.48,Tor Project,https://www.torproject.org/ +65.19.167.130,65.19.167.133,Tor Project,https://www.torproject.org/ +65.49.20.10,65.49.20.12,Tor Project,https://www.torproject.org/ +69.38.149.3,69.38.149.4,Tor Project,https://www.torproject.org/ +72.52.77.99,72.52.77.103,Tor Project,https://www.torproject.org/ +77.247.181.162,77.247.181.166,Tor Project,https://www.torproject.org/ +79.137.70.137,79.137.70.138,Tor Project,https://www.torproject.org/ +79.137.112.4,79.137.112.5,Tor Project,https://www.torproject.org/ +79.140.41.117,79.140.41.118,Tor Project,https://www.torproject.org/ +81.17.17.130,81.17.17.131,Tor Project,https://www.torproject.org/ +85.248.227.163,85.248.227.165,Tor Project,https://www.torproject.org/ +87.118.122.50,87.118.122.51,Tor Project,https://www.torproject.org/ +89.34.237.17,89.34.237.18,Tor Project,https://www.torproject.org/ +89.34.237.214,89.34.237.215,Tor Project,https://www.torproject.org/ +89.163.225.6,89.163.225.7,Tor Project,https://www.torproject.org/ +89.187.150.12,89.187.150.15,Tor Project,https://www.torproject.org/ +89.238.178.122,89.238.178.123,Tor Project,https://www.torproject.org/ +91.211.247.246,91.211.247.247,Tor Project,https://www.torproject.org/ +91.236.116.87,91.236.116.88,Tor Project,https://www.torproject.org/ +93.115.86.8,93.115.86.9,Tor Project,https://www.torproject.org/ +93.115.95.201,93.115.95.202,Tor Project,https://www.torproject.org/ +93.115.95.204,93.115.95.207,Tor Project,https://www.torproject.org/ +94.230.208.147,94.230.208.148,Tor Project,https://www.torproject.org/ +95.143.172.207,95.143.172.208,Tor Project,https://www.torproject.org/ +95.215.44.110,95.215.44.111,Tor Project,https://www.torproject.org/ +103.250.73.12,103.250.73.13,Tor Project,https://www.torproject.org/ +104.206.237.23,104.206.237.24,Tor Project,https://www.torproject.org/ +104.218.63.72,104.218.63.77,Tor Project,https://www.torproject.org/ +104.223.123.98,104.223.123.101,Tor Project,https://www.torproject.org/ +118.42.88.116,118.42.88.117,Tor Project,https://www.torproject.org/ +129.10.115.237,129.10.115.239,Tor Project,https://www.torproject.org/ +129.10.115.244,129.10.115.248,Tor Project,https://www.torproject.org/ +130.230.113.228,130.230.113.237,Tor Project,https://www.torproject.org/ +131.188.40.188,131.188.40.189,Tor Project,https://www.torproject.org/ +131.255.4.117,131.255.4.118,Tor Project,https://www.torproject.org/ +137.74.40.76,137.74.40.77,Tor Project,https://www.torproject.org/ +138.201.102.141,138.201.102.142,Tor Project,https://www.torproject.org/ +139.59.36.56,139.59.36.57,Tor Project,https://www.torproject.org/ +141.255.161.166,141.255.161.167,Tor Project,https://www.torproject.org/ +158.69.30.132,158.69.30.133,Tor Project,https://www.torproject.org/ +160.119.249.222,160.119.249.223,Tor Project,https://www.torproject.org/ +160.119.249.239,160.119.249.240,Tor Project,https://www.torproject.org/ +162.247.72.199,162.247.72.202,Tor Project,https://www.torproject.org/ +162.247.72.216,162.247.72.217,Tor Project,https://www.torproject.org/ +163.22.17.210,163.22.17.211,Tor Project,https://www.torproject.org/ +171.25.193.77,171.25.193.78,Tor Project,https://www.torproject.org/ +173.12.223.106,173.12.223.107,Tor Project,https://www.torproject.org/ +173.208.206.188,173.208.206.190,Tor Project,https://www.torproject.org/ +173.254.216.66,173.254.216.69,Tor Project,https://www.torproject.org/ +176.10.99.200,176.10.99.210,Tor Project,https://www.torproject.org/ +176.126.252.11,176.126.252.12,Tor Project,https://www.torproject.org/ +178.16.208.55,178.16.208.62,Tor Project,https://www.torproject.org/ +178.32.181.96,178.32.181.99,Tor Project,https://www.torproject.org/ +178.175.135.99,178.175.135.102,Tor Project,https://www.torproject.org/ +184.105.144.180,184.105.144.181,Tor Project,https://www.torproject.org/ +185.100.84.250,185.100.84.251,Tor Project,https://www.torproject.org/ +185.100.85.190,185.100.85.191,Tor Project,https://www.torproject.org/ +185.100.87.206,185.100.87.207,Tor Project,https://www.torproject.org/ +185.104.120.2,185.104.120.5,Tor Project,https://www.torproject.org/ +185.106.154.118,185.106.154.119,Tor Project,https://www.torproject.org/ +185.107.81.81,185.107.81.83,Tor Project,https://www.torproject.org/ +185.129.62.62,185.129.62.63,Tor Project,https://www.torproject.org/ +185.146.228.150,185.146.228.151,Tor Project,https://www.torproject.org/ +185.217.0.114,185.217.0.115,Tor Project,https://www.torproject.org/ +185.217.0.119,185.217.0.120,Tor Project,https://www.torproject.org/ +185.220.100.252,185.220.101.1,Tor Project,https://www.torproject.org/ +185.220.101.3,185.220.101.6,Tor Project,https://www.torproject.org/ +185.220.101.8,185.220.101.10,Tor Project,https://www.torproject.org/ +185.220.101.12,185.220.101.13,Tor Project,https://www.torproject.org/ +185.220.101.20,185.220.101.22,Tor Project,https://www.torproject.org/ +185.220.101.25,185.220.101.30,Tor Project,https://www.torproject.org/ +185.220.101.32,185.220.101.34,Tor Project,https://www.torproject.org/ +185.220.101.44,185.220.101.46,Tor Project,https://www.torproject.org/ +185.222.202.12,185.222.202.13,Tor Project,https://www.torproject.org/ +185.222.202.103,185.222.202.104,Tor Project,https://www.torproject.org/ +192.36.27.6,192.36.27.7,Tor Project,https://www.torproject.org/ +192.42.115.101,192.42.115.102,Tor Project,https://www.torproject.org/ +192.42.116.13,192.42.116.20,Tor Project,https://www.torproject.org/ +192.52.167.70,192.52.167.71,Tor Project,https://www.torproject.org/ +192.160.102.164,192.160.102.166,Tor Project,https://www.torproject.org/ +192.160.102.168,192.160.102.170,Tor Project,https://www.torproject.org/ +193.11.114.45,193.11.114.46,Tor Project,https://www.torproject.org/ +193.90.12.115,193.90.12.119,Tor Project,https://www.torproject.org/ +193.105.134.56,193.105.134.57,Tor Project,https://www.torproject.org/ +195.12.48.76,195.12.48.77,Tor Project,https://www.torproject.org/ +195.22.125.136,195.22.125.137,Tor Project,https://www.torproject.org/ +195.176.3.19,195.176.3.20,Tor Project,https://www.torproject.org/ +195.176.3.23,195.176.3.24,Tor Project,https://www.torproject.org/ +199.249.224.40,199.249.224.49,Tor Project,https://www.torproject.org/ +199.249.224.60,199.249.224.69,Tor Project,https://www.torproject.org/ +204.85.191.30,204.85.191.31,Tor Project,https://www.torproject.org/ +206.55.74.0,206.55.74.1,Tor Project,https://www.torproject.org/ +212.51.156.164,212.51.156.165,Tor Project,https://www.torproject.org/ +217.170.197.82,217.170.197.83,Tor Project,https://www.torproject.org/ +217.182.196.67,217.182.196.68,Tor Project,https://www.torproject.org/ diff --git a/tor.go b/tor.go new file mode 100644 index 00000000..2957002c --- /dev/null +++ b/tor.go @@ -0,0 +1,65 @@ +package ipcat + +import ( + "bufio" + "fmt" + "net/http" + "regexp" + "strings" +) + +var ( + torDownload = "https://panwdbl.appspot.com/lists/ettor.txt" + torRegexp = regexp.MustCompile(`^([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})(?:-([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))?$`) +) + +// UpdateTor downloads and parses the Tor exit node list and updates the interval set +func UpdateTor(ipmap *IntervalSet) error { + const ( + torName = "Tor Project" + torURL = "https://www.torproject.org/" + ) + + // Download list + resp, err := http.Get(torDownload) + if err != nil { + return err + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + return fmt.Errorf("Failed to download Tor ranges: status code %s", resp.Status) + } + + // Delete all existing records + ipmap.DeleteByName(torName) + + // Add them back + scanner := bufio.NewScanner(resp.Body) + for scanner.Scan() { + line := scanner.Text() + + // A line with # serves as a comment. + if commentStart := strings.IndexByte(line, '#'); commentStart >= 0 { + line = line[:commentStart] + } + + // A blank line matches no files, + // so it can serve as a separator for readability. + line = strings.TrimSpace(line) + if line == "" { + continue + } + + ips := torRegexp.FindStringSubmatch(line) + switch len(ips) { + case 2: + // Found singular IP + ipmap.AddRange(ips[1], ips[1], torName, torURL) + case 3: + // Found range + ipmap.AddRange(ips[1], ips[2], torName, torURL) + } + } + + return nil +}