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

Refactor osdns to avoid using custom linker flags in common situations #903

Merged
merged 4 commits into from
Sep 11, 2024
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
3 changes: 3 additions & 0 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ jobs:
- name: Run martian unit test
run: make -C internal/martian test

- name: Run dnshack test
run: make -C utils/dnshack test

- name: Run unit test
run: make test coverage

Expand Down
2 changes: 1 addition & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,6 @@ issues:
- nosnakecase
source: "func Example"

- path: utils/osdns/
- path: utils/dnshack/
linters:
- goheader
2 changes: 2 additions & 0 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ builds:
- main: ./cmd/forwarder
env:
- CGO_ENABLED=0
tags:
- dnshack
flags:
- -trimpath
ldflags:
Expand Down
14 changes: 7 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
export GOBIN ?= $(CURDIR)/bin
export PATH := $(GOBIN):$(PATH)

GOLD = -ldflags "-checklinkname=0"

include .version

ifneq ($(shell expr $(MAKE_VERSION) \>= 4), 1)
Expand Down Expand Up @@ -60,25 +58,27 @@ lint:

.PHONY: test
test:
@go test $(GOLD) -timeout 120s -short -race -cover -coverprofile=coverage.out ./...
@go test -timeout 120s -short -race -cover -coverprofile=coverage.out ./...

.PHONY: coverage
coverage:
@go tool cover -func=coverage.out

export BUILDAH_FORMAT=docker

GOBUILD = go build -tags dnshack -ldflags "-checklinkname=0"

.PHONY: update-devel-image
update-devel-image: CONTAINER_RUNTIME ?= docker
update-devel-image: TAG=devel
update-devel-image: TMPDIR:=$(shell mktemp -d)
update-devel-image:
@ln Containerfile LICENSE LICENSE.3RD_PARTY $(TMPDIR)
ifeq ($(shell uname),Linux)
@CGO_ENABLED=1 GOOS=linux go build $(GOLD) -race -o $(TMPDIR)/forwarder ./cmd/forwarder
@CGO_ENABLED=1 GOOS=linux $(GOBUILD) -race -o $(TMPDIR)/forwarder ./cmd/forwarder
@$(CONTAINER_RUNTIME) buildx build --network host -f Containerfile --build-arg BASE_IMAGE=ubuntu:latest -t saucelabs/forwarder:$(TAG) $(TMPDIR)
else
@CGO_ENABLED=0 GOOS=linux go build $(GOLD) -o $(TMPDIR)/forwarder ./cmd/forwarder
@CGO_ENABLED=0 GOOS=linux $(GOBUILD) -o $(TMPDIR)/forwarder ./cmd/forwarder
@$(CONTAINER_RUNTIME) buildx build --network host -f Containerfile -t saucelabs/forwarder:$(TAG) $(TMPDIR)
endif
@rm -rf $(TMPDIR)
Expand All @@ -92,9 +92,9 @@ LICENSE.3RD_PARTY: LICENSE.3RD_PARTY.tpl go.mod go.sum
.PHONY: run
run: .forwarder.yaml
run:
@GOMAXPROCS=1 go run $(GOLD) ./cmd/forwarder run --config-file .forwarder.yaml
@GOMAXPROCS=1 go run ./cmd/forwarder run --config-file .forwarder.yaml

.PHONY: run-race
run-race: .forwarder.yaml
run-race:
@go run $(GOLD) --race ./cmd/forwarder run --config-file .forwarder.yaml
@go run --race ./cmd/forwarder run --config-file .forwarder.yaml
3 changes: 1 addition & 2 deletions bind/flag.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"github.com/saucelabs/forwarder/httplog"
"github.com/saucelabs/forwarder/log"
"github.com/saucelabs/forwarder/ruleset"
"github.com/saucelabs/forwarder/utils/osdns"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"golang.org/x/exp/slices"
Expand All @@ -35,7 +34,7 @@ func ConfigFile(fs *pflag.FlagSet, configFile *string) {
"The following precedence order of configuration sources is used: command flags, environment variables, config file, default values. ")
}

