mirror of
https://github.com/miekg/dns.git
synced 2025-10-18 05:11:01 +02:00
fix the multiplexing
This commit is contained in:
parent
428c25a958
commit
241d441371
1
msg.go
1
msg.go
@ -52,7 +52,6 @@ type Msg struct {
|
|||||||
Answer []RR
|
Answer []RR
|
||||||
Ns []RR
|
Ns []RR
|
||||||
Extra []RR
|
Extra []RR
|
||||||
// Error os.Error // Do I want this??
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map of strings for each RR wire type.
|
// Map of strings for each RR wire type.
|
||||||
|
@ -53,7 +53,11 @@ func (res *Resolver) Query(q *Msg) (d *Msg, err os.Error) {
|
|||||||
in *Msg
|
in *Msg
|
||||||
port string
|
port string
|
||||||
)
|
)
|
||||||
|
if len(res.Servers) == 0 {
|
||||||
|
return nil, &Error{Error: "No servers defined"}
|
||||||
|
}
|
||||||
// len(res.Server) == 0 can be perfectly valid, when setting up the resolver
|
// len(res.Server) == 0 can be perfectly valid, when setting up the resolver
|
||||||
|
// It is now
|
||||||
if res.Port == "" {
|
if res.Port == "" {
|
||||||
port = "53"
|
port = "53"
|
||||||
} else {
|
} else {
|
||||||
|
182
server.go
182
server.go
@ -27,9 +27,14 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Server struct {
|
// Wrap request in this struct
|
||||||
// timeout and other stuff
|
type Request struct {
|
||||||
Timeout int
|
Tcp bool // True for tcp, false for udp
|
||||||
|
Buf []byte // The received message
|
||||||
|
Addr net.Addr // Remote site
|
||||||
|
UDPConn *net.UDPConn // Connection for UDP
|
||||||
|
TCPConn *net.TCPConn // Connection for TCP
|
||||||
|
Error os.Error // Any errors that are found
|
||||||
}
|
}
|
||||||
|
|
||||||
// Every nameserver implements the Hander interface. It defines
|
// Every nameserver implements the Hander interface. It defines
|
||||||
@ -44,89 +49,128 @@ type Handler interface {
|
|||||||
// a TCP response. A TCP connection does need to
|
// a TCP response. A TCP connection does need to
|
||||||
// know explicitly be told the remote address. ServeTCP() must
|
// know explicitly be told the remote address. ServeTCP() must
|
||||||
// take care of sending back a response to the requestor.
|
// take care of sending back a response to the requestor.
|
||||||
ReplyTCP(c *net.TCPConn, in []byte)
|
ReplyTCP(c *net.TCPConn, a net.Addr, in []byte)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ServeUDP(l *net.UDPConn, handler Handler) os.Error {
|
func accepterUDP(l *net.UDPConn, ch chan *Request, quit chan bool) {
|
||||||
if handler == nil {
|
|
||||||
// handler == DefaultServer
|
|
||||||
}
|
|
||||||
for {
|
for {
|
||||||
m := make([]byte, DefaultMsgSize) // TODO(mg) out of this loop?
|
select {
|
||||||
n, radd, err := l.ReadFromUDP(m)
|
case <-quit:
|
||||||
if err != nil {
|
return
|
||||||
return err
|
default:
|
||||||
}
|
r := new(Request)
|
||||||
m = m[:n]
|
r.Tcp = false
|
||||||
go handler.ReplyUDP(l, radd, m)
|
m := make([]byte, DefaultMsgSize)
|
||||||
}
|
n, radd, err := l.ReadFromUDP(m)
|
||||||
panic("not reached")
|
|
||||||
}
|
|
||||||
|
|
||||||
func ServeTCP(l *net.TCPListener, handler Handler) os.Error {
|
|
||||||
if handler == nil {
|
|
||||||
// handler = DefaultServer
|
|
||||||
}
|
|
||||||
for {
|
|
||||||
b := make([]byte, 2) // receiver length
|
|
||||||
c, err := l.AcceptTCP()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
n, cerr := c.Read(b)
|
|
||||||
if cerr != nil {
|
|
||||||
return cerr
|
|
||||||
}
|
|
||||||
length := uint16(b[0])<<8 | uint16(b[1])
|
|
||||||
if length == 0 {
|
|
||||||
return &Error{Error: "received nil msg length"}
|
|
||||||
}
|
|
||||||
m := make([]byte, length)
|
|
||||||
|
|
||||||
n, cerr = c.Read(m)
|
|
||||||
if cerr != nil {
|
|
||||||
return cerr
|
|
||||||
}
|
|
||||||
i := n
|
|
||||||
if i < int(length) {
|
|
||||||
n, err = c.Read(m[i:])
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
r.Error = err
|
||||||
|
ch <- r
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
i += n
|
m = m[:n]
|
||||||
|
r.Buf = m
|
||||||
|
r.Addr = radd
|
||||||
|
r.UDPConn = l
|
||||||
|
ch <- r
|
||||||
}
|
}
|
||||||
go handler.ReplyTCP(c, m)
|
}
|
||||||
}
|
panic("not reached")
|
||||||
panic("not reached")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ListenAndServeTCP(addr string, handler Handler) os.Error {
|
func accepterTCP(l *net.TCPListener, ch chan *Request, quit chan bool) {
|
||||||
ta, err := net.ResolveTCPAddr(addr)
|
b := make([]byte, 2)
|
||||||
if err != nil {
|
for {
|
||||||
return err
|
select {
|
||||||
}
|
case <-quit:
|
||||||
l, err := net.ListenTCP("tcp", ta)
|
return
|
||||||
if err != nil {
|
default:
|
||||||
return err
|
r := new(Request)
|
||||||
}
|
r.Tcp = true
|
||||||
err = ServeTCP(l, handler)
|
c, err := l.AcceptTCP()
|
||||||
l.Close()
|
if err != nil {
|
||||||
return err
|
r.Error = err
|
||||||
|
ch <- r
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
n, cerr := c.Read(b)
|
||||||
|
if cerr != nil {
|
||||||
|
r.Error = cerr
|
||||||
|
ch <- r
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
length := uint16(b[0])<<8 | uint16(b[1])
|
||||||
|
if length == 0 {
|
||||||
|
r.Error = &Error{Error: "received nil msg length"}
|
||||||
|
ch <- r
|
||||||
|
}
|
||||||
|
m := make([]byte, length)
|
||||||
|
|
||||||
|
n, cerr = c.Read(m)
|
||||||
|
if cerr != nil {
|
||||||
|
r.Error = cerr
|
||||||
|
ch <- r
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
i := n
|
||||||
|
if i < int(length) {
|
||||||
|
n, err = c.Read(m[i:])
|
||||||
|
if err != nil {
|
||||||
|
r.Error = err
|
||||||
|
ch <- r
|
||||||
|
}
|
||||||
|
i += n
|
||||||
|
}
|
||||||
|
r.Buf = m
|
||||||
|
r.Addr = c.RemoteAddr()
|
||||||
|
r.TCPConn = c
|
||||||
|
ch <- r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
panic("not reached")
|
||||||
}
|
}
|
||||||
|
|
||||||
func ListenAndServeUDP(addr string, handler Handler) os.Error {
|
func ListenAndServe(addr string, handler Handler, q chan bool) os.Error {
|
||||||
|
ta, err := net.ResolveTCPAddr(addr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
lt, err := net.ListenTCP("tcp", ta)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
ua, err := net.ResolveUDPAddr(addr)
|
ua, err := net.ResolveUDPAddr(addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
l, err := net.ListenUDP("udp", ua)
|
lu, err := net.ListenUDP("udp", ua)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = ServeUDP(l, handler)
|
|
||||||
l.Close()
|
rc := make(chan *Request)
|
||||||
return err
|
qt := make(chan bool)
|
||||||
|
qu := make(chan bool)
|
||||||
|
go accepterTCP(lt, rc, qt)
|
||||||
|
go accepterUDP(lu, rc, qu)
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-q:
|
||||||
|
/* quit received, lets stop */
|
||||||
|
lt.Close()
|
||||||
|
lu.Close()
|
||||||
|
qt <- true
|
||||||
|
qu <- true
|
||||||
|
case r:=<-rc:
|
||||||
|
/* request recieved */
|
||||||
|
if r.Tcp {
|
||||||
|
go handler.ReplyTCP(r.TCPConn, r.Addr, r.Buf)
|
||||||
|
} else {
|
||||||
|
go handler.ReplyUDP(r.UDPConn, r.Addr, r.Buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send a buffer on the TCP connection.
|
// Send a buffer on the TCP connection.
|
||||||
|
@ -58,7 +58,7 @@ func TestResponder(t *testing.T) {
|
|||||||
var h *server
|
var h *server
|
||||||
go ListenAndServeTCP("127.0.0.1:8053", h)
|
go ListenAndServeTCP("127.0.0.1:8053", h)
|
||||||
go ListenAndServeUDP("127.0.0.1:8053", h)
|
go ListenAndServeUDP("127.0.0.1:8053", h)
|
||||||
time.Sleep(20 * 1e9)
|
time.Sleep(1 * 1e9)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user