Skip to content
Open
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
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ GOAMD64 = v1
GOPROXY = https://proxy.golang.org|direct
GOTELEMETRY = off
OUT = dnsproxy
GOTOOLCHAIN = go1.25.5
GOTOOLCHAIN = go1.25.7
RACE = 0
REVISION = $${REVISION:-$$(git rev-parse --short HEAD)}
VERSION = 0
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/AdguardTeam/dnsproxy

go 1.25.5
go 1.25.7

require (
github.com/AdguardTeam/golibs v0.35.2
Expand Down
8 changes: 8 additions & 0 deletions internal/cmd/args.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const (
upstreamModeIdx
listenAddrsIdx
listenPortsIdx
httpListenPortsIdx
httpsListenPortsIdx
tlsListenPortsIdx
quicListenPortsIdx
Expand Down Expand Up @@ -151,6 +152,12 @@ var commandLineOptions = []*commandLineOption{
short: "p",
valueType: "port",
},
httpListenPortsIdx: {
description: "Listening ports for DNS-over-HTTP.",
long: "http-port",
short: "i",
valueType: "port",
},
httpsListenPortsIdx: {
description: "Listening ports for DNS-over-HTTPS.",
long: "https-port",
Expand Down Expand Up @@ -424,6 +431,7 @@ func parseCmdLineOptions(conf *configuration) (err error) {
upstreamModeIdx: &conf.UpstreamMode,
listenAddrsIdx: &conf.ListenAddrs,
listenPortsIdx: &conf.ListenPorts,
httpListenPortsIdx: &conf.HTTPListenPorts,
httpsListenPortsIdx: &conf.HTTPSListenPorts,
tlsListenPortsIdx: &conf.TLSListenPorts,
quicListenPortsIdx: &conf.QUICListenPorts,
Expand Down
3 changes: 3 additions & 0 deletions internal/cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ type configuration struct {
// ListenPorts are the ports server listens on.
ListenPorts []int `yaml:"listen-ports"`

// HTTP listen ports are the ports server listens on for DNS-over-HTTP.
HTTPListenPorts []int `yaml:"http-port"`

// HTTPSListenPorts are the ports server listens on for DNS-over-HTTPS.
HTTPSListenPorts []int `yaml:"https-port"`

Expand Down
7 changes: 7 additions & 0 deletions internal/cmd/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,13 @@ func (conf *configuration) initListenAddrs(config *proxy.Config) (err error) {
}
}

for _, ip := range addrs {
for _, port := range conf.HTTPListenPorts {
a := net.TCPAddrFromAddrPort(netip.AddrPortFrom(ip, uint16(port)))
config.HTTPListenAddr = append(config.HTTPListenAddr, a)
}
}

initTLSListenAddrs(config, conf, addrs)
initDNSCryptListenAddrs(config, conf, addrs)

Expand Down
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ import (
func main() {
cmd.Main()
}

3 changes: 3 additions & 0 deletions proxy/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ type Config struct {
// requests.
HTTPSListenAddr []*net.TCPAddr

HTTPListenAddr []*net.TCPAddr // if nil, then it does not listen for HTTP (DoH)

// TLSListenAddr is the set of TCP addresses to listen for DNS-over-TLS
// requests.
TLSListenAddr []*net.TCPAddr
Expand Down Expand Up @@ -448,6 +450,7 @@ func (p *Proxy) hasListenAddrs() bool {
return p.UDPListenAddr != nil ||
p.TCPListenAddr != nil ||
p.TLSListenAddr != nil ||
p.HTTPListenAddr != nil ||
p.HTTPSListenAddr != nil ||
p.QUICListenAddr != nil ||
p.DNSCryptUDPListenAddr != nil ||
Expand Down
11 changes: 11 additions & 0 deletions proxy/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,9 @@ type Proxy struct {
// them.
quicTransports []*quic.Transport

httpListen []net.Listener // HTTP listeners
httpServer *http.Server // HTTP server instance

// httpsListen are the listened HTTPS connections.
httpsListen []net.Listener

Expand Down Expand Up @@ -444,6 +447,14 @@ func (p *Proxy) closeListeners(errs []error) (res []error) {
p.httpsListen = nil
}

if p.httpServer != nil {
res = closeAll(res, p.httpServer)
p.httpServer = nil

// No need to close these since they're closed by httpsServer.Close().
p.httpListen = nil
}

if p.h3Server != nil {
res = closeAll(res, p.h3Server)
p.h3Server = nil
Expand Down
1 change: 1 addition & 0 deletions proxy/proxy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,3 +182,4 @@ func TestProxy_Start_closeOnFail(t *testing.T) {
servicetest.RequireRun(t, p, testTimeout)
}))
}
p.HTTPListenAddr = []*net.TCPAddr{{IP: ip, Port: 0}}
9 changes: 9 additions & 0 deletions proxy/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ func (p *Proxy) startListeners(ctx context.Context) (err error) {
return err
}

err = p.initHTTPListeners(ctx)
if err != nil {
return err
}

err = p.initHTTPSListeners(ctx)
if err != nil {
return err
Expand Down Expand Up @@ -67,6 +72,10 @@ func (p *Proxy) serveListeners() {
go p.tcpPacketLoop(l, ProtoTLS, p.requestsSema)
}

for _, l := range p.httpListen {
go func(l net.Listener) { _ = p.httpServer.Serve(l) }(l)
}

for _, l := range p.httpsListen {
go func(l net.Listener) { _ = p.httpsServer.Serve(l) }(l)
}
Expand Down
40 changes: 34 additions & 6 deletions proxy/serverhttps.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
func (p *Proxy) listenHTTP(
ctx context.Context,
addr *net.TCPAddr,
withTLS bool,
) (ln net.Listener, tcpAddr *net.TCPAddr, err error) {
var tcpListen *net.TCPListener
err = p.bindWithRetry(ctx, func() (listenErr error) {
Expand All @@ -45,14 +46,20 @@ func (p *Proxy) listenHTTP(
return nil, nil, fmt.Errorf("bad listener address type: %T", laddr)
}

p.logger.InfoContext(ctx, "listening to https", "addr", tcpAddr)
if withTLS {
p.logger.InfoContext(ctx, "listening to https", "addr", tcpAddr)

tlsConfig := p.TLSConfig.Clone()
tlsConfig.NextProtos = []string{http2.NextProtoTLS, "http/1.1"}
tlsConfig := p.TLSConfig.Clone()
tlsConfig.NextProtos = []string{http2.NextProtoTLS, "http/1.1"}

tlsListen := tls.NewListener(tcpListen, tlsConfig)

tlsListen := tls.NewListener(tcpListen, tlsConfig)
return tlsListen, tcpAddr, nil
}

return tlsListen, tcpAddr, nil
p.logger.InfoContext(ctx, "listening to http", "addr", tcpAddr)

return tcpListen, tcpAddr, nil
}

// listenH3 creates instances of QUIC listeners that will be used for running
Expand All @@ -73,6 +80,27 @@ func (p *Proxy) listenH3(
return quicListen, nil
}

func (p *Proxy) initHTTPListeners(ctx context.Context) (err error) {
p.httpServer = &http.Server{
Handler: p,
ReadHeaderTimeout: defaultTimeout,
WriteTimeout: defaultTimeout,
}

for _, addr := range p.HTTPListenAddr {
p.logger.InfoContext(ctx, "creating an http server")

ln, _, lErr := p.listenHTTP(ctx, addr, false)
if lErr != nil {
return fmt.Errorf("failed to start HTTPS server on %s: %w", addr, lErr)
}

p.httpListen = append(p.httpListen, ln)
}

return nil
}

// initHTTPSListeners creates TCP/UDP listeners and HTTP/H3 servers.
func (p *Proxy) initHTTPSListeners(ctx context.Context) (err error) {
p.httpsServer = &http.Server{
Expand All @@ -90,7 +118,7 @@ func (p *Proxy) initHTTPSListeners(ctx context.Context) (err error) {
for _, addr := range p.HTTPSListenAddr {
p.logger.InfoContext(ctx, "creating an https server")

ln, tcpAddr, lErr := p.listenHTTP(ctx, addr)
ln, tcpAddr, lErr := p.listenHTTP(ctx, addr, true)
if lErr != nil {
return fmt.Errorf("failed to start HTTPS server on %s: %w", addr, lErr)
}
Expand Down