dns/server.go

131 lines
2.8 KiB
Go
Raw Normal View History

2011-02-09 07:25:01 +11: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
package dns
2011-02-09 07:25:01 +11:00
import (
"os"
"net"
)
2011-02-12 06:54:54 +11:00
func ServeUDP(l *net.UDPConn, f func(*net.UDPConn, net.Addr, *Msg)) os.Error {
2011-02-09 07:25:01 +11:00
for {
2011-02-12 06:29:04 +11:00
m := make([]byte, DefaultMsgSize)
n, radd, e := l.ReadFromUDP(m)
if e != nil {
continue
}
m = m[:n]
2011-02-12 06:54:54 +11:00
msg := new(Msg)
if ! msg.Unpack(m) {
continue
}
go f(l, radd, msg)
2011-02-09 07:25:01 +11:00
}
2011-02-10 03:59:06 +11:00
panic("not reached")
2011-02-09 07:25:01 +11:00
}
2011-02-12 06:54:54 +11:00
func ServeTCP(l *net.TCPListener, f func(*net.TCPConn, net.Addr, *Msg)) os.Error {
2011-02-10 03:59:06 +11:00
b := make([]byte, 2)
for {
2011-02-12 06:29:04 +11:00
c, e := l.AcceptTCP()
if e != nil {
return e
}
n, e := c.Read(b)
if e != nil {
continue
}
2011-02-09 07:25:01 +11:00
2011-02-12 06:29:04 +11:00
length := uint16(b[0])<<8 | uint16(b[1])
if length == 0 {
return &Error{Error: "received nil msg length"}
}
m := make([]byte, length)
2011-02-09 07:25:01 +11:00
2011-02-12 06:29:04 +11:00
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
2011-02-09 07:25:01 +11:00
}
2011-02-12 06:29:04 +11:00
i += n
2011-02-09 07:25:01 +11:00
}
2011-02-12 06:54:54 +11:00
msg := new(Msg)
if ! msg.Unpack(m) {
continue
}
go f(c, c.RemoteAddr(), msg)
2011-02-10 03:59:06 +11:00
}
panic("not reached")
2011-02-09 07:25:01 +11:00
}
2011-02-12 06:54:54 +11:00
func ListenAndServeTCP(addr string, f func(*net.TCPConn, net.Addr, *Msg)) os.Error {
2011-02-12 06:29:04 +11:00
a, err := net.ResolveTCPAddr(addr)
2011-02-10 03:59:06 +11:00
if err != nil {
2011-02-12 06:29:04 +11:00
return err
2011-02-10 03:59:06 +11:00
}
2011-02-12 06:29:04 +11:00
l, err := net.ListenTCP("tcp", a)
2011-02-10 03:59:06 +11:00
if err != nil {
2011-02-12 06:29:04 +11:00
return err
2011-02-10 03:59:06 +11:00
}
2011-02-12 06:29:04 +11:00
err = ServeTCP(l, f)
return err
}
2011-02-09 07:25:01 +11:00
2011-02-12 06:54:54 +11:00
func ListenAndServeUDP(addr string, f func(*net.UDPConn, net.Addr, *Msg)) os.Error {
2011-02-12 06:29:04 +11:00
a, err := net.ResolveUDPAddr(addr)
if err != nil {
return err
}
2011-02-12 07:29:40 +11:00
l, err := net.ListenUDP("udp", a)
2011-02-12 06:29:04 +11:00
if err != nil {
return err
}
err = ServeUDP(l, f)
return err
2011-02-09 07:25:01 +11:00
}
// Send a buffer on the TCP connection.
func SendTCP(m []byte, c *net.TCPConn, a net.Addr) os.Error {
2011-02-09 07:25:01 +11:00
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)
2011-02-09 07:25:01 +11:00
if err != nil {
return err
}
// And the the message
n, err = c.Write(m)
2011-02-09 07:25:01 +11:00
if err != nil {
return err
}
i := n
for i < len(m) {
n, err = c.Write(m)
if err != nil {
return err
}
i += n
}
2011-02-09 07:25:01 +11:00
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
}