Skip to content

Commit 5c172cf

Browse files
committed
Add $OPTION directive and "fallthrough" option
Add the `$OPTION` directive to allow configuring the plugin. Implement an option, "fallthrough" which causes the plugin to continue to the next plugin in the chain when there is no match, instead of always returning NXDOMAIN. Signed-Off-By: Dan Fuhry <dan@fuhry.com>
1 parent e8b4cfd commit 5c172cf

File tree

3 files changed

+44
-2
lines changed

3 files changed

+44
-2
lines changed

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ This plugin can only be used once per Server Block.
3333

3434
~~~
3535
records [ZONES...] {
36+
$OPTION [OPTION]
3637
[INLINE]
3738
}
3839
~~~
@@ -42,6 +43,9 @@ records [ZONES...] {
4243
* **INLINE** the resource record that are to be served. These must be specified as the text
4344
represenation (as specifed in RFC 1035) of the record. See the examples below. Each record must
4445
be on a single line.
46+
* **OPTION** is a configuration option for the plugin. The following options are supported:
47+
* `fallthrough`: When no matching record is found, instead of returning NXDOMAIN, the plugin will
48+
call to the next plugin in the chain.
4549

4650
If domain name in **INLINE** are not fully qualifed each of the **ZONES** are used as the origin and
4751
added to the names.
@@ -73,6 +77,22 @@ RFC 1035 zone file and everything after it will be ignored, hence the need for q
7377
}
7478
~~~
7579

80+
Override the record for `example.com`, without overriding anything else. Subdomains, like
81+
`foo.example.com`, will continue to be resolved normally (the `forward` plugin, in this case).
82+
83+
~~~
84+
. {
85+
records . {
86+
$OPTION fallthrough
87+
example.com. 300 IN A 127.0.0.1
88+
}
89+
90+
forward . 192.168.0.1 {
91+
except example.com
92+
}
93+
}
94+
~~~
95+
7696
## Bugs
7797

7898
DNSSEC, nor wildcards are implemented. The lookup algorithm is pretty basic. Future enhancements

records.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
type Records struct {
1414
origins []string // for easy matching, these strings are the index in the map m.
1515
m map[string][]dns.RR
16+
fallthru bool
1617

1718
Next plugin.Handler
1819
}
@@ -48,6 +49,9 @@ func (re *Records) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Ms
4849

4950
// handle NXDOMAIN, NODATA and normal response here.
5051
if nxdomain {
52+
if re.fallthru {
53+
return plugin.NextOrFailure(re.Name(), re.Next, ctx, w, r)
54+
}
5155
m.Rcode = dns.RcodeNameError
5256
if soa != nil {
5357
m.Ns = []dns.RR{soa}

setup.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package records
22

33
import (
4+
"fmt"
45
"strings"
56

67
"github.com/coredns/caddy"
@@ -57,9 +58,26 @@ func recordsParse(c *caddy.Controller) (*Records, error) {
5758
// c.Val() + c.RemainingArgs() is the record we need to parse (for each zone given; now tracked in re.origins). When parsing
5859
// the record we just set the ORIGIN to the correct value and magic will happen. If no origin we set it to "."
5960

61+
parseBlocks:
6062
for c.NextBlock() {
61-
s := c.Val() + " "
62-
s += strings.Join(c.RemainingArgs(), " ")
63+
s := c.Val()
64+
if s == "$OPTION" {
65+
if !c.NextArg() {
66+
return nil, fmt.Errorf("parsing block failed: $OPTION missing argument")
67+
}
68+
opt := c.Val()
69+
switch opt {
70+
case "fallthrough":
71+
re.fallthru = true
72+
default:
73+
return nil, fmt.Errorf("parsing block failed: unknown option: %q", opt)
74+
}
75+
if len(c.RemainingArgs()) > 0 {
76+
return nil, fmt.Errorf("parsing block failed: extra arguments after option %q", opt)
77+
}
78+
continue parseBlocks
79+
}
80+
s += " " + strings.Join(c.RemainingArgs(), " ")
6381
for _, o := range re.origins {
6482
rr, err := dns.NewRR("$ORIGIN " + o + "\n" + s + "\n")
6583
if err != nil {

0 commit comments

Comments
 (0)