Skip to content

Commit

Permalink
all: imp code
Browse files Browse the repository at this point in the history
  • Loading branch information
schzhn committed Dec 20, 2023
1 parent 6aef013 commit 96df7d7
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 19 deletions.
10 changes: 7 additions & 3 deletions proxy/upstreams.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
"golang.org/x/exp/slices"
)

// errWrongUpstreamSpecs is returned by [ParseUpstreamsConfig] when upstreams
// configuration is invalid.
const errWrongUpstreamSpecs errors.Error = "wrong upstream specification"

// UpstreamConfig is a wrapper for a list of default upstreams, a map of
Expand All @@ -37,7 +39,8 @@ type UpstreamConfig struct {
var _ io.Closer = (*UpstreamConfig)(nil)

// ParseUpstreamsConfig returns UpstreamConfig and error if upstreams
// configuration is invalid.
// configuration is invalid. It also skips empty lines and comments (lines
// begining with `#`).
//
// # Simple upstreams
//
Expand Down Expand Up @@ -158,9 +161,9 @@ type configParser struct {
}

// parse returns UpstreamConfig and error if upstreams configuration is invalid.
func (p *configParser) parse(conf []string) (c *UpstreamConfig, err error) {
func (p *configParser) parse(lines []string) (c *UpstreamConfig, err error) {
var errs []error
for i, l := range conf {
for i, l := range lines {
if err = p.parseLine(i, l); err != nil {
errs = append(errs, &ParseError{Idx: i, err: err})
}
Expand Down Expand Up @@ -261,6 +264,7 @@ func (p *configParser) specifyUpstream(domains []string, u string, idx int) (err
if len(domains) == 0 {
p.upstreams = append(p.upstreams, dnsUpstream)

// TODO(s.chzhen): Logs without index.
log.Debug("dnsproxy: upstream at index %d: %s", idx, addr)
} else {
p.includeToReserved(dnsUpstream, domains)
Expand Down
24 changes: 14 additions & 10 deletions upstream/upstream.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"net"
"net/netip"
"net/url"
"strconv"
"strings"
"sync/atomic"
"time"
Expand Down Expand Up @@ -150,6 +149,7 @@ const (
// AddressToUpstream converts addr to an Upstream using the specified options.
// addr can be either a URL, or a plain address, either a domain name or an IP.
//
// - 1.2.3.4 or 1.2.3.4:4321 for plain DNS using IP address;
// - udp://5.3.5.3:53 or 5.3.5.3:53 for plain DNS using IP address;
// - udp://name.server:53 or name.server:53 for plain DNS using domain name;
// - tcp://5.3.5.3:53 for plain DNS-over-TCP using IP address;
Expand All @@ -175,22 +175,26 @@ func AddressToUpstream(addr string, opts *Options) (u Upstream, err error) {
opts = &Options{}
}

_, err = netip.ParseAddr(addr)
if err == nil {
return urlToUpstream(&url.URL{Scheme: "udp", Host: addr}, opts)
}

_, err = netip.ParseAddrPort(addr)
if err == nil {
return urlToUpstream(&url.URL{Scheme: "udp", Host: addr}, opts)
}

var uu *url.URL
if strings.Contains(addr, "://") {
// Parse as URL.
uu, err = url.Parse(addr)
if err != nil {
return nil, fmt.Errorf("failed to parse %s: %w", addr, err)
}
} else {
// Probably, plain UDP upstream defined by address or address:port.
_, port, splitErr := net.SplitHostPort(addr)
if splitErr == nil {
// Validate port.
_, err = strconv.ParseUint(port, 10, 16)
if err != nil {
return nil, fmt.Errorf("invalid address %s: %w", addr, err)
}
err = netutil.ValidateHostname(addr)
if err != nil {
return nil, fmt.Errorf("invalid address %s: %w", addr, err)
}

uu = &url.URL{
Expand Down
14 changes: 8 additions & 6 deletions upstream/upstream_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,15 +271,17 @@ func TestAddressToUpstream_bads(t *testing.T) {
wantErrMsg: "unsupported url scheme: asdf",
}, {
addr: "12345.1.1.1:1234567",
wantErrMsg: `invalid address 12345.1.1.1:1234567: ` +
`strconv.ParseUint: parsing "1234567": value out of range`,
wantErrMsg: `invalid address 12345.1.1.1:1234567: bad hostname ` +
`"12345.1.1.1:1234567": bad top-level domain name label "1:1234567": ` +
`bad top-level domain name label rune ':'`,
}, {
addr: ":1234567",
wantErrMsg: `invalid address :1234567: ` +
`strconv.ParseUint: parsing "1234567": value out of range`,
wantErrMsg: `invalid address :1234567: bad hostname ":1234567": bad top-level ` +
`domain name label ":1234567": bad top-level domain name label rune ':'`,
}, {
addr: "host:",
wantErrMsg: `invalid address host:: strconv.ParseUint: parsing "": invalid syntax`,
addr: "host:",
wantErrMsg: `invalid address host:: bad hostname "host:": bad top-level ` +
`domain name label "host:": bad top-level domain name label rune ':'`,
}}

for _, tc := range testCases {
Expand Down

0 comments on commit 96df7d7

Please # to comment.