transdep/errors/dns.go
2018-01-23 21:25:00 +01:00

156 lines
3.5 KiB
Go

package errors
import (
"encoding/json"
"fmt"
"github.com/miekg/dns"
"net"
)
const (
UDP_TRANSPORT = 17
TCP_TRANSPORT = 6
)
var PROTO_TO_STR = map[int]string{
TCP_TRANSPORT: "TCP",
UDP_TRANSPORT: "UDP",
}
var STR_TO_PROTO = map[string]int{
"": UDP_TRANSPORT,
"TCP": TCP_TRANSPORT,
"tcp": TCP_TRANSPORT,
"UDP": UDP_TRANSPORT,
"udp": UDP_TRANSPORT,
}
type serializedServfailError struct {
Type string `json:"type"`
Qname string `json:"qname"`
Qtype string `json:"qtype"`
Addr string `json:"ip"`
Proto string `json:"protocol"`
}
type ServfailError struct {
qname string
qtype uint16
addr net.IP
proto int
}
func NewServfailError(qname string, qtype uint16, addr net.IP, proto int) *ServfailError {
se := new(ServfailError)
se.qname = qname
se.qtype = qtype
se.addr = addr
se.proto = proto
return se
}
func (se *ServfailError) MarshalJSON() ([]byte, error) {
sse := new(serializedServfailError)
sse.Type = dns.RcodeToString[dns.RcodeServerFailure]
sse.Qname = se.qname
sse.Qtype = dns.TypeToString[se.qtype]
sse.Addr = se.addr.String()
sse.Proto = PROTO_TO_STR[se.proto]
return json.Marshal(sse)
}
func (se *ServfailError) UnmarshalJSON(bstr []byte) error {
sse := new(serializedServfailError)
if err := json.Unmarshal(bstr, sse); err != nil {
return err
}
se.qname = sse.Qname
se.qtype = dns.StringToType[sse.Qtype]
se.addr = net.ParseIP(sse.Addr)
se.proto = STR_TO_PROTO[sse.Proto]
return nil
}
func (se *ServfailError) Error() string {
return fmt.Sprintf("received a SERVFAIL while trying to query %s %s? from %s with %s", se.qname, dns.TypeToString[se.qtype], se.addr.String(), PROTO_TO_STR[se.proto])
}
type serializedNXDomainError struct {
Type string `json:"type"`
Qname string `json:"qname"`
Qtype string `json:"qtype"`
Addr string `json:"ip"`
Proto string `json:"protocol"`
}
type NXDomainError struct {
qname string
qtype uint16
addr net.IP
proto int
}
func NewNXDomainError(qname string, qtype uint16, addr net.IP, proto int) *NXDomainError {
nx := new(NXDomainError)
nx.qname = qname
nx.qtype = qtype
nx.addr = addr
nx.proto = proto
return nx
}
func (nx *NXDomainError) Error() string {
return fmt.Sprintf("received a NXDomain while trying to query %s %s? from %s with %s", nx.qname, dns.TypeToString[nx.qtype], nx.addr.String(), PROTO_TO_STR[nx.proto])
}
func (nx *NXDomainError) MarshalJSON() ([]byte, error) {
snx := new(serializedNXDomainError)
snx.Type = dns.RcodeToString[dns.RcodeNameError]
snx.Qname = nx.qname
snx.Qtype = dns.TypeToString[nx.qtype]
snx.Addr = nx.addr.String()
snx.Proto = PROTO_TO_STR[nx.proto]
return json.Marshal(snx)
}
func (nx *NXDomainError) UnmarshalJSON(bstr []byte) error {
snx := new(serializedNXDomainError)
if err := json.Unmarshal(bstr, snx); err != nil {
return err
}
nx.qname = snx.Qname
nx.qtype = dns.StringToType[snx.Qtype]
nx.addr = net.ParseIP(snx.Addr)
nx.proto = STR_TO_PROTO[snx.Proto]
return nil
}
type serializedNoNameError struct {
Name string `json:"name"`
}
type NoNameServerError struct {
name string
}
func (ne *NoNameServerError) MarshalJSON() ([]byte, error) {
sne := new(serializedNoNameError)
sne.Name = ne.name
return json.Marshal(sne)
}
func (ne *NoNameServerError) UnmarshalJSON(bstr []byte) error {
sne := new(serializedNoNameError)
if err := json.Unmarshal(bstr, sne); err != nil {
return err
}
ne.name = sne.Name
return nil
}
func NewNoNameServerError(name string) *NoNameServerError {
return &NoNameServerError{name}
}
func (ne *NoNameServerError) Error() string {
return fmt.Sprintf("%s has no nameservers", ne.name)
}