diff --git a/client/src/__locales/en.json b/client/src/__locales/en.json index 3b67dafc..846ecff0 100644 --- a/client/src/__locales/en.json +++ b/client/src/__locales/en.json @@ -83,7 +83,7 @@ "use_adguard_parental": "Use AdGuard parental control web service", "use_adguard_parental_hint": "AdGuard Home will check if domain contains adult materials. It uses the same privacy-friendly API as the browsing security web service.", "enforce_safe_search": "Enforce safe search", - "enforce_save_search_hint": "AdGuard Home can enforce safe search in the following search engines: Google, Youtube, Bing, and Yandex.", + "enforce_save_search_hint": "AdGuard Home can enforce safe search in the following search engines: Google, Youtube, Bing, DuckDuckGo and Yandex.", "no_servers_specified": "No servers specified", "no_settings": "No settings", "general_settings": "General settings", diff --git a/dhcpd/os_linux.go b/dhcpd/os_linux.go new file mode 100644 index 00000000..5cbcfece --- /dev/null +++ b/dhcpd/os_linux.go @@ -0,0 +1,45 @@ +package dhcpd + +import ( + "net" + "os" + "syscall" + + "golang.org/x/net/ipv4" +) + +// Create a socket for receiving broadcast packets +func newBroadcastPacketConn(bindAddr net.IP, port int, ifname string) (*ipv4.PacketConn, error) { + s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP) + if err != nil { + return nil, err + } + + if err := syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1); err != nil { + return nil, err + } + if err := syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1); err != nil { + return nil, err + } + if err := syscall.SetsockoptString(s, syscall.SOL_SOCKET, syscall.SO_BINDTODEVICE, ifname); err != nil { + return nil, err + } + + addr := syscall.SockaddrInet4{Port: port} + copy(addr.Addr[:], bindAddr.To4()) + err = syscall.Bind(s, &addr) + if err != nil { + syscall.Close(s) + return nil, err + } + + f := os.NewFile(uintptr(s), "") + c, err := net.FilePacketConn(f) + f.Close() + if err != nil { + return nil, err + } + + p := ipv4.NewPacketConn(c) + return p, nil +} diff --git a/dhcpd/os_unix.go b/dhcpd/os_unix.go index 638f2a6c..11592d33 100644 --- a/dhcpd/os_unix.go +++ b/dhcpd/os_unix.go @@ -1,4 +1,4 @@ -// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris +// +build aix darwin dragonfly freebsd netbsd openbsd solaris package dhcpd @@ -23,9 +23,6 @@ func newBroadcastPacketConn(bindAddr net.IP, port int, ifname string) (*ipv4.Pac if err := syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1); err != nil { return nil, err } - if err := syscall.SetsockoptString(s, syscall.SOL_SOCKET, syscall.SO_BINDTODEVICE, ifname); err != nil { - return nil, err - } addr := syscall.SockaddrInet4{Port: port} copy(addr.Addr[:], bindAddr.To4()) diff --git a/dhcpd/os_windows.go b/dhcpd/os_windows.go index 5eb7223a..607e3d1e 100644 --- a/dhcpd/os_windows.go +++ b/dhcpd/os_windows.go @@ -1,6 +1,7 @@ package dhcpd import ( + "errors" "net" "golang.org/x/net/ipv4" @@ -8,5 +9,5 @@ import ( // Create a socket for receiving broadcast packets func newBroadcastPacketConn(bindAddr net.IP, port int, ifname string) (*ipv4.PacketConn, error) { - return nil, nil + return nil, errors.New("newBroadcastPacketConn(): not supported on Windows") } diff --git a/dnsfilter/dnsfilter.go b/dnsfilter/dnsfilter.go index c487d7d2..e58b0350 100644 --- a/dnsfilter/dnsfilter.go +++ b/dnsfilter/dnsfilter.go @@ -649,15 +649,17 @@ func (d *Dnsfilter) checkSafeSearch(host string) (Result, error) { return Result{}, err } - res.IP = addrs[0] - // The next bug may occurs: LookupIP returns DNS64 mapped ipv4 address with zero-prefix for _, i := range addrs { - if ipv4 := i.To4(); ipv4 != nil && len(i) == net.IPv6len { + if ipv4 := i.To4(); ipv4 != nil { res.IP = ipv4 break } } + if len(res.IP) == 0 { + return Result{}, fmt.Errorf("no ipv4 addresses in safe search response for %s", safeHost) + } + // Cache result err = safeSearchCache.Set(host, res) if err != nil { @@ -1036,7 +1038,7 @@ func New(c *Config) *Dnsfilter { TLSHandshakeTimeout: 10 * time.Second, ExpectContinueTimeout: 1 * time.Second, } - if len(c.ResolverAddress) != 0 { + if c != nil && len(c.ResolverAddress) != 0 { resolverAddr = c.ResolverAddress d.transport.DialContext = customDialContext }