forked from loweel/zabov
				
			- WIP:
- new json configuration: added multiple configs, ip groups/ip aliases and timetables
  - added multiple configurations:
    - each configuration has his own upstream, singlefilters, doublefilters, blackholeip hostsfile
    - cache DB is global to all configs
    - BL downloader and parser is optimized: each BL source is downloaded/parsed only once
- TODO:
  - implement configuration selection based on source IPs and timetables
  - unused code cleanup
			
			
				remotes/1680050961956510080/tmp_refs/heads/master
			
			
		
							parent
							
								
									5c5e4e4417
								
							
						
					
					
						commit
						b6dfee64a6
					
				| 
						 | 
					@ -7,12 +7,15 @@ import (
 | 
				
			||||||
	"github.com/syndtr/goleveldb/leveldb"
 | 
						"github.com/syndtr/goleveldb/leveldb"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//MyZabovKDB is the storage where we'll put domains to block
 | 
					//MyZabovKDB is the storage where we'll put domains to block (obsolete)
 | 
				
			||||||
var MyZabovKDB *leveldb.DB
 | 
					//var MyZabovKDB *leveldb.DB
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//MyZabovCDB is the storage where we'll put domains to cache
 | 
					//MyZabovCDB is the storage where we'll put domains to cache (global for all configs)
 | 
				
			||||||
var MyZabovCDB *leveldb.DB
 | 
					var MyZabovCDB *leveldb.DB
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//MyZabovKDBs is the storage where we'll put domains to block (one for each config)
 | 
				
			||||||
 | 
					var MyZabovKDBs map[string]*leveldb.DB
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var err error
 | 
						var err error
 | 
				
			||||||
| 
						 | 
					@ -20,13 +23,13 @@ func init() {
 | 
				
			||||||
	os.RemoveAll("./db")
 | 
						os.RemoveAll("./db")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	os.MkdirAll("./db", 0755)
 | 
						os.MkdirAll("./db", 0755)
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
		MyZabovKDB, err = leveldb.OpenFile("./db/killfile", nil)
 | 
							MyZabovKDB, err = leveldb.OpenFile("./db/killfile", nil)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			fmt.Println("Cannot create Killfile db: ", err.Error())
 | 
								fmt.Println("Cannot create Killfile db: ", err.Error())
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			fmt.Println("Killfile DB created")
 | 
								fmt.Println("Killfile DB created")
 | 
				
			||||||
	}
 | 
							}*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	MyZabovCDB, err = leveldb.OpenFile("./db/cache", nil)
 | 
						MyZabovCDB, err = leveldb.OpenFile("./db/cache", nil)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
