preparing to use hijack

This commit is contained in:
Miek Gieben 2012-08-28 13:12:55 +02:00
parent 3da4bc6bf3
commit 9e318901a6
3 changed files with 42 additions and 17 deletions

View File

@ -76,6 +76,22 @@ func handleReflect(w dns.ResponseWriter, r *dns.Msg) {
t.Txt = []string{str}
switch r.Question[0].Qtype {
case dns.TypeAXFR:
c := make(chan *dns.XfrToken)
var e *error
if err := dns.XfrSend(w, r, c, e); err != nil {
close(c)
return
}
soa, _ := dns.NewRR(`miek.nl. IN SOA elektron.atoom.net. miekg.atoom.net. (
2009032802
21600
7200
604800
3600)`)
c <- &dns.XfrToken{RR: []dns.RR{soa, t, rr, soa}}
close(c)
return
case dns.TypeTXT:
m.Answer = append(m.Answer, t)
m.Extra = append(m.Extra, rr)

View File

@ -26,6 +26,8 @@ type ResponseWriter interface {
Write(*Msg) error
// WriteBuf writes a raw buffer back to the client.
WriteBuf([]byte) error
// Close closes the connection.
Close() error
// TsigStatus returns the status of the Tsig.
TsigStatus() error
// TsigTimersOnly sets the tsig timers only boolean.
@ -303,18 +305,6 @@ func newConn(t *net.TCPConn, u *net.UDPConn, a net.Addr, buf []byte, handler Han
return c, nil
}
// Close the connection.
func (c *conn) close() {
switch {
case c._UDP != nil:
c._UDP.Close()
c._UDP = nil
case c._TCP != nil:
c._TCP.Close()
c._TCP = nil
}
}
// Serve a new connection.
func (c *conn) serve() {
// for block to make it easy to break out to close the tcp connection
@ -349,7 +339,8 @@ func (c *conn) serve() {
break
}
if c._TCP != nil {
c.close() // Listen and Serve is closed then
c._TCP.Close()
c._TCP = nil
}
}
@ -425,3 +416,19 @@ func (w *response) TsigStatus() error { return w.tsigStatus }
// TsigTimersOnly implements the ResponseWriter.TsigTimersOnly method.
func (w *response) TsigTimersOnly(b bool) { w.tsigTimersOnly = b }
// Close implements the ResponseWriter.Close method
func (w *response) Close() error {
if w.conn._UDP != nil {
e := w.conn._UDP.Close()
w.conn._UDP = nil
return e
}
if w.conn._TCP != nil {
e := w.conn._TCP.Close()
w.conn._TCP = nil
return e
}
// no-op
return nil
}

10
xfr.go
View File

@ -145,7 +145,7 @@ func checkXfrSOA(in *Msg, first bool) bool {
// XfrSend performs an outgoing [AI]xfr depending on the request message. The
// caller is responsible for sending the correct sequence of RR sets through
// the channel c.
// the channel c. For reasons of symmetry XfrToken is re-used.
// Errors are signaled via the error pointer, when an error occurs the function
// sets the error and returns (it does not close the channel).
// TSIG and enveloping is handled by XfrSend.
@ -157,7 +157,7 @@ func checkXfrSOA(in *Msg, first bool) bool {
// var e *error
// err := XfrSend(w, q, c, e)
// for _, rrset := range rrsets { // rrset is a []RR
// c <- rrset
// c <- &{XfrToken{RR: rrset}
// if e != nil {
// close(c)
// break
@ -180,15 +180,17 @@ func axfrSend(w ResponseWriter, req *Msg, c chan *XfrToken, e *error) {
rep.SetReply(req)
rep.MsgHdr.Authoritative = true
first := true
for x := range c {
println("got some", len(x.RR))
// assume it fits
rep.Answer = append(rep.Answer, x.RR...)
println(rep.String())
if err := w.Write(rep); e != nil {
*e = err
return
}
w.TsigTimersOnly(first)
w.TsigTimersOnly(true)
rep.Answer = nil
}
w.Close() // Hijack
}