-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcountries.go
89 lines (76 loc) · 2.31 KB
/
countries.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/*
Copyright 2009-2012,2016 Phil Pennock
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package sks_spider
import (
"fmt"
"net"
"strconv"
"strings"
)
const hexDigit = "0123456789abcdef"
type CountrySet sortedSet
func NewCountrySet(s string) CountrySet {
cs := CountrySet(newSortedSet())
for _, country := range strings.Split(s, ",") {
sortedSet(cs).Insert(strings.ToUpper(country))
}
return cs
}
func (cs CountrySet) HasCountry(s string) bool {
return sortedSet(cs).Contains(strings.ToUpper(s))
}
func (cs CountrySet) String() string {
cList := sortedSet(cs).AllData()
return strings.Join(cList, ",")
}
func (cs CountrySet) Initialized() bool {
return sortedSet(cs).Tree != nil
}
func reverseIP(ipstr string) (reversed string, err error) {
// Crib from net.reverseaddr()
ip := net.ParseIP(ipstr)
if ip == nil {
return "", &net.DNSError{Err: "unrecognized address", Name: ipstr}
}
if ip.To4() != nil {
reversed = strconv.Itoa(int(ip[15])) + "." + strconv.Itoa(int(ip[14])) + "." + strconv.Itoa(int(ip[13])) + "." + strconv.Itoa(int(ip[12]))
return
}
maxLen := len(ip)*4 - 1 // nibble-dot-nibble-dot, no terminating dot here
buf := make([]byte, 0, maxLen+1)
// Add it, in reverse, to the buffer
for i := len(ip) - 1; i >= 0; i-- {
v := ip[i]
buf = append(buf, hexDigit[v&0xF])
buf = append(buf, '.')
buf = append(buf, hexDigit[v>>4])
buf = append(buf, '.')
}
reversed = string(buf[:maxLen])
return
}
func CountryForIPString(ipstr string) (country string, err error) {
rev, err := reverseIP(ipstr)
if err != nil {
return "", err
}
query := fmt.Sprintf("%s.%s", rev, *flCountriesZone)
txtList, err := net.LookupTXT(query)
if err != nil {
return "", err
}
if len(txtList) > 0 {
return strings.ToUpper(txtList[0]), nil
}
return "", fmt.Errorf("No TXT records (and no error) for: %s", query)
}