From de837e4eec58763ad96eea2eb9b357336fc0fea3 Mon Sep 17 00:00:00 2001 From: Eugene Burkov Date: Thu, 29 Sep 2022 14:56:37 +0300 Subject: [PATCH] all: use netip for web --- internal/aghnet/net.go | 14 +++++++------- internal/aghnet/net_test.go | 2 +- internal/home/config.go | 11 +++++------ internal/home/control.go | 2 +- internal/home/controlinstall.go | 6 +++--- internal/home/dns.go | 2 +- internal/home/home.go | 2 +- internal/home/options.go | 26 +++++++++++++------------- internal/home/options_test.go | 12 +++++++----- internal/home/web.go | 9 ++------- 10 files changed, 41 insertions(+), 45 deletions(-) diff --git a/internal/aghnet/net.go b/internal/aghnet/net.go index 25133027..910177ac 100644 --- a/internal/aghnet/net.go +++ b/internal/aghnet/net.go @@ -130,7 +130,7 @@ func NetInterfaceFrom(iface *net.Interface) (niface *NetInterface, err error) { for _, addr := range addrs { n, ok := addr.(*net.IPNet) if !ok { - // Should be net.IPNet, this is weird. + // Should be *net.IPNet, this is weird. return nil, fmt.Errorf("expected %[2]s to be %[1]T, got %[2]T", n, addr) } else if ip4 := n.IP.To4(); ip4 != nil { n.IP = ip4 @@ -141,13 +141,13 @@ func NetInterfaceFrom(iface *net.Interface) (niface *NetInterface, err error) { return nil, fmt.Errorf("bad address %s", n.IP) } - ip = ip.WithZone(iface.Name) + if ip.IsLinkLocalUnicast() { + // Ignore link-local IPv4. + if ip.Is4() { + continue + } - // Ignore link-local IPv4. - // - // TODO(e.burkov): !! or not?? - if ip.Is4() && ip.IsLinkLocalUnicast() { - continue + ip = ip.WithZone(iface.Name) } ones, _ := n.Mask.Size() diff --git a/internal/aghnet/net_test.go b/internal/aghnet/net_test.go index a8f46fa0..8b4046f4 100644 --- a/internal/aghnet/net_test.go +++ b/internal/aghnet/net_test.go @@ -199,7 +199,7 @@ func TestBroadcastFromIPNet(t *testing.T) { } func TestCheckPort(t *testing.T) { - laddr := netip.AddrPortFrom(netip.AddrFrom4([4]byte{127, 0, 0, 1}), 0) + laddr := netip.AddrPortFrom(IPv4Localhost(), 0) t.Run("tcp_bound", func(t *testing.T) { l, err := net.Listen("tcp", laddr.String()) diff --git a/internal/home/config.go b/internal/home/config.go index b65949a8..e3629b13 100644 --- a/internal/home/config.go +++ b/internal/home/config.go @@ -3,7 +3,6 @@ package home import ( "bytes" "fmt" - "net" "net/netip" "os" "path/filepath" @@ -86,10 +85,10 @@ type configuration struct { // It's reset after config is parsed fileData []byte - BindHost net.IP `yaml:"bind_host"` // BindHost is the IP address of the HTTP server to bind to - BindPort int `yaml:"bind_port"` // BindPort is the port the HTTP server - BetaBindPort int `yaml:"beta_bind_port"` // BetaBindPort is the port for new client - Users []User `yaml:"users"` // Users that can access HTTP server + BindHost netip.Addr `yaml:"bind_host"` // BindHost is the IP address of the HTTP server to bind to + BindPort int `yaml:"bind_port"` // BindPort is the port the HTTP server + BetaBindPort int `yaml:"beta_bind_port"` // BetaBindPort is the port for new client + Users []User `yaml:"users"` // Users that can access HTTP server // AuthAttempts is the maximum number of failed login attempts a user // can do before being blocked. AuthAttempts uint `yaml:"auth_attempts"` @@ -199,7 +198,7 @@ type tlsConfigSettings struct { var config = &configuration{ BindPort: 3000, BetaBindPort: 0, - BindHost: net.IP{0, 0, 0, 0}, + BindHost: netip.IPv4Unspecified(), AuthAttempts: 5, AuthBlockMin: 15, WebSessionTTLHours: 30 * 24, diff --git a/internal/home/control.go b/internal/home/control.go index 4428ae12..fd411bc5 100644 --- a/internal/home/control.go +++ b/internal/home/control.go @@ -71,7 +71,7 @@ func appendDNSAddrsWithIfaces(dst []string, src []netip.Addr) (res []string, err // on, including the addresses on all interfaces in cases of unspecified IPs. func collectDNSAddresses() (addrs []string, err error) { if hosts := config.DNS.BindHosts; len(hosts) == 0 { - addr := netip.AddrFrom4([4]byte{127, 0, 0, 1}) + addr := aghnet.IPv4Localhost() addrs = appendDNSAddrs(addrs, addr) } else { diff --git a/internal/home/controlinstall.go b/internal/home/controlinstall.go index 40137377..88acfa7a 100644 --- a/internal/home/controlinstall.go +++ b/internal/home/controlinstall.go @@ -406,7 +406,7 @@ func (web *Web) handleInstallConfigure(w http.ResponseWriter, r *http.Request) { copyInstallSettings(curConfig, config) Context.firstRun = false - config.BindHost = req.Web.IP.AsSlice() + config.BindHost = req.Web.IP config.BindPort = req.Web.Port config.DNS.BindHosts = []netip.Addr{req.DNS.IP} config.DNS.Port = req.DNS.Port @@ -439,7 +439,7 @@ func (web *Web) handleInstallConfigure(w http.ResponseWriter, r *http.Request) { } web.conf.firstRun = false - web.conf.BindHost = req.Web.IP.AsSlice() + web.conf.BindHost = req.Web.IP web.conf.BindPort = req.Web.Port registerControlHandlers() @@ -481,7 +481,7 @@ func decodeApplyConfigReq(r io.Reader) (req *applyConfigReq, restartHTTP bool, e return nil, false, errors.Error("ports cannot be 0") } - restartHTTP = !config.BindHost.Equal(req.Web.IP.AsSlice()) || config.BindPort != req.Web.Port + restartHTTP = config.BindHost != req.Web.IP || config.BindPort != req.Web.Port if restartHTTP { err = aghnet.CheckPort("tcp", netip.AddrPortFrom(req.Web.IP, uint16(req.Web.Port))) if err != nil { diff --git a/internal/home/dns.go b/internal/home/dns.go index 7f89a052..d4dd3d50 100644 --- a/internal/home/dns.go +++ b/internal/home/dns.go @@ -195,7 +195,7 @@ func generateServerConfig() (newConf dnsforward.ServerConfig, err error) { dnsConf := config.DNS hosts := dnsConf.BindHosts if len(hosts) == 0 { - hosts = []netip.Addr{netip.AddrFrom4([4]byte{127, 0, 0, 1})} + hosts = []netip.Addr{aghnet.IPv4Localhost()} } newConf = dnsforward.ServerConfig{ diff --git a/internal/home/home.go b/internal/home/home.go index c49142d7..1d418712 100644 --- a/internal/home/home.go +++ b/internal/home/home.go @@ -340,7 +340,7 @@ func setupConfig(args options) (err error) { } // override bind host/port from the console - if args.bindHost != nil { + if args.bindHost.IsValid() { config.BindHost = args.bindHost } if len(args.pidFile) != 0 && writePIDFile(args.pidFile) { diff --git a/internal/home/options.go b/internal/home/options.go index 6f5a4d8d..b8410442 100644 --- a/internal/home/options.go +++ b/internal/home/options.go @@ -2,7 +2,7 @@ package home import ( "fmt" - "net" + "net/netip" "os" "strconv" @@ -12,15 +12,15 @@ import ( // options passed from command-line arguments type options struct { - verbose bool // is verbose logging enabled - configFilename string // path to the config file - workDir string // path to the working directory where we will store the filters data and the querylog - bindHost net.IP // host address to bind HTTP server on - bindPort int // port to serve HTTP pages on - logFile string // Path to the log file. If empty, write to stdout. If "syslog", writes to syslog - pidFile string // File name to save PID to - checkConfig bool // Check configuration and exit - disableUpdate bool // If set, don't check for updates + verbose bool // is verbose logging enabled + configFilename string // path to the config file + workDir string // path to the working directory where we will store the filters data and the querylog + bindHost netip.Addr // host address to bind HTTP server on + bindPort int // port to serve HTTP pages on + logFile string // Path to the log file. If empty, write to stdout. If "syslog", writes to syslog + pidFile string // File name to save PID to + checkConfig bool // Check configuration and exit + disableUpdate bool // If set, don't check for updates // service control action (see service.ControlAction array + "status" command) serviceControlAction string @@ -60,8 +60,8 @@ type arg struct { // against its zero value and return nil if the parameter value is // zero otherwise they return a string slice of the parameter -func ipSliceOrNil(ip net.IP) []string { - if ip == nil { +func ipSliceOrNil(ip netip.Addr) []string { + if !ip.IsValid() { return nil } @@ -113,7 +113,7 @@ var workDirArg = arg{ var hostArg = arg{ "Host address to bind HTTP server on.", "host", "h", - func(o options, v string) (options, error) { o.bindHost = net.ParseIP(v); return o, nil }, nil, nil, + func(o options, v string) (options, error) { o.bindHost, _ = netip.ParseAddr(v); return o, nil }, nil, nil, func(o options) []string { return ipSliceOrNil(o.bindHost) }, } diff --git a/internal/home/options_test.go b/internal/home/options_test.go index 21972b0a..bc35a899 100644 --- a/internal/home/options_test.go +++ b/internal/home/options_test.go @@ -2,7 +2,7 @@ package home import ( "fmt" - "net" + "net/netip" "testing" "github.com/stretchr/testify/assert" @@ -56,11 +56,13 @@ func TestParseWorkDir(t *testing.T) { } func TestParseBindHost(t *testing.T) { - assert.Nil(t, testParseOK(t).bindHost, "empty is not host") - assert.Equal(t, net.IPv4(1, 2, 3, 4), testParseOK(t, "-h", "1.2.3.4").bindHost, "-h is host") + wantAddr := netip.AddrFrom4([4]byte{1, 2, 3, 4}) + + assert.Zero(t, testParseOK(t).bindHost, "empty is not host") + assert.Equal(t, wantAddr, testParseOK(t, "-h", "1.2.3.4").bindHost, "-h is host") testParseParamMissing(t, "-h") - assert.Equal(t, net.IPv4(1, 2, 3, 4), testParseOK(t, "--host", "1.2.3.4").bindHost, "--host is host") + assert.Equal(t, wantAddr, testParseOK(t, "--host", "1.2.3.4").bindHost, "--host is host") testParseParamMissing(t, "--host") } @@ -149,7 +151,7 @@ func TestSerialize(t *testing.T) { ss: []string{"-w", "path"}, }, { name: "bind_host", - opts: options{bindHost: net.IP{1, 2, 3, 4}}, + opts: options{bindHost: netip.AddrFrom4([4]byte{1, 2, 3, 4})}, ss: []string{"-h", "1.2.3.4"}, }, { name: "bind_port", diff --git a/internal/home/web.go b/internal/home/web.go index d379abe7..feef33e7 100644 --- a/internal/home/web.go +++ b/internal/home/web.go @@ -4,7 +4,6 @@ import ( "context" "crypto/tls" "io/fs" - "net" "net/http" "net/netip" "sync" @@ -36,8 +35,7 @@ type webConfig struct { clientFS fs.FS clientBetaFS fs.FS - // TODO(e.burkov): !! use netip - BindHost net.IP + BindHost netip.Addr BindPort int BetaBindPort int PortHTTPS int @@ -120,10 +118,7 @@ func WebCheckPortAvailable(port int) bool { return true } - // TODO(e.burkov): !! use netip - addr, ok := netip.AddrFromSlice(config.BindHost) - - return ok && aghnet.CheckPort("tcp", netip.AddrPortFrom(addr, uint16(port))) == nil + return aghnet.CheckPort("tcp", netip.AddrPortFrom(config.BindHost, uint16(port))) == nil } // TLSConfigChanged updates the TLS configuration and restarts the HTTPS server