mirror of
https://github.com/netbirdio/netbird.git
synced 2025-01-23 14:28:51 +01:00
User custom loopback address (#589)
We will probe a set of addresses and port to define the one available for our DNS service if none is available, we return an error
This commit is contained in:
parent
20a73e3e14
commit
ae500b63a7
@ -15,9 +15,10 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
port = 53
|
||||
customPort = 5053
|
||||
defaultIP = "127.0.0.1"
|
||||
defaultPort = 53
|
||||
customPort = 5053
|
||||
defaultIP = "127.0.0.1"
|
||||
customIP = "127.0.0.153"
|
||||
)
|
||||
|
||||
// Server is a dns server interface
|
||||
@ -54,13 +55,8 @@ type muxUpdate struct {
|
||||
// NewDefaultServer returns a new dns server
|
||||
func NewDefaultServer(ctx context.Context, wgInterface *iface.WGIface) (*DefaultServer, error) {
|
||||
mux := dns.NewServeMux()
|
||||
listenIP := defaultIP
|
||||
if runtime.GOOS != "darwin" && wgInterface != nil {
|
||||
listenIP = wgInterface.GetAddress().IP.String()
|
||||
}
|
||||
|
||||
dnsServer := &dns.Server{
|
||||
Addr: fmt.Sprintf("%s:%d", listenIP, port),
|
||||
Net: "udp",
|
||||
Handler: mux,
|
||||
UDPSize: 65535,
|
||||
@ -78,8 +74,7 @@ func NewDefaultServer(ctx context.Context, wgInterface *iface.WGIface) (*Default
|
||||
registeredMap: make(registrationMap),
|
||||
},
|
||||
wgInterface: wgInterface,
|
||||
runtimePort: port,
|
||||
runtimeIP: listenIP,
|
||||
runtimePort: defaultPort,
|
||||
}
|
||||
|
||||
hostmanager, err := newHostManager(wgInterface)
|
||||
@ -92,19 +87,15 @@ func NewDefaultServer(ctx context.Context, wgInterface *iface.WGIface) (*Default
|
||||
|
||||
// Start runs the listener in a go routine
|
||||
func (s *DefaultServer) Start() {
|
||||
s.runtimePort = port
|
||||
udpAddr := net.UDPAddrFromAddrPort(netip.MustParseAddrPort(s.server.Addr))
|
||||
probeListener, err := net.ListenUDP("udp", udpAddr)
|
||||
|
||||
ip, port, err := s.getFirstListenerAvailable()
|
||||
if err != nil {
|
||||
log.Warnf("using a custom port for dns server")
|
||||
s.runtimePort = customPort
|
||||
s.server.Addr = fmt.Sprintf("%s:%d", s.runtimeIP, customPort)
|
||||
} else {
|
||||
err = probeListener.Close()
|
||||
if err != nil {
|
||||
log.Errorf("got an error closing the probe listener, error: %s", err)
|
||||
}
|
||||
log.Error(err)
|
||||
return
|
||||
}
|
||||
s.runtimeIP = ip
|
||||
s.runtimePort = port
|
||||
s.server.Addr = fmt.Sprintf("%s:%d", s.runtimeIP, s.runtimePort)
|
||||
|
||||
log.Debugf("starting dns on %s", s.server.Addr)
|
||||
|
||||
@ -119,6 +110,30 @@ func (s *DefaultServer) Start() {
|
||||
}()
|
||||
}
|
||||
|
||||
func (s *DefaultServer) getFirstListenerAvailable() (string, int, error) {
|
||||
ips := []string{defaultIP, customIP}
|
||||
if runtime.GOOS != "darwin" && s.wgInterface != nil {
|
||||
ips = append([]string{s.wgInterface.GetAddress().IP.String()}, ips...)
|
||||
}
|
||||
ports := []int{defaultPort, customPort}
|
||||
for _, port := range ports {
|
||||
for _, ip := range ips {
|
||||
addrString := fmt.Sprintf("%s:%d", ip, port)
|
||||
udpAddr := net.UDPAddrFromAddrPort(netip.MustParseAddrPort(addrString))
|
||||
probeListener, err := net.ListenUDP("udp", udpAddr)
|
||||
if err == nil {
|
||||
err = probeListener.Close()
|
||||
if err != nil {
|
||||
log.Errorf("got an error closing the probe listener, error: %s", err)
|
||||
}
|
||||
return ip, port, nil
|
||||
}
|
||||
log.Warnf("binding dns on %s is not available, error: %s", addrString, err)
|
||||
}
|
||||
}
|
||||
return "", 0, fmt.Errorf("unable to find an unused ip and port combination. IPs tested: %v and ports %v", ips, ports)
|
||||
}
|
||||
|
||||
func (s *DefaultServer) setListenerStatus(running bool) {
|
||||
s.listenerIsRunning = running
|
||||
}
|
||||
|
@ -257,7 +257,7 @@ func TestDNSServerStartStop(t *testing.T) {
|
||||
d := net.Dialer{
|
||||
Timeout: time.Second * 5,
|
||||
}
|
||||
addr := fmt.Sprintf("127.0.0.1:%d", port)
|
||||
addr := fmt.Sprintf("%s:%d", dnsServer.runtimeIP, dnsServer.runtimePort)
|
||||
conn, err := d.DialContext(ctx, network, addr)
|
||||
if err != nil {
|
||||
t.Log(err)
|
||||
@ -297,7 +297,7 @@ func getDefaultServerWithNoHostManager(ip string) *DefaultServer {
|
||||
}
|
||||
|
||||
dnsServer := &dns.Server{
|
||||
Addr: fmt.Sprintf("%s:%d", ip, port),
|
||||
Addr: fmt.Sprintf("%s:%d", ip, defaultPort),
|
||||
Net: "udp",
|
||||
Handler: mux,
|
||||
UDPSize: 65535,
|
||||
@ -314,7 +314,7 @@ func getDefaultServerWithNoHostManager(ip string) *DefaultServer {
|
||||
localResolver: &localResolver{
|
||||
registeredMap: make(registrationMap),
|
||||
},
|
||||
runtimePort: port,
|
||||
runtimePort: defaultPort,
|
||||
runtimeIP: listenIP,
|
||||
}
|
||||
}
|
||||
|
@ -71,6 +71,10 @@ func TestEngine_SSH(t *testing.T) {
|
||||
WgPort: 33100,
|
||||
}, nbstatus.NewRecorder())
|
||||
|
||||
engine.dnsServer = &dns.MockServer{
|
||||
UpdateDNSServerFunc: func(serial uint64, update nbdns.Config) error { return nil },
|
||||
}
|
||||
|
||||
var sshKeysAdded []string
|
||||
var sshPeersRemoved []string
|
||||
|
||||
@ -385,6 +389,10 @@ func TestEngine_Sync(t *testing.T) {
|
||||
WgPort: 33100,
|
||||
}, nbstatus.NewRecorder())
|
||||
|
||||
engine.dnsServer = &dns.MockServer{
|
||||
UpdateDNSServerFunc: func(serial uint64, update nbdns.Config) error { return nil },
|
||||
}
|
||||
|
||||
defer func() {
|
||||
err := engine.Stop()
|
||||
if err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user