Host records support wildcard #16
This commit is contained in:
parent
a320fe0eb7
commit
c5e01db7b5
|
@ -87,6 +87,12 @@ can be assigned at godns.conf,default : `/etc/hosts`
|
||||||
[hosts]
|
[hosts]
|
||||||
host-file = "/etc/hosts"
|
host-file = "/etc/hosts"
|
||||||
```
|
```
|
||||||
|
Hosts file format is described in [linux man pages](http://man7.org/linux/man-pages/man5/hosts.5.html).
|
||||||
|
More than that , `*.` wildcard is supported additional.
|
||||||
|
|
||||||
|
```
|
||||||
|
127.0.0.1 *.example.com
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
__redis hosts__
|
__redis hosts__
|
||||||
|
@ -105,7 +111,7 @@ redis-key = "godns:hosts"
|
||||||
_Insert hosts records into redis_
|
_Insert hosts records into redis_
|
||||||
|
|
||||||
```
|
```
|
||||||
redis > hset godns:hosts www.sina.com.cn 1.1.1.1
|
redis > hset godns:hosts www.test.com 1.1.1.1
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
49
hosts.go
49
hosts.go
|
@ -17,12 +17,12 @@ type Hosts struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHosts(hs HostsSettings, rs RedisSettings) Hosts {
|
func NewHosts(hs HostsSettings, rs RedisSettings) Hosts {
|
||||||
fileHosts := &FileHosts{hs.HostsFile, make(map[string]string)}
|
fileHosts := &FileHosts{BaseHosts{make(map[string]string)}, hs.HostsFile}
|
||||||
|
|
||||||
var redisHosts *RedisHosts
|
var redisHosts *RedisHosts
|
||||||
if hs.RedisEnable {
|
if hs.RedisEnable {
|
||||||
rc := &redis.Client{Addr: rs.Addr(), Db: rs.DB, Password: rs.Password}
|
rc := &redis.Client{Addr: rs.Addr(), Db: rs.DB, Password: rs.Password}
|
||||||
redisHosts = &RedisHosts{rc, hs.RedisKey, make(map[string]string)}
|
redisHosts = &RedisHosts{BaseHosts{make(map[string]string)}, rc, hs.RedisKey}
|
||||||
}
|
}
|
||||||
|
|
||||||
hosts := Hosts{fileHosts, redisHosts}
|
hosts := Hosts{fileHosts, redisHosts}
|
||||||
|
@ -32,10 +32,8 @@ func NewHosts(hs HostsSettings, rs RedisSettings) Hosts {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
1. Match local /etc/hosts file first, remote redis records second
|
Match local /etc/hosts file first, remote redis records second
|
||||||
2. Fetch hosts records from /etc/hosts file and redis per minute
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
func (h *Hosts) Get(domain string, family int) (ip net.IP, ok bool) {
|
func (h *Hosts) Get(domain string, family int) (ip net.IP, ok bool) {
|
||||||
|
|
||||||
var sip string
|
var sip string
|
||||||
|
@ -61,6 +59,9 @@ func (h *Hosts) Get(domain string, family int) (ip net.IP, ok bool) {
|
||||||
return ip, (ip != nil)
|
return ip, (ip != nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Update hosts records from /etc/hosts file and redis per minute
|
||||||
|
*/
|
||||||
func (h *Hosts) refresh() {
|
func (h *Hosts) refresh() {
|
||||||
ticker := time.NewTicker(time.Minute)
|
ticker := time.NewTicker(time.Minute)
|
||||||
go func() {
|
go func() {
|
||||||
|
@ -74,17 +75,34 @@ func (h *Hosts) refresh() {
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
type RedisHosts struct {
|
type BaseHosts struct {
|
||||||
redis *redis.Client
|
|
||||||
key string
|
|
||||||
hosts map[string]string
|
hosts map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RedisHosts) Get(domain string) (ip string, ok bool) {
|
func (h *BaseHosts) Get(domain string) (ip string, ok bool) {
|
||||||
ip, ok = r.hosts[domain]
|
ip, ok = h.hosts[domain]
|
||||||
|
if ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for host, ip := range h.hosts {
|
||||||
|
if strings.HasPrefix(host, "*.") {
|
||||||
|
upperLevelDomain := strings.Split(host, "*.")[1]
|
||||||
|
if strings.HasSuffix(domain, upperLevelDomain) {
|
||||||
|
return ip, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RedisHosts struct {
|
||||||
|
BaseHosts
|
||||||
|
redis *redis.Client
|
||||||
|
key string
|
||||||
|
}
|
||||||
|
|
||||||
func (r *RedisHosts) Set(domain, ip string) (bool, error) {
|
func (r *RedisHosts) Set(domain, ip string) (bool, error) {
|
||||||
return r.redis.Hset(r.key, domain, []byte(ip))
|
return r.redis.Hset(r.key, domain, []byte(ip))
|
||||||
}
|
}
|
||||||
|
@ -99,13 +117,8 @@ func (r *RedisHosts) Refresh() {
|
||||||
}
|
}
|
||||||
|
|
||||||
type FileHosts struct {
|
type FileHosts struct {
|
||||||
file string
|
BaseHosts
|
||||||
hosts map[string]string
|
file string
|
||||||
}
|
|
||||||
|
|
||||||
func (f *FileHosts) Get(domain string) (ip string, ok bool) {
|
|
||||||
ip, ok = f.hosts[domain]
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FileHosts) Refresh() {
|
func (f *FileHosts) Refresh() {
|
||||||
|
@ -150,7 +163,7 @@ func (f *FileHosts) isDomain(domain string) bool {
|
||||||
if f.isIP(domain) {
|
if f.isIP(domain) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
match, _ := regexp.MatchString(`^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}$`, domain)
|
match, _ := regexp.MatchString(`^([a-zA-Z0-9\*]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}$`, domain)
|
||||||
return match
|
return match
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue