Upgrade miekg/dns from v1.1.58 to v1.1.61 (#7592)
Diff: [here](https://github.com/miekg/dns/compare/v1.1.58..v1.1.61).
This commit is contained in:
parent
b61c7e1fdd
commit
f2e46486f9
6
go.mod
6
go.mod
|
@ -19,7 +19,7 @@ require (
|
||||||
github.com/letsencrypt/challtestsrv v1.2.1
|
github.com/letsencrypt/challtestsrv v1.2.1
|
||||||
github.com/letsencrypt/pkcs11key/v4 v4.0.0
|
github.com/letsencrypt/pkcs11key/v4 v4.0.0
|
||||||
github.com/letsencrypt/validator/v10 v10.0.0-20230215210743-a0c7dfc17158
|
github.com/letsencrypt/validator/v10 v10.0.0-20230215210743-a0c7dfc17158
|
||||||
github.com/miekg/dns v1.1.58
|
github.com/miekg/dns v1.1.61
|
||||||
github.com/miekg/pkcs11 v1.1.1
|
github.com/miekg/pkcs11 v1.1.1
|
||||||
github.com/nxadm/tail v1.4.11
|
github.com/nxadm/tail v1.4.11
|
||||||
github.com/prometheus/client_golang v1.15.1
|
github.com/prometheus/client_golang v1.15.1
|
||||||
|
@ -81,9 +81,9 @@ require (
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect
|
||||||
go.opentelemetry.io/otel/metric v1.27.0 // indirect
|
go.opentelemetry.io/otel/metric v1.27.0 // indirect
|
||||||
go.opentelemetry.io/proto/otlp v1.2.0 // indirect
|
go.opentelemetry.io/proto/otlp v1.2.0 // indirect
|
||||||
golang.org/x/mod v0.17.0 // indirect
|
golang.org/x/mod v0.18.0 // indirect
|
||||||
golang.org/x/sys v0.21.0 // indirect
|
golang.org/x/sys v0.21.0 // indirect
|
||||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
|
golang.org/x/tools v0.22.0 // indirect
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5 // indirect
|
google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5 // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240520151616-dc85e6b867a5 // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240520151616-dc85e6b867a5 // indirect
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
|
||||||
|
|
12
go.sum
12
go.sum
|
@ -173,8 +173,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
|
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||||
github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4=
|
github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4=
|
||||||
github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4=
|
github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs=
|
||||||
github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY=
|
github.com/miekg/dns v1.1.61/go.mod h1:mnAarhS3nWaW+NVP2wTkYVIZyHNJ098SJZUki3eykwQ=
|
||||||
github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
||||||
github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU=
|
github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU=
|
||||||
github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
||||||
|
@ -308,8 +308,8 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl
|
||||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
|
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
|
||||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
@ -404,8 +404,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
|
||||||
golang.org/x/tools v0.0.0-20200313205530-4303120df7d8/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
golang.org/x/tools v0.0.0-20200313205530-4303120df7d8/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
|
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
|
||||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
|
|
@ -83,6 +83,8 @@ A not-so-up-to-date-list-that-may-be-actually-current:
|
||||||
* https://github.com/egbakou/domainverifier
|
* https://github.com/egbakou/domainverifier
|
||||||
* https://github.com/semihalev/sdns
|
* https://github.com/semihalev/sdns
|
||||||
* https://github.com/wintbiit/NineDNS
|
* https://github.com/wintbiit/NineDNS
|
||||||
|
* https://linuxcontainers.org/incus/
|
||||||
|
* https://ifconfig.es
|
||||||
|
|
||||||
|
|
||||||
Send pull request if you want to be listed here.
|
Send pull request if you want to be listed here.
|
||||||
|
@ -186,6 +188,9 @@ Example programs can be found in the `github.com/miekg/exdns` repository.
|
||||||
* 8777 - DNS Reverse IP Automatic Multicast Tunneling (AMT) Discovery
|
* 8777 - DNS Reverse IP Automatic Multicast Tunneling (AMT) Discovery
|
||||||
* 8914 - Extended DNS Errors
|
* 8914 - Extended DNS Errors
|
||||||
* 8976 - Message Digest for DNS Zones (ZONEMD RR)
|
* 8976 - Message Digest for DNS Zones (ZONEMD RR)
|
||||||
|
* 9460 - Service Binding and Parameter Specification via the DNS
|
||||||
|
* 9461 - Service Binding Mapping for DNS Servers
|
||||||
|
* 9462 - Discovery of Designated Resolvers
|
||||||
|
|
||||||
## Loosely Based Upon
|
## Loosely Based Upon
|
||||||
|
|
||||||
|
|
|
@ -198,10 +198,12 @@ func IsDomainName(s string) (labels int, ok bool) {
|
||||||
off int
|
off int
|
||||||
begin int
|
begin int
|
||||||
wasDot bool
|
wasDot bool
|
||||||
|
escape bool
|
||||||
)
|
)
|
||||||
for i := 0; i < len(s); i++ {
|
for i := 0; i < len(s); i++ {
|
||||||
switch s[i] {
|
switch s[i] {
|
||||||
case '\\':
|
case '\\':
|
||||||
|
escape = !escape
|
||||||
if off+1 > lenmsg {
|
if off+1 > lenmsg {
|
||||||
return labels, false
|
return labels, false
|
||||||
}
|
}
|
||||||
|
@ -217,6 +219,7 @@ func IsDomainName(s string) (labels int, ok bool) {
|
||||||
|
|
||||||
wasDot = false
|
wasDot = false
|
||||||
case '.':
|
case '.':
|
||||||
|
escape = false
|
||||||
if i == 0 && len(s) > 1 {
|
if i == 0 && len(s) > 1 {
|
||||||
// leading dots are not legal except for the root zone
|
// leading dots are not legal except for the root zone
|
||||||
return labels, false
|
return labels, false
|
||||||
|
@ -243,10 +246,13 @@ func IsDomainName(s string) (labels int, ok bool) {
|
||||||
labels++
|
labels++
|
||||||
begin = i + 1
|
begin = i + 1
|
||||||
default:
|
default:
|
||||||
|
escape = false
|
||||||
wasDot = false
|
wasDot = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if escape {
|
||||||
|
return labels, false
|
||||||
|
}
|
||||||
return labels, true
|
return labels, true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -714,7 +714,7 @@ func (h *MsgHdr) String() string {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pack packs a Msg: it is converted to to wire format.
|
// Pack packs a Msg: it is converted to wire format.
|
||||||
// If the dns.Compress is true the message will be in compressed wire format.
|
// If the dns.Compress is true the message will be in compressed wire format.
|
||||||
func (dns *Msg) Pack() (msg []byte, err error) {
|
func (dns *Msg) Pack() (msg []byte, err error) {
|
||||||
return dns.PackBuffer(nil)
|
return dns.PackBuffer(nil)
|
||||||
|
|
|
@ -101,12 +101,13 @@ type ttlState struct {
|
||||||
isByDirective bool // isByDirective indicates whether ttl was set by a $TTL directive
|
isByDirective bool // isByDirective indicates whether ttl was set by a $TTL directive
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRR reads the RR contained in the string s. Only the first RR is returned.
|
// NewRR reads a string s and returns the first RR.
|
||||||
// If s contains no records, NewRR will return nil with no error.
|
// If s contains no records, NewRR will return nil with no error.
|
||||||
//
|
//
|
||||||
// The class defaults to IN and TTL defaults to 3600. The full zone file syntax
|
// The class defaults to IN, TTL defaults to 3600, and
|
||||||
// like $TTL, $ORIGIN, etc. is supported. All fields of the returned RR are
|
// origin for resolving relative domain names defaults to the DNS root (.).
|
||||||
// set, except RR.Header().Rdlength which is set to 0.
|
// Full zone file syntax is supported, including directives like $TTL and $ORIGIN.
|
||||||
|
// All fields of the returned RR are set from the read data, except RR.Header().Rdlength which is set to 0.
|
||||||
func NewRR(s string) (RR, error) {
|
func NewRR(s string) (RR, error) {
|
||||||
if len(s) > 0 && s[len(s)-1] != '\n' { // We need a closing newline
|
if len(s) > 0 && s[len(s)-1] != '\n' { // We need a closing newline
|
||||||
return ReadRR(strings.NewReader(s+"\n"), "")
|
return ReadRR(strings.NewReader(s+"\n"), "")
|
||||||
|
@ -1282,7 +1283,7 @@ func stringToCm(token string) (e, m uint8, ok bool) {
|
||||||
cmeters *= 10
|
cmeters *= 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// This slighly ugly condition will allow omitting the 'meter' part, like .01 (meaning 0.01m = 1cm).
|
// This slightly ugly condition will allow omitting the 'meter' part, like .01 (meaning 0.01m = 1cm).
|
||||||
if !hasCM || mStr != "" {
|
if !hasCM || mStr != "" {
|
||||||
meters, err = strconv.Atoi(mStr)
|
meters, err = strconv.Atoi(mStr)
|
||||||
// RFC1876 states the max value is 90000000.00. The latter two conditions enforce it.
|
// RFC1876 states the max value is 90000000.00. The latter two conditions enforce it.
|
||||||
|
|
|
@ -51,25 +51,24 @@ func endingToTxtSlice(c *zlexer, errstr string) ([]string, *ParseError) {
|
||||||
switch l.value {
|
switch l.value {
|
||||||
case zString:
|
case zString:
|
||||||
empty = false
|
empty = false
|
||||||
if len(l.token) > 255 {
|
// split up tokens that are larger than 255 into 255-chunks
|
||||||
// split up tokens that are larger than 255 into 255-chunks
|
sx := []string{}
|
||||||
sx := []string{}
|
p := 0
|
||||||
p, i := 0, 255
|
for {
|
||||||
for {
|
i, ok := escapedStringOffset(l.token[p:], 255)
|
||||||
if i <= len(l.token) {
|
if !ok {
|
||||||
sx = append(sx, l.token[p:i])
|
return nil, &ParseError{err: errstr, lex: l}
|
||||||
} else {
|
|
||||||
sx = append(sx, l.token[p:])
|
|
||||||
break
|
|
||||||
|
|
||||||
}
|
|
||||||
p, i = p+255, i+255
|
|
||||||
}
|
}
|
||||||
s = append(s, sx...)
|
if i != -1 && p+i != len(l.token) {
|
||||||
break
|
sx = append(sx, l.token[p:p+i])
|
||||||
}
|
} else {
|
||||||
|
sx = append(sx, l.token[p:])
|
||||||
|
break
|
||||||
|
|
||||||
s = append(s, l.token)
|
}
|
||||||
|
p += i
|
||||||
|
}
|
||||||
|
s = append(s, sx...)
|
||||||
case zBlank:
|
case zBlank:
|
||||||
if quote {
|
if quote {
|
||||||
// zBlank can only be seen in between txt parts.
|
// zBlank can only be seen in between txt parts.
|
||||||
|
@ -1920,3 +1919,39 @@ func (rr *APL) parse(c *zlexer, o string) *ParseError {
|
||||||
rr.Prefixes = prefixes
|
rr.Prefixes = prefixes
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// escapedStringOffset finds the offset within a string (which may contain escape
|
||||||
|
// sequences) that corresponds to a certain byte offset. If the input offset is
|
||||||
|
// out of bounds, -1 is returned (which is *not* considered an error).
|
||||||
|
func escapedStringOffset(s string, desiredByteOffset int) (int, bool) {
|
||||||
|
if desiredByteOffset == 0 {
|
||||||
|
return 0, true
|
||||||
|
}
|
||||||
|
|
||||||
|
currentByteOffset, i := 0, 0
|
||||||
|
|
||||||
|
for i < len(s) {
|
||||||
|
currentByteOffset += 1
|
||||||
|
|
||||||
|
// Skip escape sequences
|
||||||
|
if s[i] != '\\' {
|
||||||
|
// Single plain byte, not an escape sequence.
|
||||||
|
i++
|
||||||
|
} else if isDDD(s[i+1:]) {
|
||||||
|
// Skip backslash and DDD.
|
||||||
|
i += 4
|
||||||
|
} else if len(s[i+1:]) < 1 {
|
||||||
|
// No character following the backslash; that's an error.
|
||||||
|
return 0, false
|
||||||
|
} else {
|
||||||
|
// Skip backslash and following byte.
|
||||||
|
i += 2
|
||||||
|
}
|
||||||
|
|
||||||
|
if currentByteOffset >= desiredByteOffset {
|
||||||
|
return i, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1, true
|
||||||
|
}
|
||||||
|
|
|
@ -188,6 +188,14 @@ type DecorateReader func(Reader) Reader
|
||||||
// Implementations should never return a nil Writer.
|
// Implementations should never return a nil Writer.
|
||||||
type DecorateWriter func(Writer) Writer
|
type DecorateWriter func(Writer) Writer
|
||||||
|
|
||||||
|
// MsgInvalidFunc is a listener hook for observing incoming messages that were discarded
|
||||||
|
// because they could not be parsed.
|
||||||
|
// Every message that is read by a Reader will eventually be provided to the Handler,
|
||||||
|
// rejected (or ignored) by the MsgAcceptFunc, or passed to this function.
|
||||||
|
type MsgInvalidFunc func(m []byte, err error)
|
||||||
|
|
||||||
|
func DefaultMsgInvalidFunc(m []byte, err error) {}
|
||||||
|
|
||||||
// A Server defines parameters for running an DNS server.
|
// A Server defines parameters for running an DNS server.
|
||||||
type Server struct {
|
type Server struct {
|
||||||
// Address to listen on, ":dns" if empty.
|
// Address to listen on, ":dns" if empty.
|
||||||
|
@ -233,6 +241,8 @@ type Server struct {
|
||||||
// AcceptMsgFunc will check the incoming message and will reject it early in the process.
|
// AcceptMsgFunc will check the incoming message and will reject it early in the process.
|
||||||
// By default DefaultMsgAcceptFunc will be used.
|
// By default DefaultMsgAcceptFunc will be used.
|
||||||
MsgAcceptFunc MsgAcceptFunc
|
MsgAcceptFunc MsgAcceptFunc
|
||||||
|
// MsgInvalidFunc is optional, will be called if a message is received but cannot be parsed.
|
||||||
|
MsgInvalidFunc MsgInvalidFunc
|
||||||
|
|
||||||
// Shutdown handling
|
// Shutdown handling
|
||||||
lock sync.RWMutex
|
lock sync.RWMutex
|
||||||
|
@ -277,6 +287,9 @@ func (srv *Server) init() {
|
||||||
if srv.MsgAcceptFunc == nil {
|
if srv.MsgAcceptFunc == nil {
|
||||||
srv.MsgAcceptFunc = DefaultMsgAcceptFunc
|
srv.MsgAcceptFunc = DefaultMsgAcceptFunc
|
||||||
}
|
}
|
||||||
|
if srv.MsgInvalidFunc == nil {
|
||||||
|
srv.MsgInvalidFunc = DefaultMsgInvalidFunc
|
||||||
|
}
|
||||||
if srv.Handler == nil {
|
if srv.Handler == nil {
|
||||||
srv.Handler = DefaultServeMux
|
srv.Handler = DefaultServeMux
|
||||||
}
|
}
|
||||||
|
@ -531,6 +544,7 @@ func (srv *Server) serveUDP(l net.PacketConn) error {
|
||||||
if cap(m) == srv.UDPSize {
|
if cap(m) == srv.UDPSize {
|
||||||
srv.udpPool.Put(m[:srv.UDPSize])
|
srv.udpPool.Put(m[:srv.UDPSize])
|
||||||
}
|
}
|
||||||
|
srv.MsgInvalidFunc(m, ErrShortRead)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
|
@ -611,6 +625,7 @@ func (srv *Server) serveUDPPacket(wg *sync.WaitGroup, m []byte, u net.PacketConn
|
||||||
func (srv *Server) serveDNS(m []byte, w *response) {
|
func (srv *Server) serveDNS(m []byte, w *response) {
|
||||||
dh, off, err := unpackMsgHdr(m, 0)
|
dh, off, err := unpackMsgHdr(m, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
srv.MsgInvalidFunc(m, err)
|
||||||
// Let client hang, they are sending crap; any reply can be used to amplify.
|
// Let client hang, they are sending crap; any reply can be used to amplify.
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -620,10 +635,12 @@ func (srv *Server) serveDNS(m []byte, w *response) {
|
||||||
|
|
||||||
switch action := srv.MsgAcceptFunc(dh); action {
|
switch action := srv.MsgAcceptFunc(dh); action {
|
||||||
case MsgAccept:
|
case MsgAccept:
|
||||||
if req.unpack(dh, m, off) == nil {
|
err := req.unpack(dh, m, off)
|
||||||
|
if err == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
srv.MsgInvalidFunc(m, err)
|
||||||
fallthrough
|
fallthrough
|
||||||
case MsgReject, MsgRejectNotImplemented:
|
case MsgReject, MsgRejectNotImplemented:
|
||||||
opcode := req.Opcode
|
opcode := req.Opcode
|
||||||
|
|
|
@ -14,7 +14,7 @@ import (
|
||||||
// SVCBKey is the type of the keys used in the SVCB RR.
|
// SVCBKey is the type of the keys used in the SVCB RR.
|
||||||
type SVCBKey uint16
|
type SVCBKey uint16
|
||||||
|
|
||||||
// Keys defined in draft-ietf-dnsop-svcb-https-08 Section 14.3.2.
|
// Keys defined in rfc9460
|
||||||
const (
|
const (
|
||||||
SVCB_MANDATORY SVCBKey = iota
|
SVCB_MANDATORY SVCBKey = iota
|
||||||
SVCB_ALPN
|
SVCB_ALPN
|
||||||
|
@ -23,7 +23,8 @@ const (
|
||||||
SVCB_IPV4HINT
|
SVCB_IPV4HINT
|
||||||
SVCB_ECHCONFIG
|
SVCB_ECHCONFIG
|
||||||
SVCB_IPV6HINT
|
SVCB_IPV6HINT
|
||||||
SVCB_DOHPATH // draft-ietf-add-svcb-dns-02 Section 9
|
SVCB_DOHPATH // rfc9461 Section 5
|
||||||
|
SVCB_OHTTP // rfc9540 Section 8
|
||||||
|
|
||||||
svcb_RESERVED SVCBKey = 65535
|
svcb_RESERVED SVCBKey = 65535
|
||||||
)
|
)
|
||||||
|
@ -37,6 +38,7 @@ var svcbKeyToStringMap = map[SVCBKey]string{
|
||||||
SVCB_ECHCONFIG: "ech",
|
SVCB_ECHCONFIG: "ech",
|
||||||
SVCB_IPV6HINT: "ipv6hint",
|
SVCB_IPV6HINT: "ipv6hint",
|
||||||
SVCB_DOHPATH: "dohpath",
|
SVCB_DOHPATH: "dohpath",
|
||||||
|
SVCB_OHTTP: "ohttp",
|
||||||
}
|
}
|
||||||
|
|
||||||
var svcbStringToKeyMap = reverseSVCBKeyMap(svcbKeyToStringMap)
|
var svcbStringToKeyMap = reverseSVCBKeyMap(svcbKeyToStringMap)
|
||||||
|
@ -201,6 +203,8 @@ func makeSVCBKeyValue(key SVCBKey) SVCBKeyValue {
|
||||||
return new(SVCBIPv6Hint)
|
return new(SVCBIPv6Hint)
|
||||||
case SVCB_DOHPATH:
|
case SVCB_DOHPATH:
|
||||||
return new(SVCBDoHPath)
|
return new(SVCBDoHPath)
|
||||||
|
case SVCB_OHTTP:
|
||||||
|
return new(SVCBOhttp)
|
||||||
case svcb_RESERVED:
|
case svcb_RESERVED:
|
||||||
return nil
|
return nil
|
||||||
default:
|
default:
|
||||||
|
@ -771,8 +775,8 @@ func (s *SVCBIPv6Hint) copy() SVCBKeyValue {
|
||||||
// SVCBDoHPath pair is used to indicate the URI template that the
|
// SVCBDoHPath pair is used to indicate the URI template that the
|
||||||
// clients may use to construct a DNS over HTTPS URI.
|
// clients may use to construct a DNS over HTTPS URI.
|
||||||
//
|
//
|
||||||
// See RFC xxxx (https://datatracker.ietf.org/doc/html/draft-ietf-add-svcb-dns-02)
|
// See RFC 9461 (https://datatracker.ietf.org/doc/html/rfc9461)
|
||||||
// and RFC yyyy (https://datatracker.ietf.org/doc/html/draft-ietf-add-ddr-06).
|
// and RFC 9462 (https://datatracker.ietf.org/doc/html/rfc9462).
|
||||||
//
|
//
|
||||||
// A basic example of using the dohpath option together with the alpn
|
// A basic example of using the dohpath option together with the alpn
|
||||||
// option to indicate support for DNS over HTTPS on a certain path:
|
// option to indicate support for DNS over HTTPS on a certain path:
|
||||||
|
@ -816,6 +820,44 @@ func (s *SVCBDoHPath) copy() SVCBKeyValue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The "ohttp" SvcParamKey is used to indicate that a service described in a SVCB RR
|
||||||
|
// can be accessed as a target using an associated gateway.
|
||||||
|
// Both the presentation and wire-format values for the "ohttp" parameter MUST be empty.
|
||||||
|
//
|
||||||
|
// See RFC 9460 (https://datatracker.ietf.org/doc/html/rfc9460/)
|
||||||
|
// and RFC 9230 (https://datatracker.ietf.org/doc/html/rfc9230/)
|
||||||
|
//
|
||||||
|
// A basic example of using the dohpath option together with the alpn
|
||||||
|
// option to indicate support for DNS over HTTPS on a certain path:
|
||||||
|
//
|
||||||
|
// s := new(dns.SVCB)
|
||||||
|
// s.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET}
|
||||||
|
// e := new(dns.SVCBAlpn)
|
||||||
|
// e.Alpn = []string{"h2", "h3"}
|
||||||
|
// p := new(dns.SVCBOhttp)
|
||||||
|
// s.Value = append(s.Value, e, p)
|
||||||
|
type SVCBOhttp struct{}
|
||||||
|
|
||||||
|
func (*SVCBOhttp) Key() SVCBKey { return SVCB_OHTTP }
|
||||||
|
func (*SVCBOhttp) copy() SVCBKeyValue { return &SVCBOhttp{} }
|
||||||
|
func (*SVCBOhttp) pack() ([]byte, error) { return []byte{}, nil }
|
||||||
|
func (*SVCBOhttp) String() string { return "" }
|
||||||
|
func (*SVCBOhttp) len() int { return 0 }
|
||||||
|
|
||||||
|
func (*SVCBOhttp) unpack(b []byte) error {
|
||||||
|
if len(b) != 0 {
|
||||||
|
return errors.New("dns: svcbotthp: svcbotthp must have no value")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*SVCBOhttp) parse(b string) error {
|
||||||
|
if b != "" {
|
||||||
|
return errors.New("dns: svcbotthp: svcbotthp must have no value")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// SVCBLocal pair is intended for experimental/private use. The key is recommended
|
// SVCBLocal pair is intended for experimental/private use. The key is recommended
|
||||||
// to be in the range [SVCB_PRIVATE_LOWER, SVCB_PRIVATE_UPPER].
|
// to be in the range [SVCB_PRIVATE_LOWER, SVCB_PRIVATE_UPPER].
|
||||||
// Basic use pattern for creating a keyNNNNN option:
|
// Basic use pattern for creating a keyNNNNN option:
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package dns
|
package dns
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
@ -20,6 +21,7 @@ type Transfer struct {
|
||||||
TsigProvider TsigProvider // An implementation of the TsigProvider interface. If defined it replaces TsigSecret and is used for all TSIG operations.
|
TsigProvider TsigProvider // An implementation of the TsigProvider interface. If defined it replaces TsigSecret and is used for all TSIG operations.
|
||||||
TsigSecret map[string]string // Secret(s) for Tsig map[<zonename>]<base64 secret>, zonename must be in canonical form (lowercase, fqdn, see RFC 4034 Section 6.2)
|
TsigSecret map[string]string // Secret(s) for Tsig map[<zonename>]<base64 secret>, zonename must be in canonical form (lowercase, fqdn, see RFC 4034 Section 6.2)
|
||||||
tsigTimersOnly bool
|
tsigTimersOnly bool
|
||||||
|
TLS *tls.Config // TLS config. If Xfr over TLS will be attempted
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Transfer) tsigProvider() TsigProvider {
|
func (t *Transfer) tsigProvider() TsigProvider {
|
||||||
|
@ -57,7 +59,11 @@ func (t *Transfer) In(q *Msg, a string) (env chan *Envelope, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if t.Conn == nil {
|
if t.Conn == nil {
|
||||||
t.Conn, err = DialTimeout("tcp", a, timeout)
|
if t.TLS != nil {
|
||||||
|
t.Conn, err = DialTimeoutWithTLS("tcp-tls", a, t.TLS, timeout)
|
||||||
|
} else {
|
||||||
|
t.Conn, err = DialTimeout("tcp", a, timeout)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -182,7 +188,7 @@ func (t *Transfer) inIxfr(q *Msg, c chan *Envelope) {
|
||||||
if v, ok := rr.(*SOA); ok {
|
if v, ok := rr.(*SOA); ok {
|
||||||
if v.Serial == serial {
|
if v.Serial == serial {
|
||||||
n++
|
n++
|
||||||
// quit if it's a full axfr or the the servers' SOA is repeated the third time
|
// quit if it's a full axfr or the servers' SOA is repeated the third time
|
||||||
if axfr && n == 2 || n == 3 {
|
if axfr && n == 2 || n == 3 {
|
||||||
c <- &Envelope{in.Answer, nil}
|
c <- &Envelope{in.Answer, nil}
|
||||||
return
|
return
|
||||||
|
@ -203,6 +209,7 @@ func (t *Transfer) inIxfr(q *Msg, c chan *Envelope) {
|
||||||
// ch := make(chan *dns.Envelope)
|
// ch := make(chan *dns.Envelope)
|
||||||
// tr := new(dns.Transfer)
|
// tr := new(dns.Transfer)
|
||||||
// var wg sync.WaitGroup
|
// var wg sync.WaitGroup
|
||||||
|
// wg.Add(1)
|
||||||
// go func() {
|
// go func() {
|
||||||
// tr.Out(w, r, ch)
|
// tr.Out(w, r, ch)
|
||||||
// wg.Done()
|
// wg.Done()
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"golang.org/x/tools/internal/gocommand"
|
"golang.org/x/tools/internal/gocommand"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// TODO(adonovan): move back into go/packages.
|
||||||
func GetSizesForArgsGolist(ctx context.Context, inv gocommand.Invocation, gocmdRunner *gocommand.Runner) (string, string, error) {
|
func GetSizesForArgsGolist(ctx context.Context, inv gocommand.Invocation, gocmdRunner *gocommand.Runner) (string, string, error) {
|
||||||
inv.Verb = "list"
|
inv.Verb = "list"
|
||||||
inv.Args = []string{"-f", "{{context.GOARCH}} {{context.Compiler}}", "--", "unsafe"}
|
inv.Args = []string{"-f", "{{context.GOARCH}} {{context.Compiler}}", "--", "unsafe"}
|
||||||
|
|
|
@ -198,14 +198,6 @@ Instead, ssadump no longer requests the runtime package,
|
||||||
but seeks it among the dependencies of the user-specified packages,
|
but seeks it among the dependencies of the user-specified packages,
|
||||||
and emits an error if it is not found.
|
and emits an error if it is not found.
|
||||||
|
|
||||||
Overlays: The Overlay field in the Config allows providing alternate contents
|
|
||||||
for Go source files, by providing a mapping from file path to contents.
|
|
||||||
go/packages will pull in new imports added in overlay files when go/packages
|
|
||||||
is run in LoadImports mode or greater.
|
|
||||||
Overlay support for the go list driver isn't complete yet: if the file doesn't
|
|
||||||
exist on disk, it will only be recognized in an overlay if it is a non-test file
|
|
||||||
and the package would be reported even without the overlay.
|
|
||||||
|
|
||||||
Questions & Tasks
|
Questions & Tasks
|
||||||
|
|
||||||
- Add GOARCH/GOOS?
|
- Add GOARCH/GOOS?
|
||||||
|
|
|
@ -34,8 +34,8 @@ type DriverRequest struct {
|
||||||
// Tests specifies whether the patterns should also return test packages.
|
// Tests specifies whether the patterns should also return test packages.
|
||||||
Tests bool `json:"tests"`
|
Tests bool `json:"tests"`
|
||||||
|
|
||||||
// Overlay maps file paths (relative to the driver's working directory) to the byte contents
|
// Overlay maps file paths (relative to the driver's working directory)
|
||||||
// of overlay files.
|
// to the contents of overlay files (see Config.Overlay).
|
||||||
Overlay map[string][]byte `json:"overlay"`
|
Overlay map[string][]byte `json:"overlay"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,7 +119,19 @@ func findExternalDriver(cfg *Config) driver {
|
||||||
stderr := new(bytes.Buffer)
|
stderr := new(bytes.Buffer)
|
||||||
cmd := exec.CommandContext(cfg.Context, tool, words...)
|
cmd := exec.CommandContext(cfg.Context, tool, words...)
|
||||||
cmd.Dir = cfg.Dir
|
cmd.Dir = cfg.Dir
|
||||||
cmd.Env = cfg.Env
|
// The cwd gets resolved to the real path. On Darwin, where
|
||||||
|
// /tmp is a symlink, this breaks anything that expects the
|
||||||
|
// working directory to keep the original path, including the
|
||||||
|
// go command when dealing with modules.
|
||||||
|
//
|
||||||
|
// os.Getwd stdlib has a special feature where if the
|
||||||
|
// cwd and the PWD are the same node then it trusts
|
||||||
|
// the PWD, so by setting it in the env for the child
|
||||||
|
// process we fix up all the paths returned by the go
|
||||||
|
// command.
|
||||||
|
//
|
||||||
|
// (See similar trick in Invocation.run in ../../internal/gocommand/invoke.go)
|
||||||
|
cmd.Env = append(slicesClip(cfg.Env), "PWD="+cfg.Dir)
|
||||||
cmd.Stdin = bytes.NewReader(req)
|
cmd.Stdin = bytes.NewReader(req)
|
||||||
cmd.Stdout = buf
|
cmd.Stdout = buf
|
||||||
cmd.Stderr = stderr
|
cmd.Stderr = stderr
|
||||||
|
@ -138,3 +150,7 @@ func findExternalDriver(cfg *Config) driver {
|
||||||
return &response, nil
|
return &response, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// slicesClip removes unused capacity from the slice, returning s[:len(s):len(s)].
|
||||||
|
// TODO(adonovan): use go1.21 slices.Clip.
|
||||||
|
func slicesClip[S ~[]E, E any](s S) S { return s[:len(s):len(s)] }
|
||||||
|
|
|
@ -841,6 +841,7 @@ func (state *golistState) cfgInvocation() gocommand.Invocation {
|
||||||
Env: cfg.Env,
|
Env: cfg.Env,
|
||||||
Logf: cfg.Logf,
|
Logf: cfg.Logf,
|
||||||
WorkingDir: cfg.Dir,
|
WorkingDir: cfg.Dir,
|
||||||
|
Overlay: cfg.goListOverlayFile,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -849,26 +850,6 @@ func (state *golistState) invokeGo(verb string, args ...string) (*bytes.Buffer,
|
||||||
cfg := state.cfg
|
cfg := state.cfg
|
||||||
|
|
||||||
inv := state.cfgInvocation()
|
inv := state.cfgInvocation()
|
||||||
|
|
||||||
// For Go versions 1.16 and above, `go list` accepts overlays directly via
|
|
||||||
// the -overlay flag. Set it, if it's available.
|
|
||||||
//
|
|
||||||
// The check for "list" is not necessarily required, but we should avoid
|
|
||||||
// getting the go version if possible.
|
|
||||||
if verb == "list" {
|
|
||||||
goVersion, err := state.getGoVersion()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if goVersion >= 16 {
|
|
||||||
filename, cleanup, err := state.writeOverlays()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer cleanup()
|
|
||||||
inv.Overlay = filename
|
|
||||||
}
|
|
||||||
}
|
|
||||||
inv.Verb = verb
|
inv.Verb = verb
|
||||||
inv.Args = args
|
inv.Args = args
|
||||||
gocmdRunner := cfg.gocmdRunner
|
gocmdRunner := cfg.gocmdRunner
|
||||||
|
@ -1015,67 +996,6 @@ func (state *golistState) invokeGo(verb string, args ...string) (*bytes.Buffer,
|
||||||
return stdout, nil
|
return stdout, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// OverlayJSON is the format overlay files are expected to be in.
|
|
||||||
// The Replace map maps from overlaid paths to replacement paths:
|
|
||||||
// the Go command will forward all reads trying to open
|
|
||||||
// each overlaid path to its replacement path, or consider the overlaid
|
|
||||||
// path not to exist if the replacement path is empty.
|
|
||||||
//
|
|
||||||
// From golang/go#39958.
|
|
||||||
type OverlayJSON struct {
|
|
||||||
Replace map[string]string `json:"replace,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// writeOverlays writes out files for go list's -overlay flag, as described
|
|
||||||
// above.
|
|
||||||
func (state *golistState) writeOverlays() (filename string, cleanup func(), err error) {
|
|
||||||
// Do nothing if there are no overlays in the config.
|
|
||||||
if len(state.cfg.Overlay) == 0 {
|
|
||||||
return "", func() {}, nil
|
|
||||||
}
|
|
||||||
dir, err := os.MkdirTemp("", "gopackages-*")
|
|
||||||
if err != nil {
|
|
||||||
return "", nil, err
|
|
||||||
}
|
|
||||||
// The caller must clean up this directory, unless this function returns an
|
|
||||||
// error.
|
|
||||||
cleanup = func() {
|
|
||||||
os.RemoveAll(dir)
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
if err != nil {
|
|
||||||
cleanup()
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
overlays := map[string]string{}
|
|
||||||
for k, v := range state.cfg.Overlay {
|
|
||||||
// Create a unique filename for the overlaid files, to avoid
|
|
||||||
// creating nested directories.
|
|
||||||
noSeparator := strings.Join(strings.Split(filepath.ToSlash(k), "/"), "")
|
|
||||||
f, err := os.CreateTemp(dir, fmt.Sprintf("*-%s", noSeparator))
|
|
||||||
if err != nil {
|
|
||||||
return "", func() {}, err
|
|
||||||
}
|
|
||||||
if _, err := f.Write(v); err != nil {
|
|
||||||
return "", func() {}, err
|
|
||||||
}
|
|
||||||
if err := f.Close(); err != nil {
|
|
||||||
return "", func() {}, err
|
|
||||||
}
|
|
||||||
overlays[k] = f.Name()
|
|
||||||
}
|
|
||||||
b, err := json.Marshal(OverlayJSON{Replace: overlays})
|
|
||||||
if err != nil {
|
|
||||||
return "", func() {}, err
|
|
||||||
}
|
|
||||||
// Write out the overlay file that contains the filepath mappings.
|
|
||||||
filename = filepath.Join(dir, "overlay.json")
|
|
||||||
if err := os.WriteFile(filename, b, 0665); err != nil {
|
|
||||||
return "", func() {}, err
|
|
||||||
}
|
|
||||||
return filename, cleanup, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func containsGoFile(s []string) bool {
|
func containsGoFile(s []string) bool {
|
||||||
for _, f := range s {
|
for _, f := range s {
|
||||||
if strings.HasSuffix(f, ".go") {
|
if strings.HasSuffix(f, ".go") {
|
||||||
|
|
|
@ -37,10 +37,20 @@ import (
|
||||||
// A LoadMode controls the amount of detail to return when loading.
|
// A LoadMode controls the amount of detail to return when loading.
|
||||||
// The bits below can be combined to specify which fields should be
|
// The bits below can be combined to specify which fields should be
|
||||||
// filled in the result packages.
|
// filled in the result packages.
|
||||||
|
//
|
||||||
// The zero value is a special case, equivalent to combining
|
// The zero value is a special case, equivalent to combining
|
||||||
// the NeedName, NeedFiles, and NeedCompiledGoFiles bits.
|
// the NeedName, NeedFiles, and NeedCompiledGoFiles bits.
|
||||||
|
//
|
||||||
// ID and Errors (if present) will always be filled.
|
// ID and Errors (if present) will always be filled.
|
||||||
// Load may return more information than requested.
|
// [Load] may return more information than requested.
|
||||||
|
//
|
||||||
|
// Unfortunately there are a number of open bugs related to
|
||||||
|
// interactions among the LoadMode bits:
|
||||||
|
// - https://github.com/golang/go/issues/48226
|
||||||
|
// - https://github.com/golang/go/issues/56633
|
||||||
|
// - https://github.com/golang/go/issues/56677
|
||||||
|
// - https://github.com/golang/go/issues/58726
|
||||||
|
// - https://github.com/golang/go/issues/63517
|
||||||
type LoadMode int
|
type LoadMode int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -123,7 +133,14 @@ const (
|
||||||
|
|
||||||
// A Config specifies details about how packages should be loaded.
|
// A Config specifies details about how packages should be loaded.
|
||||||
// The zero value is a valid configuration.
|
// The zero value is a valid configuration.
|
||||||
|
//
|
||||||
// Calls to Load do not modify this struct.
|
// Calls to Load do not modify this struct.
|
||||||
|
//
|
||||||
|
// TODO(adonovan): #67702: this is currently false: in fact,
|
||||||
|
// calls to [Load] do not modify the public fields of this struct, but
|
||||||
|
// may modify hidden fields, so concurrent calls to [Load] must not
|
||||||
|
// use the same Config. But perhaps we should reestablish the
|
||||||
|
// documented invariant.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
// Mode controls the level of information returned for each package.
|
// Mode controls the level of information returned for each package.
|
||||||
Mode LoadMode
|
Mode LoadMode
|
||||||
|
@ -199,13 +216,23 @@ type Config struct {
|
||||||
// setting Tests may have no effect.
|
// setting Tests may have no effect.
|
||||||
Tests bool
|
Tests bool
|
||||||
|
|
||||||
// Overlay provides a mapping of absolute file paths to file contents.
|
// Overlay is a mapping from absolute file paths to file contents.
|
||||||
// If the file with the given path already exists, the parser will use the
|
|
||||||
// alternative file contents provided by the map.
|
|
||||||
//
|
//
|
||||||
// Overlays provide incomplete support for when a given file doesn't
|
// For each map entry, [Load] uses the alternative file
|
||||||
// already exist on disk. See the package doc above for more details.
|
// contents provided by the overlay mapping instead of reading
|
||||||
|
// from the file system. This mechanism can be used to enable
|
||||||
|
// editor-integrated tools to correctly analyze the contents
|
||||||
|
// of modified but unsaved buffers, for example.
|
||||||
|
//
|
||||||
|
// The overlay mapping is passed to the build system's driver
|
||||||
|
// (see "The driver protocol") so that it too can report
|
||||||
|
// consistent package metadata about unsaved files. However,
|
||||||
|
// drivers may vary in their level of support for overlays.
|
||||||
Overlay map[string][]byte
|
Overlay map[string][]byte
|
||||||
|
|
||||||
|
// goListOverlayFile is the JSON file that encodes the Overlay
|
||||||
|
// mapping, used by 'go list -overlay=...'
|
||||||
|
goListOverlayFile string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load loads and returns the Go packages named by the given patterns.
|
// Load loads and returns the Go packages named by the given patterns.
|
||||||
|
@ -213,6 +240,20 @@ type Config struct {
|
||||||
// Config specifies loading options;
|
// Config specifies loading options;
|
||||||
// nil behaves the same as an empty Config.
|
// nil behaves the same as an empty Config.
|
||||||
//
|
//
|
||||||
|
// The [Config.Mode] field is a set of bits that determine what kinds
|
||||||
|
// of information should be computed and returned. Modes that require
|
||||||
|
// more information tend to be slower. See [LoadMode] for details
|
||||||
|
// and important caveats. Its zero value is equivalent to
|
||||||
|
// NeedName | NeedFiles | NeedCompiledGoFiles.
|
||||||
|
//
|
||||||
|
// Each call to Load returns a new set of [Package] instances.
|
||||||
|
// The Packages and their Imports form a directed acyclic graph.
|
||||||
|
//
|
||||||
|
// If the [NeedTypes] mode flag was set, each call to Load uses a new
|
||||||
|
// [types.Importer], so [types.Object] and [types.Type] values from
|
||||||
|
// different calls to Load must not be mixed as they will have
|
||||||
|
// inconsistent notions of type identity.
|
||||||
|
//
|
||||||
// If any of the patterns was invalid as defined by the
|
// If any of the patterns was invalid as defined by the
|
||||||
// underlying build system, Load returns an error.
|
// underlying build system, Load returns an error.
|
||||||
// It may return an empty list of packages without an error,
|
// It may return an empty list of packages without an error,
|
||||||
|
@ -286,6 +327,17 @@ func defaultDriver(cfg *Config, patterns ...string) (*DriverResponse, bool, erro
|
||||||
// (fall through)
|
// (fall through)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// go list fallback
|
||||||
|
//
|
||||||
|
// Write overlays once, as there are many calls
|
||||||
|
// to 'go list' (one per chunk plus others too).
|
||||||
|
overlay, cleanupOverlay, err := gocommand.WriteOverlays(cfg.Overlay)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
|
defer cleanupOverlay()
|
||||||
|
cfg.goListOverlayFile = overlay
|
||||||
|
|
||||||
response, err := callDriverOnChunks(goListDriver, cfg, chunks)
|
response, err := callDriverOnChunks(goListDriver, cfg, chunks)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false, err
|
return nil, false, err
|
||||||
|
@ -365,6 +417,9 @@ func mergeResponses(responses ...*DriverResponse) *DriverResponse {
|
||||||
}
|
}
|
||||||
|
|
||||||
// A Package describes a loaded Go package.
|
// A Package describes a loaded Go package.
|
||||||
|
//
|
||||||
|
// It also defines part of the JSON schema of [DriverResponse].
|
||||||
|
// See the package documentation for an overview.
|
||||||
type Package struct {
|
type Package struct {
|
||||||
// ID is a unique identifier for a package,
|
// ID is a unique identifier for a package,
|
||||||
// in a syntax provided by the underlying build system.
|
// in a syntax provided by the underlying build system.
|
||||||
|
@ -423,6 +478,13 @@ type Package struct {
|
||||||
// to corresponding loaded Packages.
|
// to corresponding loaded Packages.
|
||||||
Imports map[string]*Package
|
Imports map[string]*Package
|
||||||
|
|
||||||
|
// Module is the module information for the package if it exists.
|
||||||
|
//
|
||||||
|
// Note: it may be missing for std and cmd; see Go issue #65816.
|
||||||
|
Module *Module
|
||||||
|
|
||||||
|
// -- The following fields are not part of the driver JSON schema. --
|
||||||
|
|
||||||
// Types provides type information for the package.
|
// Types provides type information for the package.
|
||||||
// The NeedTypes LoadMode bit sets this field for packages matching the
|
// The NeedTypes LoadMode bit sets this field for packages matching the
|
||||||
// patterns; type information for dependencies may be missing or incomplete,
|
// patterns; type information for dependencies may be missing or incomplete,
|
||||||
|
@ -431,15 +493,15 @@ type Package struct {
|
||||||
// Each call to [Load] returns a consistent set of type
|
// Each call to [Load] returns a consistent set of type
|
||||||
// symbols, as defined by the comment at [types.Identical].
|
// symbols, as defined by the comment at [types.Identical].
|
||||||
// Avoid mixing type information from two or more calls to [Load].
|
// Avoid mixing type information from two or more calls to [Load].
|
||||||
Types *types.Package
|
Types *types.Package `json:"-"`
|
||||||
|
|
||||||
// Fset provides position information for Types, TypesInfo, and Syntax.
|
// Fset provides position information for Types, TypesInfo, and Syntax.
|
||||||
// It is set only when Types is set.
|
// It is set only when Types is set.
|
||||||
Fset *token.FileSet
|
Fset *token.FileSet `json:"-"`
|
||||||
|
|
||||||
// IllTyped indicates whether the package or any dependency contains errors.
|
// IllTyped indicates whether the package or any dependency contains errors.
|
||||||
// It is set only when Types is set.
|
// It is set only when Types is set.
|
||||||
IllTyped bool
|
IllTyped bool `json:"-"`
|
||||||
|
|
||||||
// Syntax is the package's syntax trees, for the files listed in CompiledGoFiles.
|
// Syntax is the package's syntax trees, for the files listed in CompiledGoFiles.
|
||||||
//
|
//
|
||||||
|
@ -449,26 +511,28 @@ type Package struct {
|
||||||
//
|
//
|
||||||
// Syntax is kept in the same order as CompiledGoFiles, with the caveat that nils are
|
// Syntax is kept in the same order as CompiledGoFiles, with the caveat that nils are
|
||||||
// removed. If parsing returned nil, Syntax may be shorter than CompiledGoFiles.
|
// removed. If parsing returned nil, Syntax may be shorter than CompiledGoFiles.
|
||||||
Syntax []*ast.File
|
Syntax []*ast.File `json:"-"`
|
||||||
|
|
||||||
// TypesInfo provides type information about the package's syntax trees.
|
// TypesInfo provides type information about the package's syntax trees.
|
||||||
// It is set only when Syntax is set.
|
// It is set only when Syntax is set.
|
||||||
TypesInfo *types.Info
|
TypesInfo *types.Info `json:"-"`
|
||||||
|
|
||||||
// TypesSizes provides the effective size function for types in TypesInfo.
|
// TypesSizes provides the effective size function for types in TypesInfo.
|
||||||
TypesSizes types.Sizes
|
TypesSizes types.Sizes `json:"-"`
|
||||||
|
|
||||||
|
// -- internal --
|
||||||
|
|
||||||
// forTest is the package under test, if any.
|
// forTest is the package under test, if any.
|
||||||
forTest string
|
forTest string
|
||||||
|
|
||||||
// depsErrors is the DepsErrors field from the go list response, if any.
|
// depsErrors is the DepsErrors field from the go list response, if any.
|
||||||
depsErrors []*packagesinternal.PackageError
|
depsErrors []*packagesinternal.PackageError
|
||||||
|
|
||||||
// module is the module information for the package if it exists.
|
|
||||||
Module *Module
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Module provides module information for a package.
|
// Module provides module information for a package.
|
||||||
|
//
|
||||||
|
// It also defines part of the JSON schema of [DriverResponse].
|
||||||
|
// See the package documentation for an overview.
|
||||||
type Module struct {
|
type Module struct {
|
||||||
Path string // module path
|
Path string // module path
|
||||||
Version string // module version
|
Version string // module version
|
||||||
|
@ -601,6 +665,7 @@ func (p *Package) UnmarshalJSON(b []byte) error {
|
||||||
OtherFiles: flat.OtherFiles,
|
OtherFiles: flat.OtherFiles,
|
||||||
EmbedFiles: flat.EmbedFiles,
|
EmbedFiles: flat.EmbedFiles,
|
||||||
EmbedPatterns: flat.EmbedPatterns,
|
EmbedPatterns: flat.EmbedPatterns,
|
||||||
|
IgnoredFiles: flat.IgnoredFiles,
|
||||||
ExportFile: flat.ExportFile,
|
ExportFile: flat.ExportFile,
|
||||||
}
|
}
|
||||||
if len(flat.Imports) > 0 {
|
if len(flat.Imports) > 0 {
|
||||||
|
|
|
@ -8,12 +8,14 @@ package gocommand
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
"reflect"
|
"reflect"
|
||||||
"regexp"
|
"regexp"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
@ -167,7 +169,9 @@ type Invocation struct {
|
||||||
// TODO(rfindley): remove, in favor of Args.
|
// TODO(rfindley): remove, in favor of Args.
|
||||||
ModFile string
|
ModFile string
|
||||||
|
|
||||||
// If Overlay is set, the go command is invoked with -overlay=Overlay.
|
// Overlay is the name of the JSON overlay file that describes
|
||||||
|
// unsaved editor buffers; see [WriteOverlays].
|
||||||
|
// If set, the go command is invoked with -overlay=Overlay.
|
||||||
// TODO(rfindley): remove, in favor of Args.
|
// TODO(rfindley): remove, in favor of Args.
|
||||||
Overlay string
|
Overlay string
|
||||||
|
|
||||||
|
@ -255,12 +259,15 @@ func (i *Invocation) run(ctx context.Context, stdout, stderr io.Writer) error {
|
||||||
waitDelay.Set(reflect.ValueOf(30 * time.Second))
|
waitDelay.Set(reflect.ValueOf(30 * time.Second))
|
||||||
}
|
}
|
||||||
|
|
||||||
// On darwin the cwd gets resolved to the real path, which breaks anything that
|
// The cwd gets resolved to the real path. On Darwin, where
|
||||||
// expects the working directory to keep the original path, including the
|
// /tmp is a symlink, this breaks anything that expects the
|
||||||
|
// working directory to keep the original path, including the
|
||||||
// go command when dealing with modules.
|
// go command when dealing with modules.
|
||||||
// The Go stdlib has a special feature where if the cwd and the PWD are the
|
//
|
||||||
// same node then it trusts the PWD, so by setting it in the env for the child
|
// os.Getwd has a special feature where if the cwd and the PWD
|
||||||
// process we fix up all the paths returned by the go command.
|
// are the same node then it trusts the PWD, so by setting it
|
||||||
|
// in the env for the child process we fix up all the paths
|
||||||
|
// returned by the go command.
|
||||||
if !i.CleanEnv {
|
if !i.CleanEnv {
|
||||||
cmd.Env = os.Environ()
|
cmd.Env = os.Environ()
|
||||||
}
|
}
|
||||||
|
@ -351,6 +358,7 @@ func runCmdContext(ctx context.Context, cmd *exec.Cmd) (err error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
startTime := time.Now()
|
||||||
err = cmd.Start()
|
err = cmd.Start()
|
||||||
if stdoutW != nil {
|
if stdoutW != nil {
|
||||||
// The child process has inherited the pipe file,
|
// The child process has inherited the pipe file,
|
||||||
|
@ -377,7 +385,7 @@ func runCmdContext(ctx context.Context, cmd *exec.Cmd) (err error) {
|
||||||
case err := <-resChan:
|
case err := <-resChan:
|
||||||
return err
|
return err
|
||||||
case <-timer.C:
|
case <-timer.C:
|
||||||
HandleHangingGoCommand(cmd.Process)
|
HandleHangingGoCommand(startTime, cmd)
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -411,7 +419,7 @@ func runCmdContext(ctx context.Context, cmd *exec.Cmd) (err error) {
|
||||||
return <-resChan
|
return <-resChan
|
||||||
}
|
}
|
||||||
|
|
||||||
func HandleHangingGoCommand(proc *os.Process) {
|
func HandleHangingGoCommand(start time.Time, cmd *exec.Cmd) {
|
||||||
switch runtime.GOOS {
|
switch runtime.GOOS {
|
||||||
case "linux", "darwin", "freebsd", "netbsd":
|
case "linux", "darwin", "freebsd", "netbsd":
|
||||||
fmt.Fprintln(os.Stderr, `DETECTED A HANGING GO COMMAND
|
fmt.Fprintln(os.Stderr, `DETECTED A HANGING GO COMMAND
|
||||||
|
@ -444,7 +452,7 @@ See golang/go#54461 for more details.`)
|
||||||
panic(fmt.Sprintf("running %s: %v", listFiles, err))
|
panic(fmt.Sprintf("running %s: %v", listFiles, err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
panic(fmt.Sprintf("detected hanging go command (pid %d): see golang/go#54461 for more details", proc.Pid))
|
panic(fmt.Sprintf("detected hanging go command (golang/go#54461); waited %s\n\tcommand:%s\n\tpid:%d", time.Since(start), cmd, cmd.Process.Pid))
|
||||||
}
|
}
|
||||||
|
|
||||||
func cmdDebugStr(cmd *exec.Cmd) string {
|
func cmdDebugStr(cmd *exec.Cmd) string {
|
||||||
|
@ -468,3 +476,73 @@ func cmdDebugStr(cmd *exec.Cmd) string {
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("GOROOT=%v GOPATH=%v GO111MODULE=%v GOPROXY=%v PWD=%v %v", env["GOROOT"], env["GOPATH"], env["GO111MODULE"], env["GOPROXY"], env["PWD"], strings.Join(args, " "))
|
return fmt.Sprintf("GOROOT=%v GOPATH=%v GO111MODULE=%v GOPROXY=%v PWD=%v %v", env["GOROOT"], env["GOPATH"], env["GO111MODULE"], env["GOPROXY"], env["PWD"], strings.Join(args, " "))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WriteOverlays writes each value in the overlay (see the Overlay
|
||||||
|
// field of go/packages.Config) to a temporary file and returns the name
|
||||||
|
// of a JSON file describing the mapping that is suitable for the "go
|
||||||
|
// list -overlay" flag.
|
||||||
|
//
|
||||||
|
// On success, the caller must call the cleanup function exactly once
|
||||||
|
// when the files are no longer needed.
|
||||||
|
func WriteOverlays(overlay map[string][]byte) (filename string, cleanup func(), err error) {
|
||||||
|
// Do nothing if there are no overlays in the config.
|
||||||
|
if len(overlay) == 0 {
|
||||||
|
return "", func() {}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
dir, err := os.MkdirTemp("", "gocommand-*")
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// The caller must clean up this directory,
|
||||||
|
// unless this function returns an error.
|
||||||
|
// (The cleanup operand of each return
|
||||||
|
// statement below is ignored.)
|
||||||
|
defer func() {
|
||||||
|
cleanup = func() {
|
||||||
|
os.RemoveAll(dir)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
cleanup()
|
||||||
|
cleanup = nil
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Write each map entry to a temporary file.
|
||||||
|
overlays := make(map[string]string)
|
||||||
|
for k, v := range overlay {
|
||||||
|
// Use a unique basename for each file (001-foo.go),
|
||||||
|
// to avoid creating nested directories.
|
||||||
|
base := fmt.Sprintf("%d-%s.go", 1+len(overlays), filepath.Base(k))
|
||||||
|
filename := filepath.Join(dir, base)
|
||||||
|
err := os.WriteFile(filename, v, 0666)
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
overlays[k] = filename
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the JSON overlay file that maps logical file names to temp files.
|
||||||
|
//
|
||||||
|
// OverlayJSON is the format overlay files are expected to be in.
|
||||||
|
// The Replace map maps from overlaid paths to replacement paths:
|
||||||
|
// the Go command will forward all reads trying to open
|
||||||
|
// each overlaid path to its replacement path, or consider the overlaid
|
||||||
|
// path not to exist if the replacement path is empty.
|
||||||
|
//
|
||||||
|
// From golang/go#39958.
|
||||||
|
type OverlayJSON struct {
|
||||||
|
Replace map[string]string `json:"replace,omitempty"`
|
||||||
|
}
|
||||||
|
b, err := json.Marshal(OverlayJSON{Replace: overlays})
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
filename = filepath.Join(dir, "overlay.json")
|
||||||
|
if err := os.WriteFile(filename, b, 0666); err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return filename, nil, nil
|
||||||
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ import (
|
||||||
"go/types"
|
"go/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// FileVersions returns a file's Go version.
|
// FileVersion returns a file's Go version.
|
||||||
// The reported version is an unknown Future version if a
|
// The reported version is an unknown Future version if a
|
||||||
// version cannot be determined.
|
// version cannot be determined.
|
||||||
func FileVersion(info *types.Info, file *ast.File) string {
|
func FileVersion(info *types.Info, file *ast.File) string {
|
||||||
|
|
|
@ -212,7 +212,7 @@ github.com/letsencrypt/validator/v10
|
||||||
# github.com/matttproud/golang_protobuf_extensions v1.0.4
|
# github.com/matttproud/golang_protobuf_extensions v1.0.4
|
||||||
## explicit; go 1.9
|
## explicit; go 1.9
|
||||||
github.com/matttproud/golang_protobuf_extensions/pbutil
|
github.com/matttproud/golang_protobuf_extensions/pbutil
|
||||||
# github.com/miekg/dns v1.1.58
|
# github.com/miekg/dns v1.1.61
|
||||||
## explicit; go 1.19
|
## explicit; go 1.19
|
||||||
github.com/miekg/dns
|
github.com/miekg/dns
|
||||||
# github.com/miekg/pkcs11 v1.1.1
|
# github.com/miekg/pkcs11 v1.1.1
|
||||||
|
@ -359,7 +359,7 @@ golang.org/x/crypto/pbkdf2
|
||||||
# golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3
|
# golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3
|
||||||
## explicit; go 1.20
|
## explicit; go 1.20
|
||||||
golang.org/x/exp/maps
|
golang.org/x/exp/maps
|
||||||
# golang.org/x/mod v0.17.0
|
# golang.org/x/mod v0.18.0
|
||||||
## explicit; go 1.18
|
## explicit; go 1.18
|
||||||
golang.org/x/mod/semver
|
golang.org/x/mod/semver
|
||||||
# golang.org/x/net v0.26.0
|
# golang.org/x/net v0.26.0
|
||||||
|
@ -395,7 +395,7 @@ golang.org/x/text/secure/bidirule
|
||||||
golang.org/x/text/transform
|
golang.org/x/text/transform
|
||||||
golang.org/x/text/unicode/bidi
|
golang.org/x/text/unicode/bidi
|
||||||
golang.org/x/text/unicode/norm
|
golang.org/x/text/unicode/norm
|
||||||
# golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d
|
# golang.org/x/tools v0.22.0
|
||||||
## explicit; go 1.19
|
## explicit; go 1.19
|
||||||
golang.org/x/tools/go/gcexportdata
|
golang.org/x/tools/go/gcexportdata
|
||||||
golang.org/x/tools/go/internal/packagesdriver
|
golang.org/x/tools/go/internal/packagesdriver
|
||||||
|
|
Loading…
Reference in New Issue