Fix #1069 install: check static ip
Squashed commit of the following: commit57466233cbMerge:2df5f281867bf545Author: Andrey Meshkov <am@adguard.com> Date: Thu Feb 13 18:39:15 2020 +0300 Merge branch 'master' into 1069-install-static-ip commit2df5f281c4Author: Andrey Meshkov <am@adguard.com> Date: Thu Feb 13 18:35:54 2020 +0300 *: lang fix commitb4649a6b27Merge:c2785253f61d5f0fAuthor: Andrey Meshkov <am@adguard.com> Date: Thu Feb 13 16:47:30 2020 +0300 *(home): fixed issues with setting static IP on Mac commitc27852537dAuthor: Andrey Meshkov <am@adguard.com> Date: Thu Feb 13 14:14:30 2020 +0300 +(dhcpd): added static IP for MacOS commitf61d5f0f85Author: Ildar Kamalov <i.kamalov@adguard.com> Date: Thu Feb 13 14:13:35 2020 +0300 + client: show confirm before setting static IP commit7afa16fbe7Author: Ildar Kamalov <i.kamalov@adguard.com> Date: Thu Feb 13 13:51:52 2020 +0300 - client: fix text commit019bff0851Author: Ildar Kamalov <i.kamalov@adguard.com> Date: Thu Feb 13 13:49:16 2020 +0300 - client: pass all params to the check_config request commit194bed72f5Author: Andrey Meshkov <am@adguard.com> Date: Wed Feb 12 17:12:16 2020 +0300 *: fix home_test commit9359f6b55fMerge:ae299058c5ca2a77Author: Andrey Meshkov <am@adguard.com> Date: Wed Feb 12 15:54:54 2020 +0300 Merge with master commitae2990582dAuthor: Andrey Meshkov <am@adguard.com> Date: Wed Feb 12 15:53:36 2020 +0300 *(global): refactoring - moved runtime properties to Context commitd8d48c5386Author: Andrey Meshkov <am@adguard.com> Date: Wed Feb 12 15:04:25 2020 +0300 *(dhcpd): refactoring, use dhcpd/network_utils where possible commit8d039c572fAuthor: Ildar Kamalov <i.kamalov@adguard.com> Date: Fri Feb 7 18:37:39 2020 +0300 - client: fix button position commit26c47e59ddAuthor: Ildar Kamalov <i.kamalov@adguard.com> Date: Fri Feb 7 18:08:56 2020 +0300 - client: fix static ip description commitcb12babc46Author: Andrey Meshkov <am@adguard.com> Date: Fri Feb 7 17:08:39 2020 +0300 *: lower log level for some commands commitd9001ff848Author: Andrey Meshkov <am@adguard.com> Date: Fri Feb 7 16:17:59 2020 +0300 *(documentation): updated openapi commit1d213d53c8Merge:8406d7d280861860Author: Andrey Meshkov <am@adguard.com> Date: Fri Feb 7 15:16:46 2020 +0300 *: merge with master commit8406d7d288Author: Ildar Kamalov <i.kamalov@adguard.com> Date: Fri Jan 31 16:52:22 2020 +0300 - client: fix locales commitfb476b0117Author: Simon Zolin <s.zolin@adguard.com> Date: Fri Jan 31 13:29:03 2020 +0300 linter commit84b5708e71Author: Simon Zolin <s.zolin@adguard.com> Date: Fri Jan 31 13:27:53 2020 +0300 linter commit143a86a28aAuthor: Simon Zolin <s.zolin@adguard.com> Date: Fri Jan 31 13:26:47 2020 +0300 linter ... and 7 more commits
This commit is contained in:
@@ -13,6 +13,10 @@ import (
|
||||
"runtime"
|
||||
"strconv"
|
||||
|
||||
"github.com/AdguardTeam/AdGuardHome/util"
|
||||
|
||||
"github.com/AdguardTeam/AdGuardHome/dhcpd"
|
||||
|
||||
"github.com/AdguardTeam/golibs/log"
|
||||
)
|
||||
|
||||
@@ -22,13 +26,21 @@ type firstRunData struct {
|
||||
Interfaces map[string]interface{} `json:"interfaces"`
|
||||
}
|
||||
|
||||
type netInterfaceJSON struct {
|
||||
Name string `json:"name"`
|
||||
MTU int `json:"mtu"`
|
||||
HardwareAddr string `json:"hardware_address"`
|
||||
Addresses []string `json:"ip_addresses"`
|
||||
Flags string `json:"flags"`
|
||||
}
|
||||
|
||||
// Get initial installation settings
|
||||
func handleInstallGetAddresses(w http.ResponseWriter, r *http.Request) {
|
||||
data := firstRunData{}
|
||||
data.WebPort = 80
|
||||
data.DNSPort = 53
|
||||
|
||||
ifaces, err := getValidNetInterfacesForWeb()
|
||||
ifaces, err := util.GetValidNetInterfacesForWeb()
|
||||
if err != nil {
|
||||
httpError(w, http.StatusInternalServerError, "Couldn't get interfaces: %s", err)
|
||||
return
|
||||
@@ -36,7 +48,14 @@ func handleInstallGetAddresses(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
data.Interfaces = make(map[string]interface{})
|
||||
for _, iface := range ifaces {
|
||||
data.Interfaces[iface.Name] = iface
|
||||
ifaceJSON := netInterfaceJSON{
|
||||
Name: iface.Name,
|
||||
MTU: iface.MTU,
|
||||
HardwareAddr: iface.HardwareAddr,
|
||||
Addresses: iface.Addresses,
|
||||
Flags: iface.Flags,
|
||||
}
|
||||
data.Interfaces[iface.Name] = ifaceJSON
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
@@ -53,17 +72,24 @@ type checkConfigReqEnt struct {
|
||||
Autofix bool `json:"autofix"`
|
||||
}
|
||||
type checkConfigReq struct {
|
||||
Web checkConfigReqEnt `json:"web"`
|
||||
DNS checkConfigReqEnt `json:"dns"`
|
||||
Web checkConfigReqEnt `json:"web"`
|
||||
DNS checkConfigReqEnt `json:"dns"`
|
||||
SetStaticIP bool `json:"set_static_ip"`
|
||||
}
|
||||
|
||||
type checkConfigRespEnt struct {
|
||||
Status string `json:"status"`
|
||||
CanAutofix bool `json:"can_autofix"`
|
||||
}
|
||||
type staticIPJSON struct {
|
||||
Static string `json:"static"`
|
||||
IP string `json:"ip"`
|
||||
Error string `json:"error"`
|
||||
}
|
||||
type checkConfigResp struct {
|
||||
Web checkConfigRespEnt `json:"web"`
|
||||
DNS checkConfigRespEnt `json:"dns"`
|
||||
Web checkConfigRespEnt `json:"web"`
|
||||
DNS checkConfigRespEnt `json:"dns"`
|
||||
StaticIP staticIPJSON `json:"static_ip"`
|
||||
}
|
||||
|
||||
// Check if ports are available, respond with results
|
||||
@@ -77,16 +103,16 @@ func handleInstallCheckConfig(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if reqData.Web.Port != 0 && reqData.Web.Port != config.BindPort {
|
||||
err = checkPortAvailable(reqData.Web.IP, reqData.Web.Port)
|
||||
err = util.CheckPortAvailable(reqData.Web.IP, reqData.Web.Port)
|
||||
if err != nil {
|
||||
respData.Web.Status = fmt.Sprintf("%v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if reqData.DNS.Port != 0 {
|
||||
err = checkPacketPortAvailable(reqData.DNS.IP, reqData.DNS.Port)
|
||||
err = util.CheckPacketPortAvailable(reqData.DNS.IP, reqData.DNS.Port)
|
||||
|
||||
if errorIsAddrInUse(err) {
|
||||
if util.ErrorIsAddrInUse(err) {
|
||||
canAutofix := checkDNSStubListener()
|
||||
if canAutofix && reqData.DNS.Autofix {
|
||||
|
||||
@@ -95,7 +121,7 @@ func handleInstallCheckConfig(w http.ResponseWriter, r *http.Request) {
|
||||
log.Error("Couldn't disable DNSStubListener: %s", err)
|
||||
}
|
||||
|
||||
err = checkPacketPortAvailable(reqData.DNS.IP, reqData.DNS.Port)
|
||||
err = util.CheckPacketPortAvailable(reqData.DNS.IP, reqData.DNS.Port)
|
||||
canAutofix = false
|
||||
}
|
||||
|
||||
@@ -103,11 +129,13 @@ func handleInstallCheckConfig(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
err = checkPortAvailable(reqData.DNS.IP, reqData.DNS.Port)
|
||||
err = util.CheckPortAvailable(reqData.DNS.IP, reqData.DNS.Port)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
respData.DNS.Status = fmt.Sprintf("%v", err)
|
||||
} else {
|
||||
respData.StaticIP = handleStaticIP(reqData.DNS.IP, reqData.SetStaticIP)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,6 +147,46 @@ func handleInstallCheckConfig(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
// handleStaticIP - handles static IP request
|
||||
// It either checks if we have a static IP
|
||||
// Or if set=true, it tries to set it
|
||||
func handleStaticIP(ip string, set bool) staticIPJSON {
|
||||
resp := staticIPJSON{}
|
||||
|
||||
interfaceName := util.GetInterfaceByIP(ip)
|
||||
resp.Static = "no"
|
||||
|
||||
if len(interfaceName) == 0 {
|
||||
resp.Static = "error"
|
||||
resp.Error = fmt.Sprintf("Couldn't find network interface by IP %s", ip)
|
||||
return resp
|
||||
}
|
||||
|
||||
if set {
|
||||
// Try to set static IP for the specified interface
|
||||
err := dhcpd.SetStaticIP(interfaceName)
|
||||
if err != nil {
|
||||
resp.Static = "error"
|
||||
resp.Error = err.Error()
|
||||
return resp
|
||||
}
|
||||
}
|
||||
|
||||
// Fallthrough here even if we set static IP
|
||||
// Check if we have a static IP and return the details
|
||||
isStaticIP, err := dhcpd.HasStaticIP(interfaceName)
|
||||
if err != nil {
|
||||
resp.Static = "error"
|
||||
resp.Error = err.Error()
|
||||
} else {
|
||||
if isStaticIP {
|
||||
resp.Static = "yes"
|
||||
}
|
||||
resp.IP = util.GetSubnet(interfaceName)
|
||||
}
|
||||
return resp
|
||||
}
|
||||
|
||||
// Check if DNSStubListener is active
|
||||
func checkDNSStubListener() bool {
|
||||
if runtime.GOOS != "linux" {
|
||||
@@ -129,7 +197,7 @@ func checkDNSStubListener() bool {
|
||||
log.Tracef("executing %s %v", cmd.Path, cmd.Args)
|
||||
_, err := cmd.Output()
|
||||
if err != nil || cmd.ProcessState.ExitCode() != 0 {
|
||||
log.Error("command %s has failed: %v code:%d",
|
||||
log.Info("command %s has failed: %v code:%d",
|
||||
cmd.Path, err, cmd.ProcessState.ExitCode())
|
||||
return false
|
||||
}
|
||||
@@ -138,7 +206,7 @@ func checkDNSStubListener() bool {
|
||||
log.Tracef("executing %s %v", cmd.Path, cmd.Args)
|
||||
_, err = cmd.Output()
|
||||
if err != nil || cmd.ProcessState.ExitCode() != 0 {
|
||||
log.Error("command %s has failed: %v code:%d",
|
||||
log.Info("command %s has failed: %v code:%d",
|
||||
cmd.Path, err, cmd.ProcessState.ExitCode())
|
||||
return false
|
||||
}
|
||||
@@ -228,7 +296,7 @@ func handleInstallConfigure(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// validate that hosts and ports are bindable
|
||||
if restartHTTP {
|
||||
err = checkPortAvailable(newSettings.Web.IP, newSettings.Web.Port)
|
||||
err = util.CheckPortAvailable(newSettings.Web.IP, newSettings.Web.Port)
|
||||
if err != nil {
|
||||
httpError(w, http.StatusBadRequest, "Impossible to listen on IP:port %s due to %s",
|
||||
net.JoinHostPort(newSettings.Web.IP, strconv.Itoa(newSettings.Web.Port)), err)
|
||||
@@ -236,13 +304,13 @@ func handleInstallConfigure(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
err = checkPacketPortAvailable(newSettings.DNS.IP, newSettings.DNS.Port)
|
||||
err = util.CheckPacketPortAvailable(newSettings.DNS.IP, newSettings.DNS.Port)
|
||||
if err != nil {
|
||||
httpError(w, http.StatusBadRequest, "%s", err)
|
||||
return
|
||||
}
|
||||
|
||||
err = checkPortAvailable(newSettings.DNS.IP, newSettings.DNS.Port)
|
||||
err = util.CheckPortAvailable(newSettings.DNS.IP, newSettings.DNS.Port)
|
||||
if err != nil {
|
||||
httpError(w, http.StatusBadRequest, "%s", err)
|
||||
return
|
||||
@@ -251,7 +319,7 @@ func handleInstallConfigure(w http.ResponseWriter, r *http.Request) {
|
||||
var curConfig configuration
|
||||
copyInstallSettings(&curConfig, &config)
|
||||
|
||||
config.firstRun = false
|
||||
Context.firstRun = false
|
||||
config.BindHost = newSettings.Web.IP
|
||||
config.BindPort = newSettings.Web.Port
|
||||
config.DNS.BindHost = newSettings.DNS.IP
|
||||
@@ -266,7 +334,7 @@ func handleInstallConfigure(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
if err != nil || err2 != nil {
|
||||
config.firstRun = true
|
||||
Context.firstRun = true
|
||||
copyInstallSettings(&config, &curConfig)
|
||||
if err != nil {
|
||||
httpError(w, http.StatusInternalServerError, "Couldn't initialize DNS server: %s", err)
|
||||
@@ -278,11 +346,11 @@ func handleInstallConfigure(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
u := User{}
|
||||
u.Name = newSettings.Username
|
||||
config.auth.UserAdd(&u, newSettings.Password)
|
||||
Context.auth.UserAdd(&u, newSettings.Password)
|
||||
|
||||
err = config.write()
|
||||
if err != nil {
|
||||
config.firstRun = true
|
||||
Context.firstRun = true
|
||||
copyInstallSettings(&config, &curConfig)
|
||||
httpError(w, http.StatusInternalServerError, "Couldn't write config: %s", err)
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user