func DNSConfig(fs *pflag.FlagSet, cfg *osdns.Config) {
func DNSConfig(fs *pflag.FlagSet, cfg *forwarder.DNSConfig) {
fs.VarP(anyflag.NewSliceValue[netip.AddrPort](nil, &cfg.Servers, forwarder.ParseDNSAddress),
"dns-server", "n", "<ip>[:<port>]"+
"DNS server(s) to use instead of system default. "+
Expand Down
7 changes: 3 additions & 4 deletions command/pac/eval/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,18 @@ import (
"github.com/saucelabs/forwarder"
"github.com/saucelabs/forwarder/bind"
"github.com/saucelabs/forwarder/pac"
"github.com/saucelabs/forwarder/utils/osdns"
"github.com/spf13/cobra"
)

type command struct {
pac *url.URL
dnsConfig *osdns.Config
dnsConfig *forwarder.DNSConfig
httpTransportConfig *forwarder.HTTPTransportConfig
}

func (c *command) runE(cmd *cobra.Command, args []string) error {
if len(c.dnsConfig.Servers) > 0 {
if err := osdns.Configure(c.dnsConfig); err != nil {
if err := c.dnsConfig.Apply(); err != nil {
return fmt.Errorf("configure DNS: %w", err)
}
}
Expand Down Expand Up @@ -68,7 +67,7 @@ func (c *command) runE(cmd *cobra.Command, args []string) error {
func Command() *cobra.Command {
c := command{
pac: &url.URL{Scheme: "file", Path: "pac.js"},
dnsConfig: osdns.DefaultConfig(),
dnsConfig: forwarder.DefaultDNSConfig(),
httpTransportConfig: forwarder.DefaultHTTPTransportConfig(),
}

Expand Down
7 changes: 3 additions & 4 deletions command/pac/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,12 @@ import (
"github.com/saucelabs/forwarder/pac"
"github.com/saucelabs/forwarder/runctx"
"github.com/saucelabs/forwarder/utils/cobrautil"
"github.com/saucelabs/forwarder/utils/osdns"
"github.com/spf13/cobra"
)

type command struct {
pac *url.URL
dnsConfig *osdns.Config
dnsConfig *forwarder.DNSConfig
httpTransportConfig *forwarder.HTTPTransportConfig
httpServerConfig *forwarder.HTTPServerConfig
logConfig *log.Config
Expand Down Expand Up @@ -81,7 +80,7 @@ func (c *command) runE(cmd *cobra.Command, _ []string) (cmdErr error) {
if len(c.dnsConfig.Servers) > 0 {
s := strings.ReplaceAll(fmt.Sprintf("%s", c.dnsConfig.Servers), " ", ", ")
logger.Named("dns").Infof("using DNS servers %v", s)
if err := osdns.Configure(c.dnsConfig); err != nil {
if err := c.dnsConfig.Apply(); err != nil {
return fmt.Errorf("configure DNS: %w", err)
}
}
Expand Down Expand Up @@ -127,7 +126,7 @@ func servePAC(script string) http.Handler {
func Command() *cobra.Command {
c := command{
pac: &url.URL{Scheme: "file", Path: "pac.js"},
dnsConfig: osdns.DefaultConfig(),
dnsConfig: forwarder.DefaultDNSConfig(),
httpTransportConfig: forwarder.DefaultHTTPTransportConfig(),
httpServerConfig: forwarder.DefaultHTTPServerConfig(),
logConfig: log.DefaultConfig(),
Expand Down
7 changes: 3 additions & 4 deletions command/run/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,14 @@ import (
"github.com/saucelabs/forwarder/utils/cobrautil"
"github.com/saucelabs/forwarder/utils/httphandler"
"github.com/saucelabs/forwarder/utils/httpx"
"github.com/saucelabs/forwarder/utils/osdns"
"github.com/spf13/cobra"
"go.uber.org/goleak"
"go.uber.org/multierr"
)

type command struct {
promReg *prometheus.Registry
dnsConfig *osdns.Config
dnsConfig *forwarder.DNSConfig
httpTransportConfig *forwarder.HTTPTransportConfig
pac *url.URL
credentials []*forwarder.HostPortUser
Expand Down Expand Up @@ -129,7 +128,7 @@ func (c *command) runE(cmd *cobra.Command, _ []string) (cmdErr error) {
if len(c.dnsConfig.Servers) > 0 {
s := strings.ReplaceAll(fmt.Sprintf("%s", c.dnsConfig.Servers), " ", ", ")
logger.Named("dns").Infof("using DNS servers %v", s)
if err := osdns.Configure(c.dnsConfig); err != nil {
if err := c.dnsConfig.Apply(); err != nil {
return fmt.Errorf("configure dns: %w", err)
}
}
Expand Down Expand Up @@ -467,7 +466,7 @@ func Metrics() (*prometheus.Registry, error) {
func makeCommand() command {
c := command{
promReg: prometheus.NewRegistry(),
dnsConfig: osdns.DefaultConfig(),
dnsConfig: forwarder.DefaultDNSConfig(),
httpTransportConfig: forwarder.DefaultHTTPTransportConfig(),
httpProxyConfig: forwarder.DefaultHTTPProxyConfig(),
mitmConfig: forwarder.DefaultMITMConfig(),
Expand Down
24 changes: 24 additions & 0 deletions dns.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright 2022-2024 Sauce Labs Inc., all rights reserved.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

package forwarder

import (
"net/netip"
"time"
)

type DNSConfig struct {
Servers []netip.AddrPort
Timeout time.Duration
RoundRobin bool
}

func DefaultDNSConfig() *DNSConfig {
return &DNSConfig{
Timeout: 5 * time.Second,
}
}
17 changes: 17 additions & 0 deletions dns_dnshack.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright 2022-2024 Sauce Labs Inc., all rights reserved.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

//go:build dnshack

package forwarder

import (
"github.com/saucelabs/forwarder/utils/dnshack"
)

func (c *DNSConfig) Apply() error {
return dnshack.Configure(c.Servers, c.Timeout, c.RoundRobin)
}
13 changes: 13 additions & 0 deletions dns_others.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright 2022-2024 Sauce Labs Inc., all rights reserved.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

//go:build !dnshack

package forwarder

func (c *DNSConfig) Apply() error {
return nil
}
2 changes: 1 addition & 1 deletion packaging/completions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ rm -rf completions
mkdir completions

for sh in bash zsh powershell fish; do
go run -ldflags "-checklinkname=0" ./cmd/forwarder completion "$sh" >"completions/forwarder.$sh"
go run ./cmd/forwarder completion "$sh" >"completions/forwarder.$sh"
done

# Set powershell extension to ps1.
Expand Down
2 changes: 1 addition & 1 deletion packaging/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

set -e

go run -ldflags "-checklinkname=0" ./cmd/forwarder run config-file > "forwarder.yaml"
go run ./cmd/forwarder run config-file > "forwarder.yaml"
2 changes: 2 additions & 0 deletions utils/dnshack/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
test:
go test -tags dnshack -ldflags "-checklinkname=0"
10 changes: 9 additions & 1 deletion utils/osdns/ast_test.go → utils/dnshack/ast_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
package osdns
// Copyright 2022-2024 Sauce Labs Inc., all rights reserved.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

//go:build dnshack

package dnshack

import (
"bytes"
Expand Down
17 changes: 3 additions & 14 deletions utils/osdns/dnsconf.go → utils/dnshack/dnsconf.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
// Use of this source code is governed by a BSD-style
// license that can be found at https://github.com/golang/go/blob/-/LICENSE.

package osdns
//go:build dnshack

package dnshack

import (
_ "net" // for go:linkname
"net/netip"
"time"
_ "unsafe" // for go:linkname
)
Expand All @@ -33,15 +34,3 @@ type dnsConfig struct {
trustAD bool // add AD flag to queries
noReload bool // do not check for config file updates
}

type Config struct {
Servers []netip.AddrPort
Timeout time.Duration
RoundRobin bool
}

func DefaultConfig() *Config {
return &Config{
Timeout: 5 * time.Second,
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
package osdns
// Copyright 2022-2024 Sauce Labs Inc., all rights reserved.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

//go:build dnshack

package dnshack

import (
"go/build"
Expand Down
53 changes: 53 additions & 0 deletions utils/dnshack/dnshack.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found at https://github.com/golang/go/blob/-/LICENSE.

//go:build dnshack

package dnshack

import (
"errors"
"fmt"
"net/netip"
"sync"
"time"
)

var preConfigure sync.Once

// Configure changes the Go standard library DNS resolver to use the specified
// servers with the specified timeout. If roundRobin is true, the resolver will
// rotate the order of the servers on each request.
//
// Since Go 1.23 it requires the -checklinkname=0 linker flag to work.
func Configure(servers []netip.AddrPort, timeout time.Duration, roundRobin bool) error {
preConfigure.Do(func() {
getSystemDNSConfig()
})

resolvConf.acquireSema()
defer resolvConf.releaseSema()

procDNSCfg := resolvConf.dnsConfig.Load()
if procDNSCfg == nil {
return errors.New("failed to get system DNS config")
}
if procDNSCfg.err != nil {
return fmt.Errorf("failed to get system DNS config: %w", procDNSCfg.err)
}

procDNSCfg.servers = make([]string, len(servers))
for i := range servers {
procDNSCfg.servers[i] = servers[i].String()
}
procDNSCfg.timeout = timeout
procDNSCfg.rotate = roundRobin

// Disable config reload from system dns config file (/etc/resolv.conf).
procDNSCfg.noReload = true

resolvConf.dnsConfig.Store(procDNSCfg)

return nil
}
4 changes: 3 additions & 1 deletion utils/osdns/resolvconf.go → utils/dnshack/resolvconf.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
// Use of this source code is governed by a BSD-style
// license that can be found at https://github.com/golang/go/blob/-/LICENSE.

package osdns
//go:build dnshack

package dnshack

import (
_ "net" // for go:linkname
Expand Down
Loading