badguardhome/internal/home/portsmap.go
Eugene Burkov b3210cfa7e 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
2021-12-16 20:54:59 +03:00

64 lines
1.3 KiB
Go

package home
import (
"fmt"
"strconv"
"strings"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/stringutil"
)
// portsMap is a helper type for mapping a network port to the number of its
// users.
type portsMap map[int]int
// add binds each of ps. Zeroes are skipped.
func (pm portsMap) add(ps ...int) {
for _, p := range ps {
if p == 0 {
continue
}
pm[p]++
}
}
// validate returns an error about all the ports bound several times.
func (pm portsMap) validate() (err error) {
overbound := []int{}
for p, num := range pm {
if num > 1 {
overbound = append(overbound, p)
pm[p] = 1
}
}
switch len(overbound) {
case 0:
return nil
case 1:
return fmt.Errorf("port %d is already used", overbound[0])
default:
b := &strings.Builder{}
// TODO(e.burkov, a.garipov): Add JoinToBuilder helper to stringutil.
stringutil.WriteToBuilder(b, "ports ", strconv.Itoa(overbound[0]))
for _, p := range overbound[1:] {
stringutil.WriteToBuilder(b, ", ", strconv.Itoa(p))
}
stringutil.WriteToBuilder(b, " are already used")
return errors.Error(b.String())
}
}
// validatePorts is a helper function for a single-step ports binding
// validation.
func validatePorts(ps ...int) (err error) {
pm := portsMap{}
pm.add(ps...)
return pm.validate()
}