Read/Write works, but axfr still fails
This commit is contained in:
parent
de9a1da6aa
commit
b1f63f57c4
|
@ -37,5 +37,4 @@ func (dns *Msg) SetAxfr(z string, class uint16) {
|
|||
dns.Question = make([]Question, 1)
|
||||
dns.Question[0] = Question{z, TypeAXFR, class}
|
||||
}
|
||||
|
||||
// IsIxfr/IsAxfr?
|
||||
|
|
32
dns.go
32
dns.go
|
@ -51,11 +51,16 @@ func (e *Error) String() string {
|
|||
type Conn struct {
|
||||
// The current UDP connection.
|
||||
UDP *net.UDPConn
|
||||
|
||||
// The current TCP connection.
|
||||
TCP *net.TCPConn
|
||||
|
||||
// The remote side of the connection.
|
||||
Addr net.Addr
|
||||
|
||||
// If TSIG is used, this holds all the information
|
||||
Signature *Tsig
|
||||
|
||||
// Timeout in sec
|
||||
Timeout int
|
||||
|
||||
|
@ -69,16 +74,21 @@ func (d *Conn) Read(p []byte) (n int, err os.Error) {
|
|||
}
|
||||
switch {
|
||||
case d.UDP != nil:
|
||||
n, err = d.UDP.Read(p)
|
||||
var addr net.Addr
|
||||
n, addr, err = d.UDP.ReadFromUDP(p)
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
d.Addr = addr
|
||||
case d.TCP != nil:
|
||||
n, err = d.TCP.Read(p[0:1])
|
||||
if len(p) < 1 {
|
||||
return 0, &Error{Error: "Buffer too small to read"}
|
||||
}
|
||||
n, err = d.TCP.Read(p[0:2])
|
||||
if err != nil || n != 2 {
|
||||
return n, err
|
||||
}
|
||||
l, _ := unpackUint16(p[0:1], 0)
|
||||
l, _ := unpackUint16(p[0:2], 0)
|
||||
if l == 0 {
|
||||
return 0, &Error{Error: "received nil msg length", Server: d.Addr}
|
||||
}
|
||||
|
@ -182,17 +192,15 @@ func (d *Conn) SetTimeout() (err os.Error) {
|
|||
return
|
||||
}
|
||||
|
||||
// Fix those here...!
|
||||
// ReadTsig
|
||||
// WriteTsig
|
||||
|
||||
func (d *Conn) Exchange(request []byte, nosend bool) (reply []byte, err os.Error) {
|
||||
var n int
|
||||
n, err = d.Write(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Layer violation to safe memory. (Its okay then.)
|
||||
if !nosend {
|
||||
n, err = d.Write(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
// Layer violation to save memory. Its okay then...
|
||||
if d.UDP == nil {
|
||||
reply = make([]byte, MaxMsgSize)
|
||||
} else {
|
||||
|
|
5
msg.go
5
msg.go
|
@ -16,7 +16,7 @@ package dns
|
|||
|
||||
import (
|
||||
"os"
|
||||
// "fmt"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"net"
|
||||
"rand"
|
||||
|
@ -210,6 +210,7 @@ func unpackDomainName(msg []byte, off int) (s string, off1 int, ok bool) {
|
|||
Loop:
|
||||
for {
|
||||
if off >= len(msg) {
|
||||
println(off, len(msg))
|
||||
return "", len(msg), false
|
||||
}
|
||||
c := int(msg[off])
|
||||
|
@ -657,7 +658,7 @@ func unpackStructValue(val *reflect.StructValue, msg []byte, off int) (off1 int,
|
|||
case "domain-name":
|
||||
s, off, ok = unpackDomainName(msg, off)
|
||||
if !ok {
|
||||
//fmt.Fprintf(os.Stderr, "dns: failure unpacking domain-name")
|
||||
fmt.Fprintf(os.Stderr, "dns: failure unpacking domain-name")
|
||||
return len(msg), false
|
||||
}
|
||||
case "size-base32":
|
||||
|
|
378
resolver.go
378
resolver.go
|
@ -45,54 +45,40 @@ type Resolver struct {
|
|||
//
|
||||
// Note that message id checking is left to the caller.
|
||||
func (res *Resolver) Query(q *Msg) (d *Msg, err os.Error) {
|
||||
var (
|
||||
c net.Conn
|
||||
port string
|
||||
inb []byte
|
||||
)
|
||||
in := new(Msg)
|
||||
if len(res.Servers) == 0 {
|
||||
return nil, &Error{Error: "No servers defined"}
|
||||
}
|
||||
if res.Rtt == nil {
|
||||
res.Rtt = make(map[string]int64)
|
||||
}
|
||||
if res.Port == "" {
|
||||
port = "53"
|
||||
} else {
|
||||
port = res.Port
|
||||
var c net.Conn
|
||||
var inb []byte
|
||||
in := new(Msg)
|
||||
port, err := check(res, q)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if q.Id == 0 {
|
||||
// No Id sed, set it
|
||||
q.Id = Id()
|
||||
}
|
||||
sending, ok := q.Pack()
|
||||
if !ok {
|
||||
return nil, &Error{Error: ErrPack}
|
||||
}
|
||||
|
||||
for i := 0; i < len(res.Servers); i++ {
|
||||
d := new(Conn)
|
||||
d := new(Conn)
|
||||
server := res.Servers[i] + ":" + port
|
||||
t := time.Nanoseconds()
|
||||
if res.Tcp {
|
||||
c, err = net.Dial("tcp", "", server)
|
||||
d.TCP = c.(*net.TCPConn)
|
||||
d.Addr = d.TCP.RemoteAddr()
|
||||
d.TCP = c.(*net.TCPConn)
|
||||
d.Addr = d.TCP.RemoteAddr()
|
||||
} else {
|
||||
c, err = net.Dial("udp", "", server)
|
||||
d.UDP = c.(*net.UDPConn)
|
||||
d.Addr = d.UDP.RemoteAddr()
|
||||
d.UDP = c.(*net.UDPConn)
|
||||
d.Addr = d.UDP.RemoteAddr()
|
||||
}
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
inb, err = d.Exchange(sending, false)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
in.Unpack(inb)
|
||||
}
|
||||
inb, err = d.Exchange(sending, false)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
in.Unpack(inb)
|
||||
res.Rtt[server] = time.Nanoseconds() - t
|
||||
c.Close()
|
||||
break
|
||||
|
@ -118,22 +104,13 @@ type Xfr struct {
|
|||
func (res *Resolver) Ixfr(q *Msg, m chan Xfr) {
|
||||
// TSIG
|
||||
var (
|
||||
port string
|
||||
x Xfr
|
||||
inb []byte
|
||||
)
|
||||
x Xfr
|
||||
inb []byte
|
||||
)
|
||||
in := new(Msg)
|
||||
if res.Port == "" {
|
||||
port = "53"
|
||||
} else {
|
||||
port = res.Port
|
||||
}
|
||||
if res.Rtt == nil {
|
||||
res.Rtt = make(map[string]int64)
|
||||
}
|
||||
|
||||
if q.Id == 0 {
|
||||
q.Id = Id()
|
||||
port, err := check(res, q)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
defer close(m)
|
||||
|
@ -149,36 +126,37 @@ Server:
|
|||
if err != nil {
|
||||
continue Server
|
||||
}
|
||||
first := true
|
||||
var serial uint32 // The first serial seen is the current server serial
|
||||
d := new(Conn)
|
||||
d.TCP = c.(*net.TCPConn)
|
||||
d.Addr = d.TCP.RemoteAddr()
|
||||
|
||||
first := true
|
||||
defer c.Close()
|
||||
for {
|
||||
if first {
|
||||
inb, err = exchangeTCP(c, sending, res, true)
|
||||
in.Unpack(inb)
|
||||
inb, err = d.Exchange(sending, false)
|
||||
} else {
|
||||
inb, err = exchangeTCP(c, sending, res, false)
|
||||
in.Unpack(inb)
|
||||
inb, err = d.Exchange(sending, true)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
// Failed to send, try the next
|
||||
c.Close()
|
||||
continue Server
|
||||
}
|
||||
|
||||
in.Unpack(inb) // error!
|
||||
if in.Id != q.Id {
|
||||
return
|
||||
}
|
||||
|
||||
if first {
|
||||
// A single SOA RR signals "no changes"
|
||||
if len(in.Answer) == 1 && checkAxfrSOA(in, true) {
|
||||
if len(in.Answer) == 1 && checkXfrSOA(in, true) {
|
||||
return
|
||||
}
|
||||
|
||||
// But still check if the returned answer is ok
|
||||
if !checkAxfrSOA(in, true) {
|
||||
if !checkXfrSOA(in, true) {
|
||||
c.Close()
|
||||
continue Server
|
||||
}
|
||||
|
@ -228,22 +206,11 @@ Server:
|
|||
// the zone as-is. Xfr.Add is always true.
|
||||
// The channel is closed to signal the end of the AXFR.
|
||||
func (res *Resolver) AxfrTSIG(q *Msg, m chan Xfr, secret string) {
|
||||
var (
|
||||
port string
|
||||
inb []byte
|
||||
)
|
||||
var inb []byte
|
||||
in := new(Msg)
|
||||
if res.Port == "" {
|
||||
port = "53"
|
||||
} else {
|
||||
port = res.Port
|
||||
}
|
||||
if res.Rtt == nil {
|
||||
res.Rtt = make(map[string]int64)
|
||||
}
|
||||
|
||||
if q.Id == 0 {
|
||||
q.Id = Id()
|
||||
port, err := check(res, q)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
defer close(m)
|
||||
|
@ -252,14 +219,14 @@ func (res *Resolver) AxfrTSIG(q *Msg, m chan Xfr, secret string) {
|
|||
return
|
||||
}
|
||||
|
||||
var tsig bool
|
||||
var reqmac string
|
||||
var tsig bool
|
||||
var reqmac string
|
||||
// Check if there is a TSIG added to the request msg
|
||||
if len(q.Extra) > 0 {
|
||||
tsig = q.Extra[len(q.Extra)-1].Header().Rrtype == TypeTSIG
|
||||
if tsig {
|
||||
reqmac = q.Extra[len(q.Extra)-1].(*RR_TSIG).MAC
|
||||
}
|
||||
tsig = q.Extra[len(q.Extra)-1].Header().Rrtype == TypeTSIG
|
||||
if tsig {
|
||||
reqmac = q.Extra[len(q.Extra)-1].(*RR_TSIG).MAC
|
||||
}
|
||||
}
|
||||
|
||||
Server:
|
||||
|
@ -269,42 +236,44 @@ Server:
|
|||
if err != nil {
|
||||
continue Server
|
||||
}
|
||||
d := new(Conn)
|
||||
d.TCP = c.(*net.TCPConn)
|
||||
d.Addr = d.TCP.RemoteAddr()
|
||||
|
||||
first := true
|
||||
defer c.Close() // TODO(mg): if not open?
|
||||
for {
|
||||
if first {
|
||||
inb, err = exchangeTCP(c, sending, res, true)
|
||||
in.Unpack(inb)
|
||||
inb, err = d.Exchange(sending, false)
|
||||
} else {
|
||||
inb, err = exchangeTCP(c, sending, res, false)
|
||||
in.Unpack(inb)
|
||||
inb, err = d.Exchange(sending, true)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
// Failed to send, try the next
|
||||
c.Close()
|
||||
continue Server
|
||||
}
|
||||
|
||||
in.Unpack(inb)
|
||||
if in.Id != q.Id {
|
||||
c.Close()
|
||||
return
|
||||
}
|
||||
|
||||
if tsig && len(in.Extra) > 0 { // What if not included?
|
||||
t := in.Extra[len(in.Extra)-1]
|
||||
if t.Header().Rrtype == TypeTSIG {
|
||||
if t.(*RR_TSIG).Verify(inb, secret, reqmac, first) {
|
||||
// Set the MAC for the next round.
|
||||
reqmac = t.(*RR_TSIG).MAC
|
||||
} else {
|
||||
c.Close()
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
if tsig && len(in.Extra) > 0 { // What if not included?
|
||||
t := in.Extra[len(in.Extra)-1]
|
||||
if t.Header().Rrtype == TypeTSIG {
|
||||
if t.(*RR_TSIG).Verify(inb, secret, reqmac, first) {
|
||||
// Set the MAC for the next round.
|
||||
reqmac = t.(*RR_TSIG).MAC
|
||||
} else {
|
||||
c.Close()
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if first {
|
||||
if !checkAxfrSOA(in, true) {
|
||||
if !checkXfrSOA(in, true) {
|
||||
c.Close()
|
||||
continue Server
|
||||
}
|
||||
|
@ -312,12 +281,12 @@ Server:
|
|||
}
|
||||
|
||||
if !first {
|
||||
if !checkAxfrSOA(in, false) {
|
||||
if !checkXfrSOA(in, false) {
|
||||
// Soa record not the last one
|
||||
sendFromMsg(in, m, false)
|
||||
sendMsg(in, m, false)
|
||||
continue
|
||||
} else {
|
||||
sendFromMsg(in, m, true)
|
||||
sendMsg(in, m, true)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -335,23 +304,12 @@ Server:
|
|||
// the zone as-is. Xfr.Add is always true.
|
||||
// The channel is closed to signal the end of the AXFR.
|
||||
func (res *Resolver) Axfr(q *Msg, m chan Xfr) {
|
||||
var (
|
||||
port string
|
||||
inb []byte
|
||||
)
|
||||
var inb []byte
|
||||
port, err := check(res, q)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
in := new(Msg)
|
||||
if res.Port == "" {
|
||||
port = "53"
|
||||
} else {
|
||||
port = res.Port
|
||||
}
|
||||
if res.Rtt == nil {
|
||||
res.Rtt = make(map[string]int64)
|
||||
}
|
||||
|
||||
if q.Id == 0 {
|
||||
q.Id = Id()
|
||||
}
|
||||
|
||||
defer close(m)
|
||||
sending, ok := q.Pack()
|
||||
|
@ -366,29 +324,31 @@ Server:
|
|||
if err != nil {
|
||||
continue Server
|
||||
}
|
||||
d := new(Conn)
|
||||
d.TCP = c.(*net.TCPConn)
|
||||
d.Addr = d.TCP.RemoteAddr()
|
||||
|
||||
first := true
|
||||
defer c.Close() // TODO(mg): if not open?
|
||||
for {
|
||||
if first {
|
||||
inb, err = exchangeTCP(c, sending, res, true)
|
||||
in.Unpack(inb)
|
||||
inb, err = d.Exchange(sending, false)
|
||||
} else {
|
||||
inb, err = exchangeTCP(c, sending, res, false)
|
||||
in.Unpack(inb)
|
||||
inb, err = d.Exchange(sending, true)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
// Failed to send, try the next
|
||||
c.Close()
|
||||
continue Server
|
||||
}
|
||||
if !in.Unpack(inb) {
|
||||
println("Failed to unpack")
|
||||
}
|
||||
if in.Id != q.Id {
|
||||
c.Close()
|
||||
return
|
||||
}
|
||||
|
||||
if first {
|
||||
if !checkAxfrSOA(in, true) {
|
||||
if !checkXfrSOA(in, true) {
|
||||
c.Close()
|
||||
continue Server
|
||||
}
|
||||
|
@ -396,12 +356,12 @@ Server:
|
|||
}
|
||||
|
||||
if !first {
|
||||
if !checkAxfrSOA(in, false) {
|
||||
if !checkXfrSOA(in, false) {
|
||||
// Soa record not the last one
|
||||
sendFromMsg(in, m, false)
|
||||
sendMsg(in, m, false)
|
||||
continue
|
||||
} else {
|
||||
sendFromMsg(in, m, true)
|
||||
sendMsg(in, m, true)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -412,158 +372,10 @@ Server:
|
|||
return
|
||||
}
|
||||
|
||||
// Send a request on the connection and hope for a reply.
|
||||
// Up to res.Attempts attempts. If send is false, nothing
|
||||
// is send.
|
||||
func exchangeUDP(c net.Conn, m []byte, r *Resolver, send bool) ([]byte, os.Error) {
|
||||
var timeout int64
|
||||
var attempts int
|
||||
if r.Mangle != nil {
|
||||
m = r.Mangle(m)
|
||||
}
|
||||
if r.Timeout == 0 {
|
||||
timeout = 1
|
||||
} else {
|
||||
timeout = int64(r.Timeout)
|
||||
}
|
||||
if r.Attempts == 0 {
|
||||
attempts = 1
|
||||
} else {
|
||||
attempts = r.Attempts
|
||||
}
|
||||
for a := 0; a < attempts; a++ {
|
||||
if send {
|
||||
err := sendUDP(m, c)
|
||||
if err != nil {
|
||||
if e, ok := err.(net.Error); ok && e.Timeout() {
|
||||
continue
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
c.SetReadTimeout(timeout * 1e9) // nanoseconds
|
||||
buf, err := recvUDP(c)
|
||||
if err != nil {
|
||||
if e, ok := err.(net.Error); ok && e.Timeout() {
|
||||
continue
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return buf, nil
|
||||
}
|
||||
return nil, &Error{Error: ErrServ}
|
||||
}
|
||||
|
||||
// Up to res.Attempts attempts.
|
||||
func exchangeTCP(c net.Conn, m []byte, r *Resolver, send bool) ([]byte, os.Error) {
|
||||
var timeout int64
|
||||
var attempts int
|
||||
if r.Mangle != nil {
|
||||
m = r.Mangle(m)
|
||||
}
|
||||
if r.Timeout == 0 {
|
||||
timeout = 1
|
||||
} else {
|
||||
timeout = int64(r.Timeout)
|
||||
}
|
||||
if r.Attempts == 0 {
|
||||
attempts = 1
|
||||
} else {
|
||||
attempts = r.Attempts
|
||||
}
|
||||
|
||||
for a := 0; a < attempts; a++ {
|
||||
// only send something when told so
|
||||
if send {
|
||||
err := sendTCP(m, c)
|
||||
if err != nil {
|
||||
if e, ok := err.(net.Error); ok && e.Timeout() {
|
||||
continue
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
c.SetReadTimeout(timeout * 1e9) // nanoseconds
|
||||
// The server replies with two bytes length.
|
||||
buf, err := recvTCP(c)
|
||||
if err != nil {
|
||||
if e, ok := err.(net.Error); ok && e.Timeout() {
|
||||
continue
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return buf, nil
|
||||
}
|
||||
return nil, &Error{Error: ErrServ}
|
||||
}
|
||||
|
||||
func sendUDP(m []byte, c net.Conn) os.Error {
|
||||
_, err := c.Write(m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func recvUDP(c net.Conn) ([]byte, os.Error) {
|
||||
m := make([]byte, DefaultMsgSize)
|
||||
n, err := c.Read(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m = m[:n]
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func sendTCP(m []byte, c net.Conn) os.Error {
|
||||
l := make([]byte, 2)
|
||||
l[0] = byte(len(m) >> 8)
|
||||
l[1] = byte(len(m))
|
||||
// First we send the length
|
||||
_, err := c.Write(l)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// And the the message
|
||||
_, err = c.Write(m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func recvTCP(c net.Conn) ([]byte, os.Error) {
|
||||
l := make([]byte, 2) // The server replies with two bytes length.
|
||||
_, err := c.Read(l)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
length := uint16(l[0])<<8 | uint16(l[1])
|
||||
if length == 0 {
|
||||
return nil, &Error{Error: "received nil msg length", Server: c.RemoteAddr()}
|
||||
}
|
||||
m := make([]byte, length)
|
||||
n, cerr := c.Read(m)
|
||||
if cerr != nil {
|
||||
return nil, cerr
|
||||
}
|
||||
i := n
|
||||
for i < int(length) {
|
||||
n, err = c.Read(m[i:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
i += n
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// Check if he SOA record exists in the Answer section of
|
||||
// the packet. If first is true the first RR must be a soa
|
||||
// if false, the last one should be a SOA
|
||||
func checkAxfrSOA(in *Msg, first bool) bool {
|
||||
func checkXfrSOA(in *Msg, first bool) bool {
|
||||
if len(in.Answer) > 0 {
|
||||
if first {
|
||||
return in.Answer[0].Header().Rrtype == TypeSOA
|
||||
|
@ -575,7 +387,7 @@ func checkAxfrSOA(in *Msg, first bool) bool {
|
|||
}
|
||||
|
||||
// Send the answer section to the channel
|
||||
func sendFromMsg(in *Msg, c chan Xfr, nosoa bool) {
|
||||
func sendMsg(in *Msg, c chan Xfr, nosoa bool) {
|
||||
x := Xfr{Add: true}
|
||||
for k, r := range in.Answer {
|
||||
if nosoa && k == len(in.Answer)-1 {
|
||||
|
@ -585,3 +397,19 @@ func sendFromMsg(in *Msg, c chan Xfr, nosoa bool) {
|
|||
c <- x
|
||||
}
|
||||
}
|
||||
|
||||
// Some assorted checks on the resolver
|
||||
func check(res *Resolver, q *Msg) (port string, err os.Error) {
|
||||
if res.Port == "" {
|
||||
port = "53"
|
||||
} else {
|
||||
port = res.Port
|
||||
}
|
||||
if res.Rtt == nil {
|
||||
res.Rtt = make(map[string]int64)
|
||||
}
|
||||
if q.Id == 0 {
|
||||
q.Id = Id()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
95
server.go
95
server.go
|
@ -11,71 +11,58 @@ import (
|
|||
"net"
|
||||
)
|
||||
|
||||
// Do I want this
|
||||
type Server struct {
|
||||
ServeUDP func(*net.UDPConn, net.Addr, *Msg) os.Error
|
||||
ServeTCP func(*net.TCPConn, net.Addr, *Msg) os.Error
|
||||
/* notify stuff here? */
|
||||
/* tsig here */
|
||||
}
|
||||
// For both -> logging
|
||||
|
||||
func ServeUDP(l *net.UDPConn, f func(*net.UDPConn, net.Addr, *Msg)) os.Error {
|
||||
func ServeUDP(l *net.UDPConn, f func(*Conn, *Msg)) os.Error {
|
||||
for {
|
||||
m := make([]byte, DefaultMsgSize)
|
||||
n, radd, e := l.ReadFromUDP(m)
|
||||
n, addr, e := l.ReadFromUDP(m)
|
||||
if e != nil {
|
||||
continue
|
||||
}
|
||||
m = m[:n]
|
||||
|
||||
d := new(Conn)
|
||||
d.UDP = l
|
||||
d.Addr = addr
|
||||
|
||||
msg := new(Msg)
|
||||
if !msg.Unpack(m) {
|
||||
continue
|
||||
}
|
||||
go f(l, radd, msg)
|
||||
go f(d, msg)
|
||||
}
|
||||
panic("not reached")
|
||||
}
|
||||
|
||||
func ServeTCP(l *net.TCPListener, f func(*net.TCPConn, net.Addr, *Msg)) os.Error {
|
||||
b := make([]byte, 2)
|
||||
func ServeTCP(l *net.TCPListener, f func(*Conn, *Msg)) os.Error {
|
||||
for {
|
||||
c, e := l.AcceptTCP()
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
n, e := c.Read(b)
|
||||
if e != nil {
|
||||
continue
|
||||
}
|
||||
d := new(Conn)
|
||||
d.TCP = c
|
||||
d.Addr = c.RemoteAddr()
|
||||
|
||||
length := uint16(b[0])<<8 | uint16(b[1])
|
||||
if length == 0 {
|
||||
return &Error{Error: "received nil msg length"}
|
||||
}
|
||||
m := make([]byte, length)
|
||||
m := make([]byte, MaxMsgSize) // This may start to hurt someday.
|
||||
n, e := d.Read(m)
|
||||
if e != nil {
|
||||
continue
|
||||
}
|
||||
m = m[:n]
|
||||
|
||||
n, e = c.Read(m)
|
||||
if e != nil {
|
||||
continue
|
||||
}
|
||||
i := n
|
||||
if i < int(length) {
|
||||
n, e = c.Read(m[i:])
|
||||
if e != nil {
|
||||
continue
|
||||
}
|
||||
i += n
|
||||
}
|
||||
msg := new(Msg)
|
||||
if !msg.Unpack(m) {
|
||||
// Logging??
|
||||
continue
|
||||
}
|
||||
go f(c, c.RemoteAddr(), msg)
|
||||
go f(d, msg)
|
||||
}
|
||||
panic("not reached")
|
||||
}
|
||||
|
||||
func ListenAndServeTCP(addr string, f func(*net.TCPConn, net.Addr, *Msg)) os.Error {
|
||||
func ListenAndServeTCP(addr string, f func(*Conn, *Msg)) os.Error {
|
||||
a, err := net.ResolveTCPAddr(addr)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -88,7 +75,7 @@ func ListenAndServeTCP(addr string, f func(*net.TCPConn, net.Addr, *Msg)) os.Err
|
|||
return err
|
||||
}
|
||||
|
||||
func ListenAndServeUDP(addr string, f func(*net.UDPConn, net.Addr, *Msg)) os.Error {
|
||||
func ListenAndServeUDP(addr string, f func(*Conn, *Msg)) os.Error {
|
||||
a, err := net.ResolveUDPAddr(addr)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -100,39 +87,3 @@ func ListenAndServeUDP(addr string, f func(*net.UDPConn, net.Addr, *Msg)) os.Err
|
|||
err = ServeUDP(l, f)
|
||||
return err
|
||||
}
|
||||
|
||||
// Send a buffer on the TCP connection.
|
||||
func SendTCP(m []byte, c *net.TCPConn, a net.Addr) os.Error {
|
||||
l := make([]byte, 2)
|
||||
l[0] = byte(len(m) >> 8)
|
||||
l[1] = byte(len(m))
|
||||
// First we send the length
|
||||
n, err := c.Write(l)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// And the the message
|
||||
n, err = c.Write(m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
i := n
|
||||
for i < len(m) {
|
||||
n, err = c.Write(m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
i += n
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Send a buffer to the remove address. Only here because
|
||||
// of the symmetry with SendTCP().
|
||||
func SendUDP(m []byte, c *net.UDPConn, a net.Addr) os.Error {
|
||||
_, err := c.WriteTo(m, a)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
14
tsig.go
14
tsig.go
|
@ -10,6 +10,19 @@ import (
|
|||
"encoding/hex"
|
||||
)
|
||||
|
||||
type Tsig struct {
|
||||
// The name of the key.
|
||||
Name string
|
||||
Fudge uint16
|
||||
TimeSigned uint64
|
||||
Algorithm string
|
||||
// Tsig secret encoded in base64.
|
||||
Secret string
|
||||
// MAC (if known)
|
||||
MAC string
|
||||
}
|
||||
|
||||
|
||||
// HMAC hashing codes. These are transmitted as domain names.
|
||||
const (
|
||||
HmacMD5 = "hmac-md5.sig-alg.reg.int."
|
||||
|
@ -34,7 +47,6 @@ func (rr *RR_TSIG) Header() *RR_Header {
|
|||
return &rr.Hdr
|
||||
}
|
||||
|
||||
// move to defaults.go?
|
||||
func (rr *RR_TSIG) SetDefaults() {
|
||||
rr.Header().Ttl = 0
|
||||
rr.Header().Class = ClassANY
|
||||
|
|
Loading…
Reference in New Issue