2018-08-13 00:42:59 +08:00
|
|
|
package ipset
|
2017-08-28 19:23:32 +08:00
|
|
|
|
|
|
|
import (
|
2020-04-06 23:37:36 +08:00
|
|
|
"errors"
|
2017-08-28 19:23:32 +08:00
|
|
|
"strings"
|
|
|
|
"sync"
|
|
|
|
|
2020-09-25 11:04:13 +08:00
|
|
|
"github.com/nadoo/glider/rule"
|
2020-09-26 23:34:26 +08:00
|
|
|
|
|
|
|
ipsetlib "github.com/nadoo/ipset"
|
2018-06-28 09:49:23 +08:00
|
|
|
)
|
2017-08-28 19:23:32 +08:00
|
|
|
|
2020-09-25 11:04:13 +08:00
|
|
|
// Manager struct.
|
2018-08-14 19:33:18 +08:00
|
|
|
type Manager struct {
|
2017-08-28 19:23:32 +08:00
|
|
|
domainSet sync.Map
|
|
|
|
}
|
|
|
|
|
2018-08-14 19:33:18 +08:00
|
|
|
// NewManager returns a Manager
|
2018-11-27 23:25:20 +08:00
|
|
|
func NewManager(rules []*rule.Config) (*Manager, error) {
|
2020-09-25 11:04:13 +08:00
|
|
|
if err := ipsetlib.Init(); err != nil {
|
2017-08-28 19:23:32 +08:00
|
|
|
return nil, err
|
|
|
|
}
|
2017-08-29 18:36:42 +08:00
|
|
|
|
2020-08-26 19:21:35 +08:00
|
|
|
// create ipset, avoid redundant.
|
|
|
|
sets := make(map[string]struct{})
|
2017-08-28 19:23:32 +08:00
|
|
|
for _, r := range rules {
|
2018-11-27 23:25:20 +08:00
|
|
|
if r.IPSet != "" {
|
2020-08-26 19:21:35 +08:00
|
|
|
sets[r.IPSet] = struct{}{}
|
2017-08-28 19:23:32 +08:00
|
|
|
}
|
2018-11-27 23:25:20 +08:00
|
|
|
}
|
2017-08-28 19:23:32 +08:00
|
|
|
|
2020-08-26 19:21:35 +08:00
|
|
|
for set := range sets {
|
2020-09-25 11:04:13 +08:00
|
|
|
ipsetlib.Create(set)
|
|
|
|
ipsetlib.Flush(set)
|
2020-08-26 19:21:35 +08:00
|
|
|
}
|
|
|
|
|
2018-11-27 23:25:20 +08:00
|
|
|
// init ipset
|
2020-09-25 11:04:13 +08:00
|
|
|
m := &Manager{}
|
2018-11-27 23:25:20 +08:00
|
|
|
for _, r := range rules {
|
|
|
|
if r.IPSet != "" {
|
|
|
|
for _, domain := range r.Domain {
|
|
|
|
m.domainSet.Store(domain, r.IPSet)
|
|
|
|
}
|
|
|
|
for _, ip := range r.IP {
|
2020-09-25 11:04:13 +08:00
|
|
|
ipsetlib.Add(r.IPSet, ip)
|
2018-11-27 23:25:20 +08:00
|
|
|
}
|
|
|
|
for _, cidr := range r.CIDR {
|
2020-09-25 11:04:13 +08:00
|
|
|
ipsetlib.Add(r.IPSet, cidr)
|
2018-11-27 23:25:20 +08:00
|
|
|
}
|
2017-08-29 18:36:42 +08:00
|
|
|
}
|
2017-08-28 19:23:32 +08:00
|
|
|
}
|
|
|
|
|
2017-08-29 18:36:42 +08:00
|
|
|
return m, nil
|
2017-08-28 19:23:32 +08:00
|
|
|
}
|
|
|
|
|
2020-09-25 11:04:13 +08:00
|
|
|
// AddDomainIP implements the dns AnswerHandler function, used to update ipset according to domainSet rule.
|
2018-08-14 19:33:18 +08:00
|
|
|
func (m *Manager) AddDomainIP(domain, ip string) error {
|
2020-04-06 23:33:23 +08:00
|
|
|
if domain == "" || ip == "" {
|
|
|
|
return errors.New("please specify the domain and ip address")
|
|
|
|
}
|
2020-09-25 11:04:13 +08:00
|
|
|
|
2020-08-16 12:00:46 +08:00
|
|
|
domain = strings.ToLower(domain)
|
|
|
|
for i := len(domain); i != -1; {
|
|
|
|
i = strings.LastIndexByte(domain[:i], '.')
|
|
|
|
if ipset, ok := m.domainSet.Load(domain[i+1:]); ok {
|
2020-09-25 11:04:13 +08:00
|
|
|
ipsetlib.Add(ipset.(string), ip)
|
2017-08-28 19:23:32 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-25 11:04:13 +08:00
|
|
|
return nil
|
2017-08-28 19:23:32 +08:00
|
|
|
}
|