Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
C
Coredns
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Railgun
Coredns
Commits
c9d8a57e
Commit
c9d8a57e
authored
Apr 15, 2016
by
Miek Gieben
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Reload zone when a write is detected (#122)
Zone reloading
parent
29ad957a
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
179 additions
and
60 deletions
+179
-60
core/setup/file.go
core/setup/file.go
+16
-10
core/setup/secondary.go
core/setup/secondary.go
+1
-1
middleware/file/README.md
middleware/file/README.md
+3
-1
middleware/file/file.go
middleware/file/file.go
+2
-15
middleware/file/notify.go
middleware/file/notify.go
+1
-1
middleware/file/reload_test.go
middleware/file/reload_test.go
+62
-0
middleware/file/secondary.go
middleware/file/secondary.go
+8
-21
middleware/file/secondary_test.go
middleware/file/secondary_test.go
+3
-3
middleware/file/xfr.go
middleware/file/xfr.go
+1
-1
middleware/file/zone.go
middleware/file/zone.go
+82
-7
No files found.
core/setup/file.go
View file @
c9d8a57e
...
@@ -16,18 +16,17 @@ func File(c *Controller) (middleware.Middleware, error) {
...
@@ -16,18 +16,17 @@ func File(c *Controller) (middleware.Middleware, error) {
return
nil
,
err
return
nil
,
err
}
}
// Add startup functions to notify the master.
// Add startup functions to notify the master
(s)
.
for
_
,
n
:=
range
zones
.
Names
{
for
_
,
n
:=
range
zones
.
Names
{
if
len
(
zones
.
Z
[
n
]
.
TransferTo
)
>
0
{
c
.
Startup
=
append
(
c
.
Startup
,
func
()
error
{
c
.
Startup
=
append
(
c
.
Startup
,
func
()
error
{
zones
.
Z
[
n
]
.
StartupOnce
.
Do
(
func
()
{
zones
.
Z
[
n
]
.
StartupOnce
.
Do
(
func
()
{
if
len
(
zones
.
Z
[
n
]
.
TransferTo
)
>
0
{
if
len
(
zones
.
Z
[
n
]
.
TransferTo
)
>
0
{
zones
.
Z
[
n
]
.
Notify
()
zones
.
Z
[
n
]
.
Notify
()
}
}
zones
.
Z
[
n
]
.
Reload
(
nil
)
})
return
nil
})
})
}
return
nil
})
}
}
return
func
(
next
middleware
.
Handler
)
middleware
.
Handler
{
return
func
(
next
middleware
.
Handler
)
middleware
.
Handler
{
...
@@ -67,17 +66,24 @@ func fileParse(c *Controller) (file.Zones, error) {
...
@@ -67,17 +66,24 @@ func fileParse(c *Controller) (file.Zones, error) {
names
=
append
(
names
,
origins
[
i
])
names
=
append
(
names
,
origins
[
i
])
}
}
noReload
:=
false
for
c
.
NextBlock
()
{
for
c
.
NextBlock
()
{
t
,
_
,
e
:=
parseTransfer
(
c
)
t
,
_
,
e
:=
parseTransfer
(
c
)
if
e
!=
nil
{
if
e
!=
nil
{
return
file
.
Zones
{},
e
return
file
.
Zones
{},
e
}
}
switch
c
.
Val
()
{
case
"no_reload"
:
noReload
=
true
}
// discard from, here, maybe check and show log when we do?
// discard from, here, maybe check and show log when we do?
for
_
,
origin
:=
range
origins
{
for
_
,
origin
:=
range
origins
{
if
t
!=
nil
{
if
t
!=
nil
{
z
[
origin
]
.
TransferTo
=
append
(
z
[
origin
]
.
TransferTo
,
t
...
)
z
[
origin
]
.
TransferTo
=
append
(
z
[
origin
]
.
TransferTo
,
t
...
)
}
}
z
[
origin
]
.
NoReload
=
noReload
}
}
}
}
}
}
}
}
...
...
core/setup/secondary.go
View file @
c9d8a57e
...
@@ -47,7 +47,7 @@ func secondaryParse(c *Controller) (file.Zones, error) {
...
@@ -47,7 +47,7 @@ func secondaryParse(c *Controller) (file.Zones, error) {
}
}
for
i
,
_
:=
range
origins
{
for
i
,
_
:=
range
origins
{
origins
[
i
]
=
middleware
.
Host
(
origins
[
i
])
.
Normalize
()
origins
[
i
]
=
middleware
.
Host
(
origins
[
i
])
.
Normalize
()
z
[
origins
[
i
]]
=
file
.
NewZone
(
origins
[
i
])
z
[
origins
[
i
]]
=
file
.
NewZone
(
origins
[
i
]
,
"stdin"
)
names
=
append
(
names
,
origins
[
i
])
names
=
append
(
names
,
origins
[
i
])
}
}
...
...
middleware/file/README.md
View file @
c9d8a57e
...
@@ -24,13 +24,15 @@ TSIG key information, something like `transfer out [address...] key [name] [base
...
@@ -24,13 +24,15 @@ TSIG key information, something like `transfer out [address...] key [name] [base
file dbfile [zones... ] {
file dbfile [zones... ] {
transfer from [address...]
transfer from [address...]
transfer to [address...]
transfer to [address...]
no_reload
}
}
~~~
~~~
*
`transfer`
enables zone transfers. It may be specified multiples times.
*To*
or
*from*
signals
*
`transfer`
enables zone transfers. It may be specified multiples times.
*To*
or
*from*
signals
the direction. Addresses must be denoted in CIDR notation (127.0.0.1/32 etc.) or just as plain
the direction. Addresses must be denoted in CIDR notation (127.0.0.1/32 etc.) or just as plain
address. The special wildcard "
*
" means: the entire internet (only valid for 'transfer to').
address. The special wildcard "
*
" means: the entire internet (only valid for 'transfer to').
*
`no_reload`
by default CoreDNS will reload a zone from disk whenever it detects a change to the
file. This option disables that behavior.
## Examples
## Examples
...
...
middleware/file/file.go
View file @
c9d8a57e
...
@@ -105,27 +105,14 @@ func (f File) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (i
...
@@ -105,27 +105,14 @@ func (f File) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (i
// Parse parses the zone in filename and returns a new Zone or an error.
// Parse parses the zone in filename and returns a new Zone or an error.
func
Parse
(
f
io
.
Reader
,
origin
,
fileName
string
)
(
*
Zone
,
error
)
{
func
Parse
(
f
io
.
Reader
,
origin
,
fileName
string
)
(
*
Zone
,
error
)
{
tokens
:=
dns
.
ParseZone
(
f
,
dns
.
Fqdn
(
origin
),
fileName
)
tokens
:=
dns
.
ParseZone
(
f
,
dns
.
Fqdn
(
origin
),
fileName
)
z
:=
NewZone
(
origin
)
z
:=
NewZone
(
origin
,
fileName
)
for
x
:=
range
tokens
{
for
x
:=
range
tokens
{
if
x
.
Error
!=
nil
{
if
x
.
Error
!=
nil
{
log
.
Printf
(
"[ERROR] Failed to parse `%s': %v"
,
origin
,
x
.
Error
)
log
.
Printf
(
"[ERROR] Failed to parse `%s': %v"
,
origin
,
x
.
Error
)
return
nil
,
x
.
Error
return
nil
,
x
.
Error
}
}
switch
h
:=
x
.
RR
.
Header
()
.
Rrtype
;
h
{
if
err
:=
z
.
Insert
(
x
.
RR
);
err
!=
nil
{
case
dns
.
TypeSOA
:
z
.
SOA
=
x
.
RR
.
(
*
dns
.
SOA
)
case
dns
.
TypeNSEC3
,
dns
.
TypeNSEC3PARAM
:
err
:=
fmt
.
Errorf
(
"NSEC3 zone is not supported, dropping"
)
log
.
Printf
(
"[ERROR] Failed to parse `%s': %v"
,
origin
,
err
)
return
nil
,
err
return
nil
,
err
case
dns
.
TypeRRSIG
:
if
x
,
ok
:=
x
.
RR
.
(
*
dns
.
RRSIG
);
ok
&&
x
.
TypeCovered
==
dns
.
TypeSOA
{
z
.
SIG
=
append
(
z
.
SIG
,
x
)
continue
}
fallthrough
default
:
z
.
Insert
(
x
.
RR
)
}
}
}
}
return
z
,
nil
return
z
,
nil
...
...
middleware/file/notify.go
View file @
c9d8a57e
...
@@ -30,7 +30,7 @@ func (z *Zone) isNotify(state middleware.State) bool {
...
@@ -30,7 +30,7 @@ func (z *Zone) isNotify(state middleware.State) bool {
// Notify will send notifies to all configured TransferTo IP addresses.
// Notify will send notifies to all configured TransferTo IP addresses.
func
(
z
*
Zone
)
Notify
()
{
func
(
z
*
Zone
)
Notify
()
{
go
notify
(
z
.
name
,
z
.
TransferTo
)
go
notify
(
z
.
origin
,
z
.
TransferTo
)
}
}
// notify sends notifies to the configured remote servers. It will try up to three times
// notify sends notifies to the configured remote servers. It will try up to three times
...
...
middleware/file/reload_test.go
0 → 100644
View file @
c9d8a57e
package
file
import
(
"io/ioutil"
"os"
"testing"
"time"
"github.com/miekg/coredns/middleware/test"
"github.com/miekg/dns"
)
func
TestZoneReload
(
t
*
testing
.
T
)
{
fileName
,
rm
,
err
:=
test
.
Zone
(
t
,
"."
,
reloadZoneTest
)
if
err
!=
nil
{
t
.
Fatalf
(
"failed to create zone: %s"
,
err
)
}
defer
rm
()
reader
,
err
:=
os
.
Open
(
fileName
)
if
err
!=
nil
{
t
.
Fatalf
(
"failed to open zone: %s"
,
err
)
}
z
,
err
:=
Parse
(
reader
,
"miek.nl"
,
fileName
)
if
err
!=
nil
{
t
.
Fatalf
(
"failed to parse zone: %s"
,
err
)
}
z
.
Reload
(
nil
)
if
_
,
_
,
_
,
res
:=
z
.
Lookup
(
"miek.nl."
,
dns
.
TypeSOA
,
false
);
res
!=
Success
{
t
.
Fatalf
(
"failed to lookup, got %d"
,
res
)
}
if
_
,
_
,
_
,
res
:=
z
.
Lookup
(
"miek.nl."
,
dns
.
TypeNS
,
false
);
res
!=
Success
{
t
.
Fatalf
(
"failed to lookup, got %d"
,
res
)
}
if
len
(
z
.
All
())
!=
5
{
t
.
Fatalf
(
"expected 5 RRs, got %d"
,
len
(
z
.
All
()))
}
if
err
:=
ioutil
.
WriteFile
(
fileName
,
[]
byte
(
reloadZone2Test
),
0644
);
err
!=
nil
{
t
.
Fatalf
(
"failed to write new zone data"
,
err
)
}
// Could still be racy, but we need to wait a bit for the event to be seen
time
.
Sleep
(
1
*
time
.
Second
)
if
len
(
z
.
All
())
!=
3
{
t
.
Fatalf
(
"expected 3 RRs, got %d"
,
len
(
z
.
All
()))
}
}
const
reloadZoneTest
=
`miek.nl. 1627 IN SOA linode.atoom.net. miek.miek.nl. 1460175181 14400 3600 604800 14400
miek.nl. 1627 IN NS ext.ns.whyscream.net.
miek.nl. 1627 IN NS omval.tednet.nl.
miek.nl. 1627 IN NS linode.atoom.net.
miek.nl. 1627 IN NS ns-ext.nlnetlabs.nl.
`
const
reloadZone2Test
=
`miek.nl. 1627 IN SOA linode.atoom.net. miek.miek.nl. 1460175181 14400 3600 604800 14400
miek.nl. 1627 IN NS ext.ns.whyscream.net.
miek.nl. 1627 IN NS omval.tednet.nl.
`
middleware/file/secondary.go
View file @
c9d8a57e
package
file
package
file
import
(
import
(
"fmt"
"log"
"log"
"time"
"time"
...
@@ -16,7 +15,7 @@ func (z *Zone) TransferIn() error {
...
@@ -16,7 +15,7 @@ func (z *Zone) TransferIn() error {
return
nil
return
nil
}
}
m
:=
new
(
dns
.
Msg
)
m
:=
new
(
dns
.
Msg
)
m
.
SetAxfr
(
z
.
name
)
m
.
SetAxfr
(
z
.
origin
)
z1
:=
z
.
Copy
()
z1
:=
z
.
Copy
()
var
(
var
(
...
@@ -29,32 +28,20 @@ Transfer:
...
@@ -29,32 +28,20 @@ Transfer:
t
:=
new
(
dns
.
Transfer
)
t
:=
new
(
dns
.
Transfer
)
c
,
err
:=
t
.
In
(
m
,
tr
)
c
,
err
:=
t
.
In
(
m
,
tr
)
if
err
!=
nil
{
if
err
!=
nil
{
log
.
Printf
(
"[ERROR] Failed to setup transfer `%s' with `%s': %v"
,
z
.
name
,
tr
,
err
)
log
.
Printf
(
"[ERROR] Failed to setup transfer `%s' with `%s': %v"
,
z
.
origin
,
tr
,
err
)
Err
=
err
Err
=
err
continue
Transfer
continue
Transfer
}
}
for
env
:=
range
c
{
for
env
:=
range
c
{
if
env
.
Error
!=
nil
{
if
env
.
Error
!=
nil
{
log
.
Printf
(
"[ERROR] Failed to parse transfer `%s': %v"
,
z
.
name
,
env
.
Error
)
log
.
Printf
(
"[ERROR] Failed to parse transfer `%s': %v"
,
z
.
origin
,
env
.
Error
)
Err
=
env
.
Error
Err
=
env
.
Error
continue
Transfer
continue
Transfer
}
}
for
_
,
rr
:=
range
env
.
RR
{
for
_
,
rr
:=
range
env
.
RR
{
switch
h
:=
rr
.
Header
()
.
Rrtype
;
h
{
if
err
:=
z1
.
Insert
(
rr
);
err
!=
nil
{
case
dns
.
TypeSOA
:
log
.
Printf
(
"[ERROR] Failed to parse transfer `%s': %v"
,
z
.
origin
,
err
)
z1
.
SOA
=
rr
.
(
*
dns
.
SOA
)
case
dns
.
TypeNSEC3
,
dns
.
TypeNSEC3PARAM
:
err
:=
fmt
.
Errorf
(
"NSEC3 zone is not supported, dropping"
)
log
.
Printf
(
"[ERROR] Failed to parse transfer `%s': %v"
,
z
.
name
,
err
)
return
err
return
err
case
dns
.
TypeRRSIG
:
if
x
,
ok
:=
rr
.
(
*
dns
.
RRSIG
);
ok
&&
x
.
TypeCovered
==
dns
.
TypeSOA
{
z1
.
SIG
=
append
(
z1
.
SIG
,
x
)
continue
}
fallthrough
default
:
z1
.
Insert
(
rr
)
}
}
}
}
}
}
...
@@ -62,7 +49,7 @@ Transfer:
...
@@ -62,7 +49,7 @@ Transfer:
break
break
}
}
if
Err
!=
nil
{
if
Err
!=
nil
{
log
.
Printf
(
"[ERROR] Failed to transfer %s: %s"
,
z
.
name
,
Err
)
log
.
Printf
(
"[ERROR] Failed to transfer %s: %s"
,
z
.
origin
,
Err
)
return
Err
return
Err
}
}
...
@@ -70,7 +57,7 @@ Transfer:
...
@@ -70,7 +57,7 @@ Transfer:
z
.
SOA
=
z1
.
SOA
z
.
SOA
=
z1
.
SOA
z
.
SIG
=
z1
.
SIG
z
.
SIG
=
z1
.
SIG
*
z
.
Expired
=
false
*
z
.
Expired
=
false
log
.
Printf
(
"[INFO] Transferred: %s from %s"
,
z
.
name
,
tr
)
log
.
Printf
(
"[INFO] Transferred: %s from %s"
,
z
.
origin
,
tr
)
return
nil
return
nil
}
}
...
@@ -80,7 +67,7 @@ func (z *Zone) shouldTransfer() (bool, error) {
...
@@ -80,7 +67,7 @@ func (z *Zone) shouldTransfer() (bool, error) {
c
:=
new
(
dns
.
Client
)
c
:=
new
(
dns
.
Client
)
c
.
Net
=
"tcp"
// do this query over TCP to minimize spoofing
c
.
Net
=
"tcp"
// do this query over TCP to minimize spoofing
m
:=
new
(
dns
.
Msg
)
m
:=
new
(
dns
.
Msg
)
m
.
SetQuestion
(
z
.
name
,
dns
.
TypeSOA
)
m
.
SetQuestion
(
z
.
origin
,
dns
.
TypeSOA
)
var
Err
error
var
Err
error
serial
:=
-
1
serial
:=
-
1
...
...
middleware/file/secondary_test.go
View file @
c9d8a57e
...
@@ -81,7 +81,7 @@ func TestShouldTransfer(t *testing.T) {
...
@@ -81,7 +81,7 @@ func TestShouldTransfer(t *testing.T) {
defer
s
.
Shutdown
()
defer
s
.
Shutdown
()
z
:=
new
(
Zone
)
z
:=
new
(
Zone
)
z
.
name
=
testZone
z
.
origin
=
testZone
z
.
TransferFrom
=
[]
string
{
addrstr
}
z
.
TransferFrom
=
[]
string
{
addrstr
}
// Serial smaller
// Serial smaller
...
@@ -118,7 +118,7 @@ func TestTransferIn(t *testing.T) {
...
@@ -118,7 +118,7 @@ func TestTransferIn(t *testing.T) {
z
:=
new
(
Zone
)
z
:=
new
(
Zone
)
z
.
Expired
=
new
(
bool
)
z
.
Expired
=
new
(
bool
)
z
.
name
=
testZone
z
.
origin
=
testZone
z
.
TransferFrom
=
[]
string
{
addrstr
}
z
.
TransferFrom
=
[]
string
{
addrstr
}
err
=
z
.
TransferIn
()
err
=
z
.
TransferIn
()
...
@@ -133,7 +133,7 @@ func TestTransferIn(t *testing.T) {
...
@@ -133,7 +133,7 @@ func TestTransferIn(t *testing.T) {
func
TestIsNotify
(
t
*
testing
.
T
)
{
func
TestIsNotify
(
t
*
testing
.
T
)
{
z
:=
new
(
Zone
)
z
:=
new
(
Zone
)
z
.
Expired
=
new
(
bool
)
z
.
Expired
=
new
(
bool
)
z
.
name
=
testZone
z
.
origin
=
testZone
state
:=
NewState
(
testZone
,
dns
.
TypeSOA
)
state
:=
NewState
(
testZone
,
dns
.
TypeSOA
)
// need to set opcode
// need to set opcode
state
.
Req
.
Opcode
=
dns
.
OpcodeNotify
state
.
Req
.
Opcode
=
dns
.
OpcodeNotify
...
...
middleware/file/xfr.go
View file @
c9d8a57e
...
@@ -38,7 +38,7 @@ func (x Xfr) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (in
...
@@ -38,7 +38,7 @@ func (x Xfr) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (in
j
,
l
:=
0
,
0
j
,
l
:=
0
,
0
records
=
append
(
records
,
records
[
0
])
// add closing SOA to the end
records
=
append
(
records
,
records
[
0
])
// add closing SOA to the end
log
.
Printf
(
"[INFO] Outgoing transfer of %d records of zone %s to %s started"
,
len
(
records
),
x
.
name
,
state
.
IP
())
log
.
Printf
(
"[INFO] Outgoing transfer of %d records of zone %s to %s started"
,
len
(
records
),
x
.
origin
,
state
.
IP
())
for
i
,
r
:=
range
records
{
for
i
,
r
:=
range
records
{
l
+=
dns
.
Len
(
r
)
l
+=
dns
.
Len
(
r
)
if
l
>
transferLength
{
if
l
>
transferLength
{
...
...
middleware/file/zone.go
View file @
c9d8a57e
package
file
package
file
import
(
import
(
"fmt"
"log"
"os"
"sync"
"sync"
"github.com/miekg/coredns/middleware"
"github.com/miekg/coredns/middleware"
"github.com/miekg/coredns/middleware/file/tree"
"github.com/miekg/coredns/middleware/file/tree"
"github.com/fsnotify/fsnotify"
"github.com/miekg/dns"
"github.com/miekg/dns"
)
)
type
Zone
struct
{
type
Zone
struct
{
SOA
*
dns
.
SOA
SOA
*
dns
.
SOA
SIG
[]
dns
.
RR
SIG
[]
dns
.
RR
name
string
origin
string
file
string
*
tree
.
Tree
*
tree
.
Tree
TransferTo
[]
string
TransferTo
[]
string
StartupOnce
sync
.
Once
StartupOnce
sync
.
Once
TransferFrom
[]
string
TransferFrom
[]
string
Expired
*
bool
Expired
*
bool
NoReload
bool
reloadMu
sync
.
RWMutex
// TODO: shutdown watcher channel
}
}
// NewZone returns a new zone.
// NewZone returns a new zone.
func
NewZone
(
name
string
)
*
Zone
{
func
NewZone
(
name
,
file
string
)
*
Zone
{
z
:=
&
Zone
{
name
:
dns
.
Fqdn
(
name
)
,
Tree
:
&
tree
.
Tree
{},
Expired
:
new
(
bool
)}
z
:=
&
Zone
{
origin
:
dns
.
Fqdn
(
name
),
file
:
file
,
Tree
:
&
tree
.
Tree
{},
Expired
:
new
(
bool
)}
*
z
.
Expired
=
false
*
z
.
Expired
=
false
return
z
return
z
}
}
// Copy copies a zone *without* copying the zone's content. It is not a deep copy.
// Copy copies a zone *without* copying the zone's content. It is not a deep copy.
func
(
z
*
Zone
)
Copy
()
*
Zone
{
func
(
z
*
Zone
)
Copy
()
*
Zone
{
z1
:=
NewZone
(
z
.
nam
e
)
z1
:=
NewZone
(
z
.
origin
,
z
.
fil
e
)
z1
.
TransferTo
=
z
.
TransferTo
z1
.
TransferTo
=
z
.
TransferTo
z1
.
TransferFrom
=
z
.
TransferFrom
z1
.
TransferFrom
=
z
.
TransferFrom
z1
.
Expired
=
z
.
Expired
z1
.
Expired
=
z
.
Expired
...
@@ -40,7 +49,24 @@ func (z *Zone) Copy() *Zone {
...
@@ -40,7 +49,24 @@ func (z *Zone) Copy() *Zone {
}
}
// Insert inserts r into z.
// Insert inserts r into z.
func
(
z
*
Zone
)
Insert
(
r
dns
.
RR
)
{
z
.
Tree
.
Insert
(
r
)
}
func
(
z
*
Zone
)
Insert
(
r
dns
.
RR
)
error
{
switch
h
:=
r
.
Header
()
.
Rrtype
;
h
{
case
dns
.
TypeSOA
:
z
.
SOA
=
r
.
(
*
dns
.
SOA
)
return
nil
case
dns
.
TypeNSEC3
,
dns
.
TypeNSEC3PARAM
:
return
fmt
.
Errorf
(
"NSEC3 zone is not supported, dropping"
)
case
dns
.
TypeRRSIG
:
if
x
,
ok
:=
r
.
(
*
dns
.
RRSIG
);
ok
&&
x
.
TypeCovered
==
dns
.
TypeSOA
{
z
.
SIG
=
append
(
z
.
SIG
,
x
)
return
nil
}
fallthrough
default
:
z
.
Tree
.
Insert
(
r
)
}
return
nil
}
// Delete deletes r from z.
// Delete deletes r from z.
func
(
z
*
Zone
)
Delete
(
r
dns
.
RR
)
{
z
.
Tree
.
Delete
(
r
)
}
func
(
z
*
Zone
)
Delete
(
r
dns
.
RR
)
{
z
.
Tree
.
Delete
(
r
)
}
...
@@ -59,6 +85,8 @@ func (z *Zone) TransferAllowed(state middleware.State) bool {
...
@@ -59,6 +85,8 @@ func (z *Zone) TransferAllowed(state middleware.State) bool {
// All returns all records from the zone, the first record will be the SOA record,
// All returns all records from the zone, the first record will be the SOA record,
// otionally followed by all RRSIG(SOA)s.
// otionally followed by all RRSIG(SOA)s.
func
(
z
*
Zone
)
All
()
[]
dns
.
RR
{
func
(
z
*
Zone
)
All
()
[]
dns
.
RR
{
z
.
reloadMu
.
RLock
()
defer
z
.
reloadMu
.
RUnlock
()
records
:=
[]
dns
.
RR
{}
records
:=
[]
dns
.
RR
{}
allNodes
:=
z
.
Tree
.
All
()
allNodes
:=
z
.
Tree
.
All
()
for
_
,
a
:=
range
allNodes
{
for
_
,
a
:=
range
allNodes
{
...
@@ -70,3 +98,50 @@ func (z *Zone) All() []dns.RR {
...
@@ -70,3 +98,50 @@ func (z *Zone) All() []dns.RR {
}
}
return
append
([]
dns
.
RR
{
z
.
SOA
},
records
...
)
return
append
([]
dns
.
RR
{
z
.
SOA
},
records
...
)
}
}
func
(
z
*
Zone
)
Reload
(
shutdown
chan
bool
)
error
{
if
z
.
NoReload
{
return
nil
}
watcher
,
err
:=
fsnotify
.
NewWatcher
()
if
err
!=
nil
{
return
err
}
err
=
watcher
.
Add
(
z
.
file
)
if
err
!=
nil
{
return
err
}
go
func
()
{
// TODO(miek): needs to be killed on reload.
for
{
select
{
case
event
:=
<-
watcher
.
Events
:
if
event
.
Op
&
fsnotify
.
Write
==
fsnotify
.
Write
||
event
.
Op
&
fsnotify
.
Rename
==
fsnotify
.
Rename
{
reader
,
err
:=
os
.
Open
(
z
.
file
)
if
err
!=
nil
{
log
.
Printf
(
"[ERROR] Failed to open `%s' for `%s': %v"
,
z
.
file
,
z
.
origin
,
err
)
continue
}
z
.
reloadMu
.
Lock
()
zone
,
err
:=
Parse
(
reader
,
z
.
origin
,
z
.
file
)
if
err
!=
nil
{
log
.
Printf
(
"[ERROR] Failed to parse `%s': %v"
,
z
.
origin
,
err
)
z
.
reloadMu
.
Unlock
()
continue
}
// copy elements we need
z
.
SOA
=
zone
.
SOA
z
.
SIG
=
zone
.
SIG
z
.
Tree
=
zone
.
Tree
z
.
reloadMu
.
Unlock
()
log
.
Printf
(
"[INFO] Successfully reload zone `%s'"
,
z
.
origin
)
}
case
<-
shutdown
:
watcher
.
Close
()
return
}
}
}()
return
nil
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment