2011-02-08 20:25:01 +00:00
|
|
|
// Copyright 2011 Miek Gieben. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
// DNS server implementation
|
|
|
|
|
2011-02-08 20:26:40 +00:00
|
|
|
package dns
|
2011-02-08 20:25:01 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"os"
|
|
|
|
"net"
|
|
|
|
)
|
|
|
|
|
2011-03-23 18:37:07 +00:00
|
|
|
// HandleUDP handles one UDP connection. It reads the incoming
|
|
|
|
// message and then calls the function f.
|
2011-03-24 08:24:24 +00:00
|
|
|
// The function f is executed in a seperate goroutine at which point
|
|
|
|
// HandleUDP returns.
|
2011-03-21 21:53:15 +00:00
|
|
|
func HandleUDP(l *net.UDPConn, f func(*Conn, *Msg)) os.Error {
|
2011-02-08 20:25:01 +00:00
|
|
|
for {
|
2011-03-15 22:12:20 +00:00
|
|
|
m := make([]byte, DefaultMsgSize)
|
2011-03-20 18:58:55 +00:00
|
|
|
n, addr, e := l.ReadFromUDP(m)
|
2011-03-15 22:12:20 +00:00
|
|
|
if e != nil {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
m = m[:n]
|
2011-03-20 18:58:55 +00:00
|
|
|
|
2011-03-24 08:24:24 +00:00
|
|
|
d := new(Conn)
|
2011-03-27 09:52:37 +00:00
|
|
|
// Use the remote addr as we got from ReadFromUDP
|
2011-03-27 09:45:01 +00:00
|
|
|
d.SetUDPConn(l, addr)
|
2011-03-20 18:58:55 +00:00
|
|
|
|
2011-03-15 22:12:20 +00:00
|
|
|
msg := new(Msg)
|
|
|
|
if !msg.Unpack(m) {
|
|
|
|
continue
|
|
|
|
}
|
2011-03-20 18:58:55 +00:00
|
|
|
go f(d, msg)
|
2011-02-08 20:25:01 +00:00
|
|
|
}
|
2011-02-09 16:59:06 +00:00
|
|
|
panic("not reached")
|
2011-02-08 20:25:01 +00:00
|
|
|
}
|
|
|
|
|
2011-03-23 18:37:07 +00:00
|
|
|
// HandleTCP handles one TCP connection. It reads the incoming
|
|
|
|
// message and then calls the function f.
|
2011-03-24 08:24:24 +00:00
|
|
|
// The function f is executed in a seperate goroutine at which point
|
|
|
|
// HandleTCP returns.
|
2011-03-21 21:53:15 +00:00
|
|
|
func HandleTCP(l *net.TCPListener, f func(*Conn, *Msg)) os.Error {
|
2011-02-09 16:59:06 +00:00
|
|
|
for {
|
2011-03-15 22:12:20 +00:00
|
|
|
c, e := l.AcceptTCP()
|
|
|
|
if e != nil {
|
|
|
|
return e
|
|
|
|
}
|
2011-03-24 08:24:24 +00:00
|
|
|
d := new(Conn)
|
2011-03-27 09:45:01 +00:00
|
|
|
d.SetTCPConn(c, nil)
|
2011-02-08 20:25:01 +00:00
|
|
|
|
2011-03-15 22:12:20 +00:00
|
|
|
msg := new(Msg)
|
2011-03-24 08:24:24 +00:00
|
|
|
err := d.ReadMsg(msg)
|
2011-03-23 15:10:15 +00:00
|
|
|
|
|
|
|
if err != nil {
|
2011-03-24 08:24:24 +00:00
|
|
|
// Logging??
|
2011-03-15 22:12:20 +00:00
|
|
|
continue
|
|
|
|
}
|
2011-03-20 18:58:55 +00:00
|
|
|
go f(d, msg)
|
2011-02-09 16:59:06 +00:00
|
|
|
}
|
|
|
|
panic("not reached")
|
2011-02-08 20:25:01 +00:00
|
|
|
}
|
|
|
|
|
2011-03-23 18:37:07 +00:00
|
|
|
// ListenAndServerTCP listens on the TCP network address addr and
|
|
|
|
// then calls HandleTCP with f to handle requests on incoming
|
|
|
|
// connections. The function f may not be nil.
|
2011-03-20 18:58:55 +00:00
|
|
|
func ListenAndServeTCP(addr string, f func(*Conn, *Msg)) os.Error {
|
2011-03-24 08:24:24 +00:00
|
|
|
if f == nil {
|
|
|
|
return &Error{Error: "The handle function may not be nil"}
|
|
|
|
}
|
2011-02-11 19:29:04 +00:00
|
|
|
a, err := net.ResolveTCPAddr(addr)
|
2011-02-09 16:59:06 +00:00
|
|
|
if err != nil {
|
2011-02-11 19:29:04 +00:00
|
|
|
return err
|
2011-02-09 16:59:06 +00:00
|
|
|
}
|
2011-02-11 19:29:04 +00:00
|
|
|
l, err := net.ListenTCP("tcp", a)
|
2011-02-09 16:59:06 +00:00
|
|
|
if err != nil {
|
2011-02-11 19:29:04 +00:00
|
|
|
return err
|
2011-02-09 16:59:06 +00:00
|
|
|
}
|
2011-03-21 21:53:15 +00:00
|
|
|
err = HandleTCP(l, f)
|
2011-02-11 19:29:04 +00:00
|
|
|
return err
|
|
|
|
}
|
2011-02-08 20:25:01 +00:00
|
|
|
|
2011-03-23 18:37:07 +00:00
|
|
|
// ListenAndServerUDP listens on the UDP network address addr and
|
|
|
|
// then calls HandleUDP with f to handle requests on incoming
|
|
|
|
// connections. The function f may not be nil.
|
2011-03-20 18:58:55 +00:00
|
|
|
func ListenAndServeUDP(addr string, f func(*Conn, *Msg)) os.Error {
|
2011-03-24 08:24:24 +00:00
|
|
|
if f == nil {
|
|
|
|
return &Error{Error: "The handle function may not be nil"}
|
|
|
|
}
|
2011-02-11 19:29:04 +00:00
|
|
|
a, err := net.ResolveUDPAddr(addr)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2011-02-11 20:29:40 +00:00
|
|
|
l, err := net.ListenUDP("udp", a)
|
2011-02-11 19:29:04 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2011-03-21 21:53:15 +00:00
|
|
|
err = HandleUDP(l, f)
|
2011-02-11 19:29:04 +00:00
|
|
|
return err
|
2011-02-08 20:25:01 +00:00
|
|
|
}
|