Pull request: 3835 check ports properly

Merge in DNS/adguard-home from 3835-imp-error-msg to master

Updates #3835.

Squashed commit of the following:

commit ba31cb67833df9f293fe13be96a35c2a823f115b
Merge: 19c7dfc9 4be69d35
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Dec 16 20:07:25 2021 +0300

    Merge branch 'master' into 3835-imp-error-msg

commit 19c7dfc96284a271d30d7111c86c439be3461389
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Dec 16 19:42:10 2021 +0300

    all: imp more

commit 5b9c6a3e357238bf44ef800a6033a7671f27d469
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Dec 16 18:57:02 2021 +0300

    all: introduce aghhttp

commit 29caa17200957aad2b98461573bb33d80931adcf
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Dec 16 14:23:53 2021 +0300

    all: imp more

commit 754c020191d7b9518cb0e789f3f5741ba38c3cf4
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Wed Dec 15 20:53:41 2021 +0300

    all: imp code, log changes

commit ec712dd562f31fcc2fbc27e7035f926c79827444
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Wed Dec 15 18:40:54 2021 +0300

    home: check ports properly
This commit is contained in:
Eugene Burkov
2021-12-16 20:54:59 +03:00
parent 4be69d35eb
commit b3210cfa7e
31 changed files with 675 additions and 348 deletions

View File

@@ -4,13 +4,11 @@ package aghnet
import (
"encoding/json"
"fmt"
"io"
"net"
"os"
"os/exec"
"runtime"
"strings"
"syscall"
"time"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/log"
@@ -189,57 +187,30 @@ func GetSubnet(ifaceName string) *net.IPNet {
return nil
}
// CheckPortAvailable - check if TCP port is available
func CheckPortAvailable(host net.IP, port int) error {
ln, err := net.Listen("tcp", netutil.JoinHostPort(host.String(), port))
if err != nil {
return err
// CheckPort checks if the port is available for binding.
func CheckPort(network string, ip net.IP, port int) (err error) {
var c io.Closer
addr := netutil.IPPort{IP: ip, Port: port}.String()
switch network {
case "tcp":
c, err = net.Listen(network, addr)
case "udp":
c, err = net.ListenPacket(network, addr)
default:
return nil
}
_ = ln.Close()
// It seems that net.Listener.Close() doesn't close file descriptors right away.
// We wait for some time and hope that this fd will be closed.
time.Sleep(100 * time.Millisecond)
return nil
return errors.WithDeferred(err, closePortChecker(c))
}
// CheckPacketPortAvailable - check if UDP port is available
func CheckPacketPortAvailable(host net.IP, port int) error {
ln, err := net.ListenPacket("udp", netutil.JoinHostPort(host.String(), port))
if err != nil {
return err
}
_ = ln.Close()
// It seems that net.Listener.Close() doesn't close file descriptors right away.
// We wait for some time and hope that this fd will be closed.
time.Sleep(100 * time.Millisecond)
return err
}
// ErrorIsAddrInUse - check if error is "address already in use"
func ErrorIsAddrInUse(err error) bool {
errOpError, ok := err.(*net.OpError)
if !ok {
// IsAddrInUse checks if err is about unsuccessful address binding.
func IsAddrInUse(err error) (ok bool) {
var sysErr syscall.Errno
if !errors.As(err, &sysErr) {
return false
}
errSyscallError, ok := errOpError.Err.(*os.SyscallError)
if !ok {
return false
}
errErrno, ok := errSyscallError.Err.(syscall.Errno)
if !ok {
return false
}
if runtime.GOOS == "windows" {
const WSAEADDRINUSE = 10048
return errErrno == WSAEADDRINUSE
}
return errErrno == syscall.EADDRINUSE
return isAddrInUse(sysErr)
}
// SplitHost is a wrapper for net.SplitHostPort for the cases when the hostport