| 
						 | 
					@ -35,4 +38,21 @@ func init() {
 | 
				
			||||||
		fmt.Println("Cache DB created")
 | 
							fmt.Println("Cache DB created")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						MyZabovKDBs = map[string]*leveldb.DB{}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ZabovCreateKDB creates Kill DBs
 | 
				
			||||||
 | 
					func ZabovCreateKDB(conf string) {
 | 
				
			||||||
 | 
						var err error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dbname := "./db/killfile_" + conf
 | 
				
			||||||
 | 
						KDB, err := leveldb.OpenFile(dbname, nil)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							fmt.Println("Cannot create Killfile db: ", err.Error())
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							fmt.Println("Killfile DB created")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						MyZabovKDBs[conf] = KDB
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										163
									
								
								01.conf.go
								
								
								
								
							
							
						
						
									
										163
									
								
								01.conf.go
								
								
								
								
							| 
						 | 
					@ -6,29 +6,16 @@ import (
 | 
				
			||||||
	"io/ioutil"
 | 
						"io/ioutil"
 | 
				
			||||||
	"log"
 | 
						"log"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/miekg/dns"
 | 
						"github.com/miekg/dns"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type stringarray []string
 | 
				
			||||||
 | 
					type urlsMap map[string]stringarray
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
 | 
						var MyConfRaw interface{}
 | 
				
			||||||
	//ZabovConf describes the Json we use for configuration
 | 
					 | 
				
			||||||
	type ZabovConf struct {
 | 
					 | 
				
			||||||
		Zabov struct {
 | 
					 | 
				
			||||||
			Port          string `json:"port"`
 | 
					 | 
				
			||||||
			Proto         string `json:"proto"`
 | 
					 | 
				
			||||||
			Ipaddr        string `json:"ipaddr"`
 | 
					 | 
				
			||||||
			Upstream      string `json:"upstream"`
 | 
					 | 
				
			||||||
			Cachettl      int    `json:"cachettl"`
 | 
					 | 
				
			||||||
			Killfilettl   int    `json:"killfilettl"`
 | 
					 | 
				
			||||||
			Singlefilters string `json:"singlefilters"`
 | 
					 | 
				
			||||||
			Doublefilters string `json:"doublefilters"`
 | 
					 | 
				
			||||||
			Blackholeip   string `json:"blackholeip"`
 | 
					 | 
				
			||||||
			Hostsfile     string `json:"hostsfile"`
 | 
					 | 
				
			||||||
		} `json:"zabov"`
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var MyConf ZabovConf
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	file, err := ioutil.ReadFile("config.json")
 | 
						file, err := ioutil.ReadFile("config.json")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,26 +24,35 @@ func init() {
 | 
				
			||||||
		os.Exit(1)
 | 
							os.Exit(1)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = json.Unmarshal([]byte(file), &MyConf)
 | 
						err = json.Unmarshal([]byte(file), &MyConfRaw)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.Println("Cannot marshal json: ", err.Error())
 | 
							log.Println("Cannot unmarshal json: ", err.Error())
 | 
				
			||||||
		os.Exit(1)
 | 
							os.Exit(1)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// now we read configuration file
 | 
						// now we read configuration file
 | 
				
			||||||
	fmt.Println("Reading configuration file...")
 | 
						fmt.Println("Reading configuration file...")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ZabovPort := MyConf.Zabov.Port
 | 
						MyConf := MyConfRaw.(map[string]interface{})
 | 
				
			||||||
	ZabovType := MyConf.Zabov.Proto
 | 
					
 | 
				
			||||||
	ZabovAddr := MyConf.Zabov.Ipaddr
 | 
						zabov := MyConf["zabov"].(map[string]interface{})
 | 
				
			||||||
	ZabovUpDNS = MyConf.Zabov.Upstream
 | 
					
 | 
				
			||||||
	ZabovSingleBL = MyConf.Zabov.Singlefilters
 | 
						ZabovPort := zabov["port"].(string)
 | 
				
			||||||
	ZabovDoubleBL = MyConf.Zabov.Doublefilters
 | 
						ZabovType := zabov["proto"].(string)
 | 
				
			||||||
	ZabovAddBL = MyConf.Zabov.Blackholeip
 | 
						ZabovAddr := zabov["ipaddr"].(string)
 | 
				
			||||||
	ZabovCacheTTL = MyConf.Zabov.Cachettl
 | 
						ZabovCacheTTL = int(zabov["cachettl"].(float64))
 | 
				
			||||||
	ZabovKillTTL = MyConf.Zabov.Killfilettl
 | 
						ZabovKillTTL = int(zabov["killfilettl"].(float64))
 | 
				
			||||||
	ZabovHostsFile = MyConf.Zabov.Hostsfile
 | 
					
 | 
				
			||||||
 | 
						configs := MyConf["configs"].(map[string]interface{})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						defaultConf := configs["default"].(map[string]interface{})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ZabovUpDNS = defaultConf["upstream"].(string)
 | 
				
			||||||
 | 
						ZabovSingleBL = defaultConf["singlefilters"].(string)
 | 
				
			||||||
 | 
						ZabovDoubleBL = defaultConf["doublefilters"].(string)
 | 
				
			||||||
 | 
						ZabovAddBL = defaultConf["blackholeip"].(string)
 | 
				
			||||||
 | 
						ZabovHostsFile = defaultConf["hostsfile"].(string)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	zabovString := ZabovAddr + ":" + ZabovPort
 | 
						zabovString := ZabovAddr + ":" + ZabovPort
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -66,4 +62,111 @@ func init() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ZabovDNSArray = fileByLines(ZabovUpDNS)
 | 
						ZabovDNSArray = fileByLines(ZabovUpDNS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ZabovConfigs = map[string]ZabovConfig{}
 | 
				
			||||||
 | 
						ZabovIPGroups = []ZabovIPGroup{}
 | 
				
			||||||
 | 
						ZabovTimetables = map[string]ZabovTimetable{}
 | 
				
			||||||
 | 
						ZabovIPAliases = map[string]string{}
 | 
				
			||||||
 | 
						ZabovDNSArrays = map[string][]string{}
 | 
				
			||||||
 | 
						IPAliasesRaw := MyConf["ipaliases"].(map[string]interface{})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for alias, ip := range IPAliasesRaw {
 | 
				
			||||||
 | 
							fmt.Println("IP Alias:", alias, ip)
 | 
				
			||||||
 | 
							ZabovIPAliases[alias] = ip.(string)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for name, v := range configs {
 | 
				
			||||||
 | 
							fmt.Println("evaluaing config name:", name)
 | 
				
			||||||
 | 
							confRaw := v.(map[string]interface{})
 | 
				
			||||||
 | 
							var conf ZabovConfig
 | 
				
			||||||
 | 
							conf.ZabovUpDNS = confRaw["upstream"].(string)
 | 
				
			||||||
 | 
							conf.ZabovSingleBL = confRaw["singlefilters"].(string)
 | 
				
			||||||
 | 
							conf.ZabovDoubleBL = confRaw["doublefilters"].(string)
 | 
				
			||||||
 | 
							conf.ZabovAddBL = confRaw["blackholeip"].(string)
 | 
				
			||||||
 | 
							conf.ZabovHostsFile = confRaw["hostsfile"].(string)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ZabovDNSArrays[name] = fileByLines(conf.ZabovUpDNS)
 | 
				
			||||||
 | 
							ZabovConfigs[name] = conf
 | 
				
			||||||
 | 
							if name == "default" {
 | 
				
			||||||
 | 
								ZabovConfigDefault = conf
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							ZabovCreateKDB(name)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						timetables := MyConf["timetables"].(map[string]interface{})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for name, v := range timetables {
 | 
				
			||||||
 | 
							fmt.Println("evaluaing timetable name:", name)
 | 
				
			||||||
 | 
							timetableRaw := v.(map[string]interface{})
 | 
				
			||||||
 | 
							var timetable ZabovTimetable
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							timetable.cfgin = timetableRaw["cfgin"].(string)
 | 
				
			||||||
 | 
							timetable.cfgout = timetableRaw["cfgout"].(string)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if timetable.cfgin == "" {
 | 
				
			||||||
 | 
								timetable.cfgin = "default"
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if timetable.cfgout == "" {
 | 
				
			||||||
 | 
								timetable.cfgout = "default"
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							_, ok := ZabovConfigs[timetable.cfgin]
 | 
				
			||||||
 | 
							if !ok {
 | 
				
			||||||
 | 
								log.Println("inexistent cfgin:", timetable.cfgin)
 | 
				
			||||||
 | 
								os.Exit(1)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							_, ok = ZabovConfigs[timetable.cfgout]
 | 
				
			||||||
 | 
							if !ok {
 | 
				
			||||||
 | 
								log.Println("inexistent cfgout:", timetable.cfgout)
 | 
				
			||||||
 | 
								os.Exit(1)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							tables := timetableRaw["tables"].([]interface{})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for i := range tables {
 | 
				
			||||||
 | 
								table := tables[i].(map[string]interface{})
 | 
				
			||||||
 | 
								var ttEntry ZabovTimetableEntry
 | 
				
			||||||
 | 
								ttEntry.times = strings.Split(table["times"].(string), ";")
 | 
				
			||||||
 | 
								ttEntry.days = strings.Split(table["days"].(string), ";")
 | 
				
			||||||
 | 
								timetable.table = append(timetable.table, ttEntry)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							ZabovTimetables[name] = timetable
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						IPGroups := MyConf["ipgroups"].([]interface{})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fmt.Println("evaluating IP Groups: ", len(IPGroups))
 | 
				
			||||||
 | 
						for i := range IPGroups {
 | 
				
			||||||
 | 
							fmt.Println("evaluating IP Group n.", i)
 | 
				
			||||||
 | 
							var groupStruct ZabovIPGroup
 | 
				
			||||||
 | 
							groupMap := IPGroups[i].(map[string]interface{})
 | 
				
			||||||
 | 
							IPsRaw := groupMap["ips"].([]interface{})
 | 
				
			||||||
 | 
							groupStruct.ips = []string{}
 | 
				
			||||||
 | 
							for x := range IPsRaw {
 | 
				
			||||||
 | 
								ip := IPsRaw[x].(string)
 | 
				
			||||||
 | 
								fmt.Println("adding IP ", ip)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								alias, ok := ZabovIPAliases[ip]
 | 
				
			||||||
 | 
								if ok {
 | 
				
			||||||
 | 
									fmt.Println("IP alias: ", ip, alias)
 | 
				
			||||||
 | 
									ip = alias
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								groupStruct.ips = append(groupStruct.ips, ip)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							groupStruct.cfg = groupMap["cfg"].(string)
 | 
				
			||||||
 | 
							groupStruct.timetable = groupMap["timetable"].(string)
 | 
				
			||||||
 | 
							fmt.Println("cfg:", groupStruct.cfg)
 | 
				
			||||||
 | 
							fmt.Println("timetable:", groupStruct.timetable)
 | 
				
			||||||
 | 
							_, ok := ZabovTimetables[groupStruct.timetable]
 | 
				
			||||||
 | 
							if !ok {
 | 
				
			||||||
 | 
								log.Println("inexistent timetable:", groupStruct.timetable)
 | 
				
			||||||
 | 
								os.Exit(1)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							ZabovIPGroups = append(ZabovIPGroups, groupStruct)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						fmt.Println("ZabovConfigs:", ZabovConfigs)
 | 
				
			||||||
 | 
						fmt.Println("ZabovTimetables:", ZabovTimetables)
 | 
				
			||||||
 | 
						fmt.Println("ZabovIPAliases:", ZabovIPAliases)
 | 
				
			||||||
 | 
						fmt.Println("ZabovIPGroups:", ZabovIPGroups)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,11 +5,10 @@ import (
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var zabovKbucket = []byte("killfile")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type killfileItem struct {
 | 
					type killfileItem struct {
 | 
				
			||||||
	Kdomain  string
 | 
						Kdomain  string
 | 
				
			||||||
	Ksource  string
 | 
						Ksource  string
 | 
				
			||||||
 | 
						Kconfigs stringarray
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var bChannel chan killfileItem
 | 
					var bChannel chan killfileItem
 | 
				
			||||||
| 
						 | 
					@ -27,7 +26,9 @@ func bWriteThread() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for item := range bChannel {
 | 
						for item := range bChannel {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		writeInKillfile(item.Kdomain, item.Ksource)
 | 
							for _, config := range item.Kconfigs {
 | 
				
			||||||
 | 
								writeInKillfile(item.Kdomain, item.Ksource, config)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		incrementStats("BL domains from "+item.Ksource, 1)
 | 
							incrementStats("BL domains from "+item.Ksource, 1)
 | 
				
			||||||
		incrementStats("TOTAL", 1)
 | 
							incrementStats("TOTAL", 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,7 +37,7 @@ func bWriteThread() {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//DomainKill stores a domain name inside the killfile
 | 
					//DomainKill stores a domain name inside the killfile
 | 
				
			||||||
func DomainKill(s, durl string) {
 | 
					func DomainKill(s, durl string, configs stringarray) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if len(s) > 2 {
 | 
						if len(s) > 2 {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -46,6 +47,7 @@ func DomainKill(s, durl string) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		k.Kdomain = s
 | 
							k.Kdomain = s
 | 
				
			||||||
		k.Ksource = durl
 | 
							k.Ksource = durl
 | 
				
			||||||
 | 
							k.Kconfigs = configs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		bChannel <- k
 | 
							bChannel <- k
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -53,11 +55,12 @@ func DomainKill(s, durl string) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func writeInKillfile(key, value string) {
 | 
					func writeInKillfile(key, value string, config string) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stK := []byte(key)
 | 
						stK := []byte(key)
 | 
				
			||||||
	stV := []byte(value)
 | 
						stV := []byte(value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						MyZabovKDB := MyZabovKDBs[config]
 | 
				
			||||||
	err := MyZabovKDB.Put(stK, stV, nil)
 | 
						err := MyZabovKDB.Put(stK, stV, nil)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		fmt.Println("Cannot write to Killfile DB: ", err.Error())
 | 
							fmt.Println("Cannot write to Killfile DB: ", err.Error())
 | 
				
			||||||
| 
						 | 
					@ -65,10 +68,11 @@ func writeInKillfile(key, value string) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func domainInKillfile(domain string) bool {
 | 
					func domainInKillfile(domain string, config string) bool {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	s := strings.ToLower(domain)
 | 
						s := strings.ToLower(domain)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						MyZabovKDB := MyZabovKDBs[config]
 | 
				
			||||||
	has, err := MyZabovKDB.Has([]byte(s), nil)
 | 
						has, err := MyZabovKDB.Has([]byte(s), nil)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		fmt.Println("Cannot read from Killfile DB: ", err.Error())
 | 
							fmt.Println("Cannot read from Killfile DB: ", err.Error())
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,9 +16,9 @@ func init() {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//DoubleIndexFilter puts the domains inside file
 | 
					//DoubleIndexFilter puts the domains inside file
 | 
				
			||||||
func DoubleIndexFilter(durl string) error {
 | 
					func DoubleIndexFilter(durl string, configs stringarray) error {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fmt.Println("Retrieving HostFile from: ", durl)
 | 
						fmt.Println("DoubleIndexFilter: Retrieving HostFile from: ", durl)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var err error
 | 
						var err error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -59,7 +59,8 @@ func DoubleIndexFilter(durl string) error {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if net.ParseIP(h[0]) != nil {
 | 
							if net.ParseIP(h[0]) != nil {
 | 
				
			||||||
			DomainKill(h[1], durl)
 | 
					
 | 
				
			||||||
 | 
								DomainKill(h[1], durl, configs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// fmt.Println("MATCH: ", h[1])
 | 
								// fmt.Println("MATCH: ", h[1])
 | 
				
			||||||
			numLines++
 | 
								numLines++
 | 
				
			||||||
| 
						 | 
					@ -76,20 +77,38 @@ func DoubleIndexFilter(durl string) error {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func getDoubleFilters() {
 | 
					func getDoubleFilters(urls urlsMap) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	s := fileByLines(ZabovDoubleBL)
 | 
						fmt.Println("getDoubleFilters: downloading all urls:", len(urls))
 | 
				
			||||||
 | 
						for url, configs := range urls {
 | 
				
			||||||
	for _, a := range s {
 | 
							DoubleIndexFilter(url, configs)
 | 
				
			||||||
		DoubleIndexFilter(a)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func downloadDoubleThread() {
 | 
					func downloadDoubleThread() {
 | 
				
			||||||
	fmt.Println("Starting updater of DOUBLE lists, each (hours):", ZabovKillTTL)
 | 
						fmt.Println("Starting updater of DOUBLE lists, each (hours):", ZabovKillTTL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_urls := urlsMap{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for {
 | 
						for {
 | 
				
			||||||
		getDoubleFilters()
 | 
							fmt.Println("downloadDoubleThread: collecting urls from all configs...")
 | 
				
			||||||
 | 
							for config := range ZabovConfigs {
 | 
				
			||||||
 | 
								ZabovDoubleBL := ZabovConfigs[config].ZabovDoubleBL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								s := fileByLines(ZabovDoubleBL)
 | 
				
			||||||
 | 
								for _, v := range s {
 | 
				
			||||||
 | 
									configs := _urls[v]
 | 
				
			||||||
 | 
									if configs == nil {
 | 
				
			||||||
 | 
										configs = stringarray{}
 | 
				
			||||||
 | 
										_urls[v] = configs
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									configs = append(configs, config)
 | 
				
			||||||
 | 
									_urls[v] = configs
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							getDoubleFilters(_urls)
 | 
				
			||||||
		time.Sleep(time.Duration(ZabovKillTTL) * time.Hour)
 | 
							time.Sleep(time.Duration(ZabovKillTTL) * time.Hour)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,7 +14,7 @@ func init() {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//SingleIndexFilter puts the domains inside file
 | 
					//SingleIndexFilter puts the domains inside file
 | 
				
			||||||
func SingleIndexFilter(durl string) error {
 | 
					func SingleIndexFilter(durl string, configs stringarray) error {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fmt.Println("Retrieving DomainFile from: ", durl)
 | 
						fmt.Println("Retrieving DomainFile from: ", durl)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -57,7 +57,9 @@ func SingleIndexFilter(durl string) error {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if !strings.Contains(h[0], "#") {
 | 
							if !strings.Contains(h[0], "#") {
 | 
				
			||||||
			DomainKill(h[0], durl)
 | 
					
 | 
				
			||||||
 | 
								DomainKill(h[0], durl, configs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// fmt.Println("MATCH: ", h[1])
 | 
								// fmt.Println("MATCH: ", h[1])
 | 
				
			||||||
			numLines++
 | 
								numLines++
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
| 
						 | 
					@ -73,20 +75,37 @@ func SingleIndexFilter(durl string) error {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func getSingleFilters() {
 | 
					func getSingleFilters(urls urlsMap) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	s := fileByLines(ZabovSingleBL)
 | 
						fmt.Println("getSingleFilters: downloading all urls:", len(urls))
 | 
				
			||||||
 | 
						for url, configs := range urls {
 | 
				
			||||||
	for _, a := range s {
 | 
							SingleIndexFilter(url, configs)
 | 
				
			||||||
		SingleIndexFilter(a)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func downloadThread() {
 | 
					func downloadThread() {
 | 
				
			||||||
	fmt.Println("Starting updater of SINGLE lists, each (hours): ", ZabovKillTTL)
 | 
						fmt.Println("Starting updater of SINGLE lists, each (hours): ", ZabovKillTTL)
 | 
				
			||||||
 | 
						_urls := urlsMap{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for {
 | 
						for {
 | 
				
			||||||
		getSingleFilters()
 | 
							fmt.Println("downloadThread: collecting urls from all configs...")
 | 
				
			||||||
 | 
							for config := range ZabovConfigs {
 | 
				
			||||||
 | 
								ZabovSingleBL := ZabovConfigs[config].ZabovSingleBL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								s := fileByLines(ZabovSingleBL)
 | 
				
			||||||
 | 
								for _, v := range s {
 | 
				
			||||||
 | 
									configs := _urls[v]
 | 
				
			||||||
 | 
									if configs == nil {
 | 
				
			||||||
 | 
										configs = stringarray{}
 | 
				
			||||||
 | 
										_urls[v] = configs
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									configs = append(configs, config)
 | 
				
			||||||
 | 
									_urls[v] = configs
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							getSingleFilters(_urls)
 | 
				
			||||||
		time.Sleep(time.Duration(ZabovKillTTL) * time.Hour)
 | 
							time.Sleep(time.Duration(ZabovKillTTL) * time.Hour)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										43
									
								
								config.json
								
								
								
								
							
							
						
						
									
										43
									
								
								config.json
								
								
								
								
							| 
						 | 
					@ -1,15 +1,50 @@
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    "zabov": {  
 | 
					    "zabov":{
 | 
				
			||||||
        "port":"53", 
 | 
					        "port":"53", 
 | 
				
			||||||
        "proto":"udp", 
 | 
					        "proto":"udp", 
 | 
				
			||||||
        "ipaddr":"0.0.0.0",
 | 
					        "ipaddr":"0.0.0.0",
 | 
				
			||||||
        "upstream":"./dns-upstream.txt"  ,
 | 
					 | 
				
			||||||
        "cachettl": 1,
 | 
					        "cachettl": 1,
 | 
				
			||||||
        "killfilettl": 12,
 | 
					        "killfilettl": 12
 | 
				
			||||||
        "singlefilters":"./urls-domains.txt" ,
 | 
					    },
 | 
				
			||||||
 | 
					    "ipaliases":{
 | 
				
			||||||
 | 
					        "pc8":"192.168.178.29"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "ipgroups":[
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "ips":["192.168.178.30/32", "192.168.178.31/32", "pc8"],
 | 
				
			||||||
 | 
					            "cfg":"",
 | 
				
			||||||
 | 
					            "timetable":"tt_children"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "timetables":{
 | 
				
			||||||
 | 
					        "tt_children":{
 | 
				
			||||||
 | 
					            "tables":[{"times":"8:30-12:30;18:30-22:30", "days":"Mo;Tu;We;Th;Fr;Sa;Su"}],
 | 
				
			||||||
 | 
					            "cfgin":"children_restricted",
 | 
				
			||||||
 | 
					            "cfgout":"children"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "configs":{
 | 
				
			||||||
 | 
					        "default":{
 | 
				
			||||||
 | 
					            "upstream":"./dns-upstream.txt",
 | 
				
			||||||
 | 
					            "singlefilters":"./urls-domains.txt",
 | 
				
			||||||
 | 
					            "doublefilters":"./urls-hosts.txt", 
 | 
				
			||||||
 | 
					            "blackholeip":"127.0.0.1",
 | 
				
			||||||
 | 
					            "hostsfile":"./urls-local.txt"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "children":{
 | 
				
			||||||
 | 
					            "upstream":"./dns-upstream.txt",
 | 
				
			||||||
 | 
					            "singlefilters":"./urls-domains.txt",
 | 
				
			||||||
 | 
					            "doublefilters":"./urls-hosts.txt", 
 | 
				
			||||||
 | 
					            "blackholeip":"127.0.0.1",
 | 
				
			||||||
 | 
					            "hostsfile":"./urls-local.txt"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "children_restricted":{
 | 
				
			||||||
 | 
					            "upstream":"./dns-upstream.txt",
 | 
				
			||||||
 | 
					            "singlefilters":"./urls-domains.txt",
 | 
				
			||||||
            "doublefilters":"./urls-hosts.txt", 
 | 
					            "doublefilters":"./urls-hosts.txt", 
 | 
				
			||||||
            "blackholeip":"127.0.0.1",
 | 
					            "blackholeip":"127.0.0.1",
 | 
				
			||||||
            "hostsfile":"./urls-local.txt"
 | 
					            "hostsfile":"./urls-local.txt"
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,7 +12,8 @@ import (
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//ForwardQuery forwards the query to the upstream server
 | 
					//ForwardQuery forwards the query to the upstream server
 | 
				
			||||||
//first server to answer wins
 | 
					//first server to answer wins
 | 
				
			||||||
func ForwardQuery(query *dns.Msg) *dns.Msg {
 | 
					//accepts config name to select the UP DNS source list
 | 
				
			||||||
 | 
					func ForwardQuery(query *dns.Msg, config string) *dns.Msg {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	go incrementStats("ForwardQueries", 1)
 | 
						go incrementStats("ForwardQueries", 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,7 +46,7 @@ func ForwardQuery(query *dns.Msg) *dns.Msg {
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		d := oneTimeDNS()
 | 
							d := oneTimeDNS(config)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		in, _, err := c.Exchange(query, d)
 | 
							in, _, err := c.Exchange(query, d)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
| 
						 | 
					@ -78,10 +79,11 @@ func init() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func oneTimeDNS() (dns string) {
 | 
					func oneTimeDNS(config string) (dns string) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rand.Seed(time.Now().Unix())
 | 
						rand.Seed(time.Now().Unix())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ZabovDNSArray := ZabovDNSArrays[config]
 | 
				
			||||||
	upl := ZabovDNSArray
 | 
						upl := ZabovDNSArray
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if len(upl) < 1 {
 | 
						if len(upl) < 1 {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,19 +12,23 @@ func (mydns *handler) ServeDNS(w dns.ResponseWriter, r *dns.Msg) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	remIP, _, e := net.SplitHostPort(w.RemoteAddr().String())
 | 
						remIP, _, e := net.SplitHostPort(w.RemoteAddr().String())
 | 
				
			||||||
	if e != nil {
 | 
						if e != nil {
 | 
				
			||||||
 | 
							go incrementStats("CLIENT ERROR: "+remIP, 1)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
		go incrementStats("CLIENT: "+remIP, 1)
 | 
							go incrementStats("CLIENT: "+remIP, 1)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	msg := dns.Msg{}
 | 
						msg := dns.Msg{}
 | 
				
			||||||
	msg.SetReply(r)
 | 
						msg.SetReply(r)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						config := "default" // TODO: get config from client IP & timetable
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch r.Question[0].Qtype {
 | 
						switch r.Question[0].Qtype {
 | 
				
			||||||
	case dns.TypeA:
 | 
						case dns.TypeA:
 | 
				
			||||||
		msg.Authoritative = true
 | 
							msg.Authoritative = true
 | 
				
			||||||
		domain := msg.Question[0].Name
 | 
							domain := msg.Question[0].Name
 | 
				
			||||||
		fqdn := strings.TrimRight(domain, ".")
 | 
							fqdn := strings.TrimRight(domain, ".")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if domainInKillfile(fqdn) {
 | 
							if domainInKillfile(fqdn, config) {
 | 
				
			||||||
			go incrementStats("Killed", 1)
 | 
								go incrementStats("Killed", 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			msg.Answer = append(msg.Answer, &dns.A{
 | 
								msg.Answer = append(msg.Answer, &dns.A{
 | 
				
			||||||
| 
						 | 
					@ -32,11 +36,11 @@ func (mydns *handler) ServeDNS(w dns.ResponseWriter, r *dns.Msg) {
 | 
				
			||||||
				A:   net.ParseIP(ZabovAddBL),
 | 
									A:   net.ParseIP(ZabovAddBL),
 | 
				
			||||||
			})
 | 
								})
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			ret := ForwardQuery(r)
 | 
								ret := ForwardQuery(r, config)
 | 
				
			||||||
			w.WriteMsg(ret)
 | 
								w.WriteMsg(ret)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		ret := ForwardQuery(r)
 | 
							ret := ForwardQuery(r, config)
 | 
				
			||||||
		w.WriteMsg(ret)
 | 
							w.WriteMsg(ret)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	w.WriteMsg(&msg)
 | 
						w.WriteMsg(&msg)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										21
									
								
								hostfile.go
								
								
								
								
							
							
						
						
									
										21
									
								
								hostfile.go
								
								
								
								
							| 
						 | 
					@ -9,12 +9,26 @@ import (
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fmt.Println("Ingesting local hosts file")
 | 
						fmt.Println("Ingesting local hosts file")
 | 
				
			||||||
	ingestLocalBlacklist()
 | 
						ingestLocalBlacklists()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func ingestLocalBlacklist() {
 | 
					func ingestLocalBlacklists() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fmt.Println("ingestLocalBlacklist: collecting urls from all configs...")
 | 
				
			||||||
 | 
						_files := urlsMap{}
 | 
				
			||||||
 | 
						for config := range ZabovConfigs {
 | 
				
			||||||
 | 
							ZabovHostsFile := ZabovConfigs[config].ZabovHostsFile
 | 
				
			||||||
 | 
							configs := _files[ZabovHostsFile]
 | 
				
			||||||
 | 
							if configs == nil {
 | 
				
			||||||
 | 
								configs = stringarray{}
 | 
				
			||||||
 | 
								_files[ZabovHostsFile] = configs
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							configs = append(configs, config)
 | 
				
			||||||
 | 
							_files[ZabovHostsFile] = configs
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for ZabovHostsFile, configs := range _files {
 | 
				
			||||||
		file, err := os.Open(ZabovHostsFile)
 | 
							file, err := os.Open(ZabovHostsFile)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			fmt.Println(err.Error())
 | 
								fmt.Println(err.Error())
 | 
				
			||||||
| 
						 | 
					@ -24,7 +38,7 @@ func ingestLocalBlacklist() {
 | 
				
			||||||
		scanner := bufio.NewScanner(file)
 | 
							scanner := bufio.NewScanner(file)
 | 
				
			||||||
		for scanner.Scan() {
 | 
							for scanner.Scan() {
 | 
				
			||||||
			d := scanner.Text()
 | 
								d := scanner.Text()
 | 
				
			||||||
		DomainKill(d, ZabovHostsFile)
 | 
								DomainKill(d, ZabovHostsFile, configs)
 | 
				
			||||||
			incrementStats("Blacklist", 1)
 | 
								incrementStats("Blacklist", 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -32,6 +46,7 @@ func ingestLocalBlacklist() {
 | 
				
			||||||
		if err := scanner.Err(); err != nil {
 | 
							if err := scanner.Err(); err != nil {
 | 
				
			||||||
			fmt.Println(err.Error())
 | 
								fmt.Println(err.Error())
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										47
									
								
								main.go
								
								
								
								
							
							
						
						
									
										47
									
								
								main.go
								
								
								
								
							| 
						 | 
					@ -35,6 +35,53 @@ var ZabovDNSArray []string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type handler struct{}
 | 
					type handler struct{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//ZabovDNSArrays contains the arrays containing all the DNS we mention
 | 
				
			||||||
 | 
					var ZabovDNSArrays map[string][]string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ZabovConfig contains all Zabov configs
 | 
				
			||||||
 | 
					type ZabovConfig struct {
 | 
				
			||||||
 | 
						ZabovUpDNS     string // json:upstream -> ZabovDNSArray
 | 
				
			||||||
 | 
						ZabovSingleBL  string // json:singlefilters
 | 
				
			||||||
 | 
						ZabovDoubleBL  string // json:doublefilters
 | 
				
			||||||
 | 
						ZabovAddBL     string // json:blackholeip
 | 
				
			||||||
 | 
						ZabovHostsFile string // json:hostsfile
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ZabovConfigs contains all Zabov configs
 | 
				
			||||||
 | 
					var ZabovConfigs map[string]ZabovConfig
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ZabovConfigDefault contains only "default" config
 | 
				
			||||||
 | 
					var ZabovConfigDefault ZabovConfig
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ZabovIPGroup contains Zabov groups of IPs
 | 
				
			||||||
 | 
					type ZabovIPGroup struct {
 | 
				
			||||||
 | 
						ips       []string // IPs in this group
 | 
				
			||||||
 | 
						cfg       string   // config name to be used if there is no timetable
 | 
				
			||||||
 | 
						timetable string   // timetable name to be used for this group; timetable SHALL reference to config name to use
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ZabovIPGroups contains an array of all Zabov groups of IP rules
 | 
				
			||||||
 | 
					var ZabovIPGroups []ZabovIPGroup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ZabovTimetableEntry contains Zabov single time table entry
 | 
				
			||||||
 | 
					type ZabovTimetableEntry struct {
 | 
				
			||||||
 | 
						times []string
 | 
				
			||||||
 | 
						days  []string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ZabovTimetable contains a Zabov time table
 | 
				
			||||||
 | 
					type ZabovTimetable struct {
 | 
				
			||||||
 | 
						table  []ZabovTimetableEntry
 | 
				
			||||||
 | 
						cfgin  string // configuration name to be used if "inside" timetable
 | 
				
			||||||
 | 
						cfgout string // configuration name to be used if "outiside" timetable
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ZabovTimetables contains all Zabov time tables, by name
 | 
				
			||||||
 | 
					var ZabovTimetables map[string]ZabovTimetable
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ZabovIPAliases contains an array of all Zabov IP aliases
 | 
				
			||||||
 | 
					var ZabovIPAliases map[string]string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func main() {
 | 
					func main() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	MyDNS.Handler = &handler{}
 | 
						MyDNS.Handler = &handler{}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue