mirror of
https://github.com/status-im/consul.git
synced 2025-02-20 09:28:34 +00:00
Support RFC 2782 for prepared query DNS lookups (#14465)
Format: _<query id or name>._tcp.query[.<datacenter>].<domain>
This commit is contained in:
parent
f0837a2cd0
commit
3e7e8ae9c5
3
.changelog/14465.txt
Normal file
3
.changelog/14465.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
```release-note:improvement
|
||||||
|
dns: support RFC 2782 SRV lookups for prepared queries using format `_<query id or name>._tcp.query[.<datacenter>].<domain>`.
|
||||||
|
```
|
20
agent/dns.go
20
agent/dns.go
@ -908,10 +908,11 @@ func (d *DNSServer) dispatch(remoteAddr net.Addr, req, resp *dns.Msg, maxRecursi
|
|||||||
return d.nodeLookup(cfg, lookup, req, resp)
|
return d.nodeLookup(cfg, lookup, req, resp)
|
||||||
|
|
||||||
case "query":
|
case "query":
|
||||||
|
n := len(queryParts)
|
||||||
datacenter := d.agent.config.Datacenter
|
datacenter := d.agent.config.Datacenter
|
||||||
|
|
||||||
// ensure we have a query name
|
// ensure we have a query name
|
||||||
if len(queryParts) < 1 {
|
if n < 1 {
|
||||||
return invalid()
|
return invalid()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -919,8 +920,23 @@ func (d *DNSServer) dispatch(remoteAddr net.Addr, req, resp *dns.Msg, maxRecursi
|
|||||||
return invalid()
|
return invalid()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
query := ""
|
||||||
|
|
||||||
|
// If the first and last DNS query parts begin with _, this is an RFC 2782 style SRV lookup.
|
||||||
|
// This allows for prepared query names to include "." (for backwards compatibility).
|
||||||
|
// Otherwise, this is a standard prepared query lookup.
|
||||||
|
if n >= 2 && strings.HasPrefix(queryParts[0], "_") && strings.HasPrefix(queryParts[n-1], "_") {
|
||||||
|
// The last DNS query part is the protocol field (ignored).
|
||||||
|
// All prior parts are the prepared query name or ID.
|
||||||
|
query = strings.Join(queryParts[:n-1], ".")
|
||||||
|
|
||||||
|
// Strip leading underscore
|
||||||
|
query = query[1:]
|
||||||
|
} else {
|
||||||
// Allow a "." in the query name, just join all the parts.
|
// Allow a "." in the query name, just join all the parts.
|
||||||
query := strings.Join(queryParts, ".")
|
query = strings.Join(queryParts, ".")
|
||||||
|
}
|
||||||
|
|
||||||
err := d.preparedQueryLookup(cfg, datacenter, query, remoteAddr, req, resp, maxRecursionLevel)
|
err := d.preparedQueryLookup(cfg, datacenter, query, remoteAddr, req, resp, maxRecursionLevel)
|
||||||
return ecsNotGlobalError{error: err}
|
return ecsNotGlobalError{error: err}
|
||||||
|
|
||||||
|
@ -2743,13 +2743,16 @@ func TestDNS_ServiceLookup_ServiceAddress_SRV(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Register an equivalent prepared query.
|
// Register an equivalent prepared query.
|
||||||
|
// Specify prepared query name containing "." to test
|
||||||
|
// since that is technically supported (though atypical).
|
||||||
var id string
|
var id string
|
||||||
|
preparedQueryName := "query.name.with.dots"
|
||||||
{
|
{
|
||||||
args := &structs.PreparedQueryRequest{
|
args := &structs.PreparedQueryRequest{
|
||||||
Datacenter: "dc1",
|
Datacenter: "dc1",
|
||||||
Op: structs.PreparedQueryCreate,
|
Op: structs.PreparedQueryCreate,
|
||||||
Query: &structs.PreparedQuery{
|
Query: &structs.PreparedQuery{
|
||||||
Name: "test",
|
Name: preparedQueryName,
|
||||||
Service: structs.ServiceQuery{
|
Service: structs.ServiceQuery{
|
||||||
Service: "db",
|
Service: "db",
|
||||||
},
|
},
|
||||||
@ -2764,6 +2767,9 @@ func TestDNS_ServiceLookup_ServiceAddress_SRV(t *testing.T) {
|
|||||||
questions := []string{
|
questions := []string{
|
||||||
"db.service.consul.",
|
"db.service.consul.",
|
||||||
id + ".query.consul.",
|
id + ".query.consul.",
|
||||||
|
preparedQueryName + ".query.consul.",
|
||||||
|
fmt.Sprintf("_%s._tcp.query.consul.", id),
|
||||||
|
fmt.Sprintf("_%s._tcp.query.consul.", preparedQueryName),
|
||||||
}
|
}
|
||||||
for _, question := range questions {
|
for _, question := range questions {
|
||||||
m := new(dns.Msg)
|
m := new(dns.Msg)
|
||||||
|
@ -396,16 +396,24 @@ you can use the following query formats specify namespace but not partition:
|
|||||||
|
|
||||||
### Prepared Query Lookups
|
### Prepared Query Lookups
|
||||||
|
|
||||||
The format of a prepared query lookup is:
|
The following formats are valid for prepared query lookups:
|
||||||
|
|
||||||
|
- Standard lookup
|
||||||
|
|
||||||
```text
|
```text
|
||||||
<query or name>.query[.<datacenter>].<domain>
|
<query name or id>.query[.<datacenter>].<domain>
|
||||||
|
```
|
||||||
|
|
||||||
|
- [RFC 2782](https://tools.ietf.org/html/rfc2782) SRV lookup
|
||||||
|
|
||||||
|
```text
|
||||||
|
_<query name or id>._tcp.query[.<datacenter>].<domain>
|
||||||
```
|
```
|
||||||
|
|
||||||
The `datacenter` is optional, and if not provided, the datacenter of this Consul
|
The `datacenter` is optional, and if not provided, the datacenter of this Consul
|
||||||
agent is assumed.
|
agent is assumed.
|
||||||
|
|
||||||
The `query or name` is the ID or given name of an existing
|
The `query name or id` is the given name or ID of an existing
|
||||||
[Prepared Query](/api-docs/query). These behave like standard service
|
[Prepared Query](/api-docs/query). These behave like standard service
|
||||||
queries but provide a much richer set of features, such as filtering by multiple
|
queries but provide a much richer set of features, such as filtering by multiple
|
||||||
tags and automatically failing over to look for services in remote datacenters if
|
tags and automatically failing over to look for services in remote datacenters if
|
||||||
|
Loading…
x
Reference in New Issue
Block a user