completely break the api

This commit is contained in:
Miek Gieben 2011-04-02 09:22:05 +02:00
parent 751a50b4b6
commit 172331a23f
2 changed files with 205 additions and 12 deletions

1
dns.go
View File

@ -95,6 +95,7 @@ func (e *Error) String() string {
return e.Error
}
// OLD
// A Conn is the lowest primative in the dns package.
// A Conn holds both the UDP and TCP connection, but only one
// can be active any given time.

216
server.go
View File

@ -7,6 +7,7 @@
package dns
import (
"io"
"os"
"net"
)
@ -15,11 +16,33 @@ type Handler interface {
ServeDNS(w ResponseWriter, r *Msg)
}
// Handle register the handler the given pattern
// in the DefaultServeMux. The documentation for
// ServeMux explains how patters are matched.
func Handle(pattern string, handler Hander) {
// You can ofcourse make YOUR OWN RESPONSE WRITTER that
// uses TSIG an other cool stuff
type ResponseWriter interface {
// RemoteAddr returns the address of the client that sent the current request
RemoteAddr() string
Write([]byte) (int, os.Error)
// IP based ACL mapping. The contains the string representation
// of the IP address and a boolean saying it may connect (true) or not.
Acl() map[string]bool
// Tsig secrets. Its a mapping of key names to secrets.
Tsig() map[string]string
}
type conn struct {
remoteAddr net.Addr // address of remote side (sans port)
handler Handler // request handler
request []byte // bytes read
connUDP *net.UDPConn
connTCP *net.TCPConn
}
type response struct {
conn *conn
req *Msg
}
// ServeMux is an DNS request multiplexer. It matches the
@ -30,20 +53,34 @@ type ServeMux struct {
m map[string]Handler
}
func NewServeMux() *ServeMux {
// NewServeMux allocates and returns a new ServeMux.
func NewServeMux() *ServeMux { return &ServeMux{make(map[string]Handler)} }
// DefaultServeMux is the default ServeMux used by Serve.
var DefaultServeMux = NewServeMux()
// The HandlerFunc type is an adapter to allow the use of
// ordinary functions as DNS handlers. If f is a function
// with the appropriate signature, HandlerFunc(f) is a
// Handler object that calls f.
type HandlerFunc func(ResponseWriter, *Msg)
// ServerDNS calls f(w, reg)
func (f HandlerFunc) ServeDNS(w ResponseWriter, r *Msg) {
f(w, r)
}
func (mux *ServeMux) Handle(pattern string, handler Handler) {
// Helper handlers
}
// Error replies to the request with the specified error msg TODO(mg)
/*
func Error(w ResponseWriter) { }
// ServeDNS dispatches the request to the handler whose
// pattern most closely matches the request message.
func (mux *ServeMux) ServeDNS(w ReponseWriter, request *Msg) {
func NotFound(w ResponseWriter, r *Msg) {
func NotFoundHandler() Handler { return HandlerFunc(NotFound) }
*/
}
// HandleUDP handles one UDP connection. It reads the incoming
// message and then calls the function f.
@ -96,6 +133,12 @@ func HandleTCP(l *net.TCPListener, f func(*Conn, *Msg)) os.Error {
panic("not reached")
}
func ListenAndServe(addr string, network string, handler Handler) os.Error {
server := &Server{Addr: addr, Network: network, Handler: handler}
return server.ListenAndServe()
}
// 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.
@ -135,7 +178,7 @@ func ListenAndServeUDP(addr string, f func(*Conn, *Msg)) os.Error {
}
func zoneMatch(pattern, zone string) bool {
if len(patter) == 0 {
if len(pattern) == 0 {
return false
}
n := len(pattern)
@ -163,3 +206,152 @@ func (mux *ServeMux) Handle(pattern string, handler Handler) {
}
mux.m[pattern] = handler
}
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Msg)) {
mux.Handle(pattern, HandlerFunc(handler))
}
// ServeDNS dispatches the request to the handler whose
// pattern most closely matches the request message.
func (mux *ServeMux) ServeDNS(w ResponseWriter, request *Msg) {
h := mux.match(request.Question[0].Name)
if h == nil {
// h = NotFoundHandler()
}
h.ServeDNS(w, request)
}
// Handle register the handler the given pattern
// in the DefaultServeMux. The documentation for
// ServeMux explains how patters are matched.
func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) }
func HandleFunc(pattern string, handler func(ResponseWriter, *Msg)) {
DefaultServeMux.HandleFunc(pattern, handler)
}
// Serve accepts incoming DNS request on the listener l,
// creating a new service thread for each. The service threads
// read requests and then call handler to reply to them.
// Handler is typically nil, in which case the DefaultServeMux is used.
func Serve(l net.Listener, handler Handler) os.Error {
srv := &Server{Handler: handler}
return srv.Serve(l)
}
// A Server defines parameters for running an HTTP server.
type Server struct {
Addr string // address to listen on, ":dns" if empty
Network string // If "tcp" it will invoke a TCP listener, otherwise an UDP one
Handler Handler // handler to invoke, http.DefaultServeMux if nil
ReadTimeout int64 // the net.Conn.SetReadTimeout value for new connections
WriteTimeout int64 // the net.Conn.SetWriteTimeout value for new connections
}
// Fixes for udp/tcp
func (srv *Server) ListenAndServe() os.Error {
addr := srv.Addr
if addr == "" {
addr = ":domain"
}
switch srv.Network {
case "tcp":
a, e := net.ResolveTCPAddr(addr)
if e != nil {
return e
}
l, e := net.ListenTCP("tcp", a)
if e != nil {
return e
}
return srv.ServeTCP(l)
case "udp":
a, e := net.ResolveUDPAddr(addr)
if e != nil {
return e
}
l, e := net.ListenUDP("udp", a)
if e != nil {
return e
}
return srv.ServeUDP(l)
}
return nil // os.Error with wrong network
}
func (srv *Server) ServeTCP(l *net.TCPListener) os.Error {
defer l.Close()
handler := srv.Handler
if handler == nil {
handler = DefaultServeMux
}
for {
rw, e := l.AcceptTCP()
if e != nil {
return e
}
if srv.ReadTimeout != 0 {
rw.SetReadTimeout(srv.ReadTimeout)
}
if srv.WriteTimeout != 0 {
rw.SetWriteTimeout(srv.WriteTimeout)
}
m := read /* read and set the buffer */
d, err := newConn(rw, nil, rw.RemoteAddr(), nil, handler)
d.ReadReqest()
if err != nil {
continue
}
go d.serve()
}
panic("not reached")
}
func (srv *Server) ServeUDP(l *net.UDPConn) os.Error {
defer l.Close()
handler := srv.Handler
if handler == nil {
handler = DefaultServeMux
}
for {
m := make([]byte, DefaultMsgSize)
c, a, e := l.ReadFromUDP()
if e != nil {
return e
}
m = m[:n]
if srv.ReadTimeout != 0 {
rw.SetReadTimeout(srv.ReadTimeout)
}
if srv.WriteTimeout != 0 {
rw.SetWriteTimeout(srv.WriteTimeout)
}
d, err := newConn(rw, nil, addr, m, handler)
if err != nil {
continue
}
go d.serve()
}
panic("not reached")
}
func newConn(t *net.TCPConn, u *net.UDPConn, a net.Addr, buf []byte, handler Handler) (c *conn, err os.Error) {
c = new(conn)
c.handler = handler
c.TCPconn = t
c.UDPconn = u
c.RemoteAddr = a
return c, err
}
func (c *conn) serve() {
// c.ReadRequest
// c.Handler.ServeDNS(w, w.req) // this does the writing
}
func (c *conn) ReadRequest() (w *response, err os.Error) {
w = new(response)
return w, nil
}