Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/add tcp support to dnsproxy #5

Merged
merged 3 commits into from
Dec 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 52 additions & 19 deletions internal/dnsproxy/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ const (

// Proxy is a DNS proxy
type Proxy struct {
server *dns.Server
udp *dns.Server
tcp *dns.Server
remotes *Remotes
watches *Watches
reports chan *Report
done chan struct{}

// channels for temp watch cleaning goroutine
stopClean chan struct{}
Expand Down Expand Up @@ -132,22 +134,54 @@ func (p *Proxy) cleanTempWatches() {
}
}

// startDNSServer starts the dns server
func (p *Proxy) startDNSServer(server *dns.Server) {
log.WithFields(log.Fields{
"addr": server.Addr,
"net": server.Net,
}).Debug("DNS-Proxy starting server")
err := server.ListenAndServe()
if err != nil {
log.WithError(err).Error("DNS-Proxy DNS server stopped")
}
}

// stopDNSServer stops the dns server
func (p *Proxy) stopDNSServer(server *dns.Server) {
err := server.Shutdown()
if err != nil {
log.WithFields(log.Fields{
"addr": server.Addr,
"net": server.Net,
"error": err,
}).Error("DNS-Proxy could not stop DNS server")
}
}

// start starts running the proxy
func (p *Proxy) start() {
// start cleaning goroutine
go p.cleanTempWatches()

// start dns server
// start dns servers
log.Debug("DNS-Proxy registering handler")
dns.HandleFunc(".", p.handleRequest)
log.WithFields(log.Fields{
"addr": p.server.Addr,
"net": p.server.Net,
}).Debug("DNS-Proxy starting server")
err := p.server.ListenAndServe()
if err != nil {
log.WithError(err).Error("DNS-Proxy could not start DNS server")
for _, srv := range []*dns.Server{p.udp, p.tcp} {
go p.startDNSServer(srv)
}

// wait for proxy termination
<-p.done

// stop cleaning goroutine
close(p.stopClean)
<-p.doneClean

// stop dns servers
for _, srv := range []*dns.Server{p.udp, p.tcp} {
p.stopDNSServer(srv)
}
close(p.reports)
}

// Start starts running the proxy
Expand All @@ -157,16 +191,10 @@ func (p *Proxy) Start() {

// Stop stops running the proxy
func (p *Proxy) Stop() {
// stop cleaning goroutine
close(p.stopClean)
<-p.doneClean

// stop server
err := p.server.Shutdown()
if err != nil {
log.WithError(err).Fatal("DNS-Proxy could not stop DNS server")
close(p.done)
for range p.reports {
// wait for channel shutdown
}
close(p.reports)
}

// Reports returns the Report channel for watched domains
Expand All @@ -193,13 +221,18 @@ func (p *Proxy) SetWatches(watches []string) {
// NewProxy returns a new Proxy that listens on address
func NewProxy(address string) *Proxy {
return &Proxy{
server: &dns.Server{
udp: &dns.Server{
Addr: address,
Net: "udp",
},
tcp: &dns.Server{
Addr: address,
Net: "tcp",
},
remotes: NewRemotes(),
watches: NewWatches(),
reports: make(chan *Report),
done: make(chan struct{}),

stopClean: make(chan struct{}),
doneClean: make(chan struct{}),
Expand Down
4 changes: 3 additions & 1 deletion internal/dnsproxy/proxy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,12 @@ func TestProxySetWatches(t *testing.T) {
// TestNewProxy tests NewProxy
func TestNewProxy(t *testing.T) {
p := NewProxy("127.0.0.1:4254")
if p.server == nil ||
if p.udp == nil ||
p.tcp == nil ||
p.remotes == nil ||
p.watches == nil ||
p.reports == nil ||
p.done == nil ||
p.stopClean == nil ||
p.doneClean == nil {

Expand Down
6 changes: 6 additions & 0 deletions internal/vpnconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,9 @@ func (c *Config) SetDNS(server string) {

// flush dns caches
runResolvectl("flush-caches")

// reset learnt server features
runResolvectl("reset-server-features")
}

// UnsetDNS unsets the DNS configuration
Expand All @@ -259,6 +262,9 @@ func (c *Config) UnsetDNS() {

// flush dns caches
runResolvectl("flush-caches")

// reset learnt server features
runResolvectl("reset-server-features")
}

// New returns a new Config
Expand Down
2 changes: 2 additions & 0 deletions internal/vpnconfig/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ func TestConfigSetDNS(t *testing.T) {
"domain tun0 mycompany.com ~.",
"default-route tun0 yes",
"flush-caches",
"reset-server-features",
}
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, want %v", got, want)
Expand All @@ -300,6 +301,7 @@ func TestConfigUnsetDNS(t *testing.T) {
want := []string{
"revert tun0",
"flush-caches",
"reset-server-features",
}
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, want %v", got, want)
Expand Down
1 change: 1 addition & 0 deletions tools/dnsproxy/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,5 +74,6 @@ func main() {
go p.Start()
for r := range p.Reports() {
log.WithField("report", r).Debug("DNS-Proxy got watched domain report")
r.Done()
}
}