| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051 |
- // Copyright (c) Tailscale Inc & AUTHORS
- // SPDX-License-Identifier: BSD-3-Clause
- //go:build linux && !android
- // Package linuxdnsfight provides Linux support for detecting DNS fights
- // (inotify watching of /etc/resolv.conf).
- package linuxdnsfight
- import (
- "context"
- "fmt"
- "github.com/illarion/gonotify/v3"
- "tailscale.com/net/dns"
- )
- func init() {
- dns.HookWatchFile.Set(watchFile)
- }
- // watchFile sets up an inotify watch for a given directory and
- // calls the callback function every time a particular file is changed.
- // The filename should be located in the provided directory.
- func watchFile(ctx context.Context, dir, filename string, cb func()) error {
- ctx, cancel := context.WithCancel(ctx)
- defer cancel()
- const events = gonotify.IN_ATTRIB |
- gonotify.IN_CLOSE_WRITE |
- gonotify.IN_CREATE |
- gonotify.IN_DELETE |
- gonotify.IN_MODIFY |
- gonotify.IN_MOVE
- watcher, err := gonotify.NewDirWatcher(ctx, events, dir)
- if err != nil {
- return fmt.Errorf("NewDirWatcher: %w", err)
- }
- for {
- select {
- case event := <-watcher.C:
- if event.Name == filename {
- cb()
- }
- case <-ctx.Done():
- return ctx.Err()
- }
- }
- }
|