@@ -16,11 +16,20 @@ use crate::{check_command_output_status, netlink, IpVersion};
1616use crate :: { Peer , WireguardInterfaceError } ;
1717
1818#[ cfg( any( target_os = "freebsd" , target_os = "linux" , target_os = "netbsd" ) ) ]
19- pub ( crate ) fn configure_dns ( ifname : & str , dns : & [ IpAddr ] ) -> Result < ( ) , WireguardInterfaceError > {
19+ pub ( crate ) fn configure_dns (
20+ ifname : & str ,
21+ dns : & [ IpAddr ] ,
22+ search_domains : & [ & str ] ,
23+ ) -> Result < ( ) , WireguardInterfaceError > {
2024 // Build the resolvconf command
2125 debug ! ( "Setting up DNS" ) ;
2226 let mut cmd = Command :: new ( "resolvconf" ) ;
23- let args = [ "-a" , ifname, "-m" , "0" , "-x" ] ;
27+ let mut args = vec ! [ "-a" , ifname, "-m" , "0" ] ;
28+ // Set the exclusive flag if no search domains are provided,
29+ // making the DNS servers a preferred route for any domain
30+ if search_domains. is_empty ( ) {
31+ args. push ( "-x" ) ;
32+ }
2433 debug ! ( "Executing command resolvconf with args: {args:?}" ) ;
2534 cmd. args ( args) ;
2635
@@ -31,6 +40,10 @@ pub(crate) fn configure_dns(ifname: &str, dns: &[IpAddr]) -> Result<(), Wireguar
3140 debug ! ( "Adding nameserver entry: {entry}" ) ;
3241 writeln ! ( stdin, "nameserver {entry}" ) ?;
3342 }
43+ for domain in search_domains {
44+ debug ! ( "Adding search domain entry: {domain}" ) ;
45+ writeln ! ( stdin, "search {domain}" ) ?;
46+ }
3447 }
3548
3649 let status = child. wait ( ) . expect ( "Failed to wait for command" ) ;
@@ -65,7 +78,10 @@ fn network_services() -> Result<Vec<String>, IoError> {
6578}
6679
6780#[ cfg( target_os = "macos" ) ]
68- pub ( crate ) fn configure_dns ( dns : & [ IpAddr ] ) -> Result < ( ) , WireguardInterfaceError > {
81+ pub ( crate ) fn configure_dns (
82+ dns : & [ IpAddr ] ,
83+ search_domains : & [ & str ] ,
84+ ) -> Result < ( ) , WireguardInterfaceError > {
6985 for service in network_services ( ) ? {
7086 debug ! ( "Setting DNS entries for {service}" ) ;
7187 let mut cmd = Command :: new ( "networksetup" ) ;
@@ -77,8 +93,23 @@ pub(crate) fn configure_dns(dns: &[IpAddr]) -> Result<(), WireguardInterfaceErro
7793 cmd. args ( dns. iter ( ) . map ( ToString :: to_string) ) ;
7894 }
7995
96+ let status = cmd. status ( ) ?;
97+ if !status. success ( ) {
98+ warn ! ( "Command `networksetup` failed while setting DNS servers for {service}" ) ;
99+ }
100+
101+ // Set search domains, if empty, clear all search domains.
102+ debug ! ( "Setting search domains for {service}" ) ;
103+ let mut cmd = Command :: new ( "networksetup" ) ;
104+ cmd. arg ( "-setsearchdomains" ) . arg ( & service) ;
105+ if search_domains. is_empty ( ) {
106+ // This clears all search domains.
107+ cmd. arg ( "Empty" ) ;
108+ } else {
109+ cmd. args ( search_domains. iter ( ) ) ;
110+ }
80111 if !cmd. status ( ) ?. success ( ) {
81- warn ! ( "Command `networksetup` failed for {service}" ) ;
112+ warn ! ( "Command `networksetup` failed while setting search domains for {service}" ) ;
82113 }
83114 }
84115
0 commit comments