mirror of
https://github.com/lukaszraczylo/lolcathost.git
synced 2026-06-13 01:29:17 +00:00
Initial commit.
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
// Package daemon provides DNS cache flushing functionality.
|
||||
package daemon
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// DNSFlusher handles DNS cache flushing.
|
||||
type DNSFlusher struct {
|
||||
method FlushMethod
|
||||
}
|
||||
|
||||
// FlushMethod defines the DNS flush method to use.
|
||||
type FlushMethod string
|
||||
|
||||
const (
|
||||
FlushMethodAuto FlushMethod = "auto"
|
||||
FlushMethodDscacheutil FlushMethod = "dscacheutil"
|
||||
FlushMethodKillall FlushMethod = "killall"
|
||||
FlushMethodBoth FlushMethod = "both"
|
||||
FlushMethodSystemd FlushMethod = "systemd"
|
||||
FlushMethodNscd FlushMethod = "nscd"
|
||||
)
|
||||
|
||||
// NewDNSFlusher creates a new DNS flusher.
|
||||
func NewDNSFlusher(method FlushMethod) *DNSFlusher {
|
||||
return &DNSFlusher{method: method}
|
||||
}
|
||||
|
||||
// Flush flushes the DNS cache using the configured method.
|
||||
func (f *DNSFlusher) Flush() error {
|
||||
method := f.method
|
||||
if method == FlushMethodAuto || method == "" {
|
||||
method = f.detectMethod()
|
||||
}
|
||||
|
||||
switch runtime.GOOS {
|
||||
case "darwin":
|
||||
return f.flushDarwin(method)
|
||||
case "linux":
|
||||
return f.flushLinux(method)
|
||||
default:
|
||||
return fmt.Errorf("unsupported operating system: %s", runtime.GOOS)
|
||||
}
|
||||
}
|
||||
|
||||
func (f *DNSFlusher) detectMethod() FlushMethod {
|
||||
switch runtime.GOOS {
|
||||
case "darwin":
|
||||
return FlushMethodBoth
|
||||
case "linux":
|
||||
// Check for systemd-resolve first
|
||||
if _, err := exec.LookPath("systemd-resolve"); err == nil {
|
||||
return FlushMethodSystemd
|
||||
}
|
||||
if _, err := exec.LookPath("resolvectl"); err == nil {
|
||||
return FlushMethodSystemd
|
||||
}
|
||||
// Fall back to nscd
|
||||
if _, err := exec.LookPath("nscd"); err == nil {
|
||||
return FlushMethodNscd
|
||||
}
|
||||
return FlushMethodAuto
|
||||
default:
|
||||
return FlushMethodAuto
|
||||
}
|
||||
}
|
||||
|
||||
func (f *DNSFlusher) flushDarwin(method FlushMethod) error {
|
||||
var errs []error
|
||||
|
||||
switch method {
|
||||
case FlushMethodDscacheutil:
|
||||
if err := runCommand("dscacheutil", "-flushcache"); err != nil {
|
||||
return fmt.Errorf("dscacheutil failed: %w", err)
|
||||
}
|
||||
case FlushMethodKillall:
|
||||
if err := runCommand("killall", "-HUP", "mDNSResponder"); err != nil {
|
||||
return fmt.Errorf("killall mDNSResponder failed: %w", err)
|
||||
}
|
||||
case FlushMethodBoth:
|
||||
if err := runCommand("dscacheutil", "-flushcache"); err != nil {
|
||||
errs = append(errs, fmt.Errorf("dscacheutil failed: %w", err))
|
||||
}
|
||||
if err := runCommand("killall", "-HUP", "mDNSResponder"); err != nil {
|
||||
errs = append(errs, fmt.Errorf("killall mDNSResponder failed: %w", err))
|
||||
}
|
||||
if len(errs) == 2 {
|
||||
return fmt.Errorf("all DNS flush methods failed: %v, %v", errs[0], errs[1])
|
||||
}
|
||||
default:
|
||||
// Auto - try both
|
||||
_ = runCommand("dscacheutil", "-flushcache")
|
||||
_ = runCommand("killall", "-HUP", "mDNSResponder")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *DNSFlusher) flushLinux(method FlushMethod) error {
|
||||
switch method {
|
||||
case FlushMethodSystemd:
|
||||
// Try resolvectl first (newer), then systemd-resolve (older)
|
||||
if err := runCommand("resolvectl", "flush-caches"); err != nil {
|
||||
if err := runCommand("systemd-resolve", "--flush-caches"); err != nil {
|
||||
return fmt.Errorf("systemd DNS flush failed: %w", err)
|
||||
}
|
||||
}
|
||||
case FlushMethodNscd:
|
||||
// Try to restart nscd
|
||||
if err := runCommand("nscd", "-i", "hosts"); err != nil {
|
||||
// Try service restart as fallback
|
||||
if err := runCommand("service", "nscd", "restart"); err != nil {
|
||||
return fmt.Errorf("nscd flush failed: %w", err)
|
||||
}
|
||||
}
|
||||
default:
|
||||
// Auto - try all methods
|
||||
// Try systemd first
|
||||
if err := runCommand("resolvectl", "flush-caches"); err == nil {
|
||||
return nil
|
||||
}
|
||||
if err := runCommand("systemd-resolve", "--flush-caches"); err == nil {
|
||||
return nil
|
||||
}
|
||||
// Try nscd
|
||||
if err := runCommand("nscd", "-i", "hosts"); err == nil {
|
||||
return nil
|
||||
}
|
||||
// On many Linux systems, no explicit flush is needed as /etc/hosts is read directly
|
||||
// So we return nil here
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func runCommand(name string, args ...string) error {
|
||||
cmd := exec.Command(name, args...)
|
||||
return cmd.Run()
|
||||
}
|
||||
Reference in New Issue
Block a user