Skip to content

Commit

Permalink
Merge: Refactoring: move global variables; move initialization of per…
Browse files Browse the repository at this point in the history
…iodic tasks

Close #583

* commit 'b8444ff46aff5e45194c6cb61fdf4d3e7aa798fa':
  * minor
  * dnsforward: move initialization of periodic tasks to NewServer()
  * move "dnsctx" to "config"
  * move "dnsServer" to "config"
  * move "dhcpServer" to "config"
  * move "httpServer" to "config"
  * move "httpsServer" to "config"
  * move "pidFileName" to "config"
  * move "versionCheckJSON" to "config"
  * move "client", "transport" to "config"
  * move "controlLock" mutex to "config"
  * clients: move container object to "config"
  • Loading branch information
szolin committed Jul 19, 2019
2 parents 1973901 + b8444ff commit bd5162a
Show file tree
Hide file tree
Showing 14 changed files with 213 additions and 221 deletions.
38 changes: 14 additions & 24 deletions dnsforward/dnsforward.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ type Server struct {
dnsFilter *dnsfilter.Dnsfilter // DNS filter instance
queryLog *queryLog // Query log instance
stats *stats // General server statistics
once sync.Once

AllowedClients map[string]bool // IP addresses of whitelist clients
DisallowedClients map[string]bool // IP addresses of clients that should be blocked
Expand All @@ -55,11 +54,24 @@ type Server struct {

// NewServer creates a new instance of the dnsforward.Server
// baseDir is the base directory for query logs
// Note: this function must be called only once
func NewServer(baseDir string) *Server {
return &Server{
s := &Server{
queryLog: newQueryLog(baseDir),
stats: newStats(),
}

log.Tracef("Loading stats from querylog")
err := s.queryLog.fillStatsFromQueryLog(s.stats)
if err != nil {
log.Error("failed to load stats from querylog: %s", err)
}

log.Printf("Start DNS server periodic jobs")
go s.queryLog.periodicQueryLogRotate()
go s.queryLog.runningTop.periodicHourlyTopRotate()
go s.stats.statsRotator()
return s
}

// FilteringConfig represents the DNS filtering configuration of AdGuard Home
Expand Down Expand Up @@ -169,33 +181,11 @@ func (s *Server) startInternal(config *ServerConfig) error {
return errors.New("DNS server is already started")
}

if s.queryLog == nil {
s.queryLog = newQueryLog(".")
}

if s.stats == nil {
s.stats = newStats()
}

err := s.initDNSFilter()
if err != nil {
return err
}

log.Tracef("Loading stats from querylog")
err = s.queryLog.fillStatsFromQueryLog(s.stats)
if err != nil {
return errorx.Decorate(err, "failed to load stats from querylog")
}

// TODO: Think about reworking this, the current approach won't work properly if AG Home is restarted periodically
s.once.Do(func() {
log.Printf("Start DNS server periodic jobs")
go s.queryLog.periodicQueryLogRotate()
go s.queryLog.runningTop.periodicHourlyTopRotate()
go s.stats.statsRotator()
})

proxyConfig := proxy.Config{
UDPListenAddr: s.conf.UDPListenAddr,
TCPListenAddr: s.conf.TCPListenAddr,
Expand Down
73 changes: 37 additions & 36 deletions home/clients.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,33 +66,34 @@ type clientsContainer struct {
lock sync.Mutex
}

var clients clientsContainer

// Initialize clients container
func clientsInit() {
// Init initializes clients container
// Note: this function must be called only once
func (clients *clientsContainer) Init() {
if clients.list != nil {
log.Fatal("clients.list != nil")
}
clients.list = make(map[string]*Client)
clients.ipIndex = make(map[string]*Client)
clients.ipHost = make(map[string]ClientHost)

go periodicClientsUpdate()
go clients.periodicUpdate()
}

func periodicClientsUpdate() {
func (clients *clientsContainer) periodicUpdate() {
for {
clientsAddFromHostsFile()
clientsAddFromSystemARP()
clients.addFromHostsFile()
clients.addFromSystemARP()
time.Sleep(clientsUpdatePeriod)
}
}

func clientsGetList() map[string]*Client {
// GetList returns the pointer to clients list
func (clients *clientsContainer) GetList() map[string]*Client {
return clients.list
}

func clientExists(ip string) bool {
// Exists checks if client with this IP already exists
func (clients *clientsContainer) Exists(ip string) bool {
clients.lock.Lock()
defer clients.lock.Unlock()

Expand All @@ -105,8 +106,8 @@ func clientExists(ip string) bool {
return ok
}

// Search for a client by IP
func clientFind(ip string) (Client, bool) {
// Find searches for a client by IP
func (clients *clientsContainer) Find(ip string) (Client, bool) {
clients.lock.Lock()
defer clients.lock.Unlock()

Expand All @@ -121,7 +122,7 @@ func clientFind(ip string) (Client, bool) {
if err != nil {
continue
}
ipAddr := dhcpServer.FindIPbyMAC(mac)
ipAddr := config.dhcpServer.FindIPbyMAC(mac)
if ipAddr == nil {
continue
}
Expand All @@ -135,7 +136,7 @@ func clientFind(ip string) (Client, bool) {
}

// Check if Client object's fields are correct
func clientCheck(c *Client) error {
func (c *Client) check() error {
if len(c.Name) == 0 {
return fmt.Errorf("Invalid Name")
}
Expand All @@ -162,8 +163,8 @@ func clientCheck(c *Client) error {

// Add a new client object
// Return true: success; false: client exists.
func clientAdd(c Client) (bool, error) {
e := clientCheck(&c)
func (clients *clientsContainer) Add(c Client) (bool, error) {
e := c.check()
if e != nil {
return false, e
}
Expand Down Expand Up @@ -194,8 +195,8 @@ func clientAdd(c Client) (bool, error) {
return true, nil
}

// Remove a client
func clientDel(name string) bool {
// Del removes a client
func (clients *clientsContainer) Del(name string) bool {
clients.lock.Lock()
defer clients.lock.Unlock()

Expand All @@ -210,8 +211,8 @@ func clientDel(name string) bool {
}

// Update a client
func clientUpdate(name string, c Client) error {
err := clientCheck(&c)
func (clients *clientsContainer) Update(name string, c Client) error {
err := c.check()
if err != nil {
return err
}
Expand Down Expand Up @@ -257,10 +258,10 @@ func clientUpdate(name string, c Client) error {
return nil
}

// Add new IP -> Host pair
// AddHost adds new IP -> Host pair
// Use priority of the source (etc/hosts > ARP > rDNS)
// so we overwrite existing entries with an equal or higher priority
func clientAddHost(ip, host string, source clientSource) (bool, error) {
func (clients *clientsContainer) AddHost(ip, host string, source clientSource) (bool, error) {
clients.lock.Lock()
defer clients.lock.Unlock()

Expand All @@ -279,7 +280,7 @@ func clientAddHost(ip, host string, source clientSource) (bool, error) {
}

// Parse system 'hosts' file and fill clients array
func clientsAddFromHostsFile() {
func (clients *clientsContainer) addFromHostsFile() {
hostsFn := "/etc/hosts"
if runtime.GOOS == "windows" {
hostsFn = os.ExpandEnv("$SystemRoot\\system32\\drivers\\etc\\hosts")
Expand All @@ -304,7 +305,7 @@ func clientsAddFromHostsFile() {
continue
}

ok, e := clientAddHost(fields[0], fields[1], ClientSourceHostsFile)
ok, e := clients.AddHost(fields[0], fields[1], ClientSourceHostsFile)
if e != nil {
log.Tracef("%s", e)
}
Expand All @@ -319,7 +320,7 @@ func clientsAddFromHostsFile() {
// Add IP -> Host pairs from the system's `arp -a` command output
// The command's output is:
// HOST (IP) at MAC on IFACE
func clientsAddFromSystemARP() {
func (clients *clientsContainer) addFromSystemARP() {

if runtime.GOOS == "windows" {
return
Expand Down Expand Up @@ -350,7 +351,7 @@ func clientsAddFromSystemARP() {
continue
}

ok, e := clientAddHost(ip, host, ClientSourceARP)
ok, e := clients.AddHost(ip, host, ClientSourceARP)
if e != nil {
log.Tracef("%s", e)
}
Expand Down Expand Up @@ -379,8 +380,8 @@ func handleGetClients(w http.ResponseWriter, r *http.Request) {

data := clientListJSON{}

clients.lock.Lock()
for _, c := range clients.list {
config.clients.lock.Lock()
for _, c := range config.clients.list {
cj := clientJSON{
IP: c.IP,
MAC: c.MAC,
Expand All @@ -394,15 +395,15 @@ func handleGetClients(w http.ResponseWriter, r *http.Request) {

if len(c.MAC) != 0 {
hwAddr, _ := net.ParseMAC(c.MAC)
ipAddr := dhcpServer.FindIPbyMAC(hwAddr)
ipAddr := config.dhcpServer.FindIPbyMAC(hwAddr)
if ipAddr != nil {
cj.IP = ipAddr.String()
}
}

data.Clients = append(data.Clients, cj)
}
for ip, ch := range clients.ipHost {
for ip, ch := range config.clients.ipHost {
cj := clientHostJSON{
IP: ip,
Name: ch.Host,
Expand All @@ -416,7 +417,7 @@ func handleGetClients(w http.ResponseWriter, r *http.Request) {
}
data.AutoClients = append(data.AutoClients, cj)
}
clients.lock.Unlock()
config.clients.lock.Unlock()

w.Header().Set("Content-Type", "application/json")
e := json.NewEncoder(w).Encode(data)
Expand Down Expand Up @@ -462,7 +463,7 @@ func handleAddClient(w http.ResponseWriter, r *http.Request) {
httpError(w, http.StatusBadRequest, "%s", err)
return
}
ok, err := clientAdd(*c)
ok, err := config.clients.Add(*c)
if err != nil {
httpError(w, http.StatusBadRequest, "%s", err)
return
Expand Down Expand Up @@ -492,7 +493,7 @@ func handleDelClient(w http.ResponseWriter, r *http.Request) {
return
}

if !clientDel(cj.Name) {
if !config.clients.Del(cj.Name) {
httpError(w, http.StatusBadRequest, "Client not found")
return
}
Expand All @@ -501,7 +502,7 @@ func handleDelClient(w http.ResponseWriter, r *http.Request) {
returnOK(w)
}

type clientUpdateJSON struct {
type updateJSON struct {
Name string `json:"name"`
Data clientJSON `json:"data"`
}
Expand All @@ -515,7 +516,7 @@ func handleUpdateClient(w http.ResponseWriter, r *http.Request) {
return
}

var dj clientUpdateJSON
var dj updateJSON
err = json.Unmarshal(body, &dj)
if err != nil {
httpError(w, http.StatusBadRequest, "JSON parse: %s", err)
Expand All @@ -532,7 +533,7 @@ func handleUpdateClient(w http.ResponseWriter, r *http.Request) {
return
}

err = clientUpdate(dj.Name, *c)
err = config.clients.Update(dj.Name, *c)
if err != nil {
httpError(w, http.StatusBadRequest, "%s", err)
return
Expand Down
Loading

0 comments on commit bd5162a

Please sign in to comment.