mirror of
https://github.com/netbirdio/netbird.git
synced 2025-02-02 19:39:17 +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 (
|
const (
|
||||||
port = 53
|
defaultPort = 53
|
||||||
customPort = 5053
|
customPort = 5053
|
||||||
defaultIP = "127.0.0.1"
|
defaultIP = "127.0.0.1"
|
||||||
|
customIP = "127.0.0.153"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Server is a dns server interface
|
// Server is a dns server interface
|
||||||
@ -54,13 +55,8 @@ type muxUpdate struct {
|
|||||||
// NewDefaultServer returns a new dns server
|
// NewDefaultServer returns a new dns server
|
||||||
func NewDefaultServer(ctx context.Context, wgInterface *iface.WGIface) (*DefaultServer, error) {
|
func NewDefaultServer(ctx context.Context, wgInterface *iface.WGIface) (*DefaultServer, error) {
|
||||||
mux := dns.NewServeMux()
|
mux := dns.NewServeMux()
|
||||||
listenIP := defaultIP
|
|
||||||
if runtime.GOOS != "darwin" && wgInterface != nil {
|
|
||||||
listenIP = wgInterface.GetAddress().IP.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
dnsServer := &dns.Server{
|
dnsServer := &dns.Server{
|
||||||
Addr: fmt.Sprintf("%s:%d", listenIP, port),
|
|
||||||
Net: "udp",
|
Net: "udp",
|
||||||
Handler: mux,
|
Handler: mux,
|
||||||
UDPSize: 65535,
|
UDPSize: 65535,
|
||||||
@ -78,8 +74,7 @@ func NewDefaultServer(ctx context.Context, wgInterface *iface.WGIface) (*Default
|
|||||||
registeredMap: make(registrationMap),
|
registeredMap: make(registrationMap),
|
||||||
},
|
},
|
||||||
wgInterface: wgInterface,
|
wgInterface: wgInterface,
|
||||||
runtimePort: port,
|
runtimePort: defaultPort,
|
||||||
runtimeIP: listenIP,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hostmanager, err := newHostManager(wgInterface)
|
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
|
// Start runs the listener in a go routine
|
||||||
func (s *DefaultServer) Start() {
|
func (s *DefaultServer) Start() {
|
||||||
|
|
||||||
|
ip, port, err := s.getFirstListenerAvailable()
|
||||||
|
if err != nil {
|
||||||
|
log.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
s.runtimeIP = ip
|
||||||
s.runtimePort = port
|
s.runtimePort = port
|
||||||
udpAddr := net.UDPAddrFromAddrPort(netip.MustParseAddrPort(s.server.Addr))
|
s.server.Addr = fmt.Sprintf("%s:%d", s.runtimeIP, s.runtimePort)
|
||||||
probeListener, err := net.ListenUDP("udp", udpAddr)
|
|
||||||
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.Debugf("starting dns on %s", s.server.Addr)
|
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) {
|
func (s *DefaultServer) setListenerStatus(running bool) {
|
||||||
s.listenerIsRunning = running
|
s.listenerIsRunning = running
|
||||||
}
|
}
|
||||||
|
@ -257,7 +257,7 @@ func TestDNSServerStartStop(t *testing.T) {
|
|||||||
d := net.Dialer{
|
d := net.Dialer{
|
||||||
Timeout: time.Second * 5,
|
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)
|
conn, err := d.DialContext(ctx, network, addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Log(err)
|
t.Log(err)
|
||||||
@ -297,7 +297,7 @@ func getDefaultServerWithNoHostManager(ip string) *DefaultServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dnsServer := &dns.Server{
|
dnsServer := &dns.Server{
|
||||||
Addr: fmt.Sprintf("%s:%d", ip, port),
|
Addr: fmt.Sprintf("%s:%d", ip, defaultPort),
|
||||||
Net: "udp",
|
Net: "udp",
|
||||||
Handler: mux,
|
Handler: mux,
|
||||||
UDPSize: 65535,
|
UDPSize: 65535,
|
||||||
@ -314,7 +314,7 @@ func getDefaultServerWithNoHostManager(ip string) *DefaultServer {
|
|||||||
localResolver: &localResolver{
|
localResolver: &localResolver{
|
||||||
registeredMap: make(registrationMap),
|
registeredMap: make(registrationMap),
|
||||||
},
|
},
|
||||||
runtimePort: port,
|
runtimePort: defaultPort,
|
||||||
runtimeIP: listenIP,
|
runtimeIP: listenIP,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,6 +71,10 @@ func TestEngine_SSH(t *testing.T) {
|
|||||||
WgPort: 33100,
|
WgPort: 33100,
|
||||||
}, nbstatus.NewRecorder())
|
}, nbstatus.NewRecorder())
|
||||||
|
|
||||||
|
engine.dnsServer = &dns.MockServer{
|
||||||
|
UpdateDNSServerFunc: func(serial uint64, update nbdns.Config) error { return nil },
|
||||||
|
}
|
||||||
|
|
||||||
var sshKeysAdded []string
|
var sshKeysAdded []string
|
||||||
var sshPeersRemoved []string
|
var sshPeersRemoved []string
|
||||||
|
|
||||||
@ -385,6 +389,10 @@ func TestEngine_Sync(t *testing.T) {
|
|||||||
WgPort: 33100,
|
WgPort: 33100,
|
||||||
}, nbstatus.NewRecorder())
|
}, nbstatus.NewRecorder())
|
||||||
|
|
||||||
|
engine.dnsServer = &dns.MockServer{
|
||||||
|
UpdateDNSServerFunc: func(serial uint64, update nbdns.Config) error { return nil },
|
||||||
|
}
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
err := engine.Stop()
|
err := engine.Stop()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user