Exemplo n.º 1
0
func respondWithFallback(raw []uint8, clientMsg *dns.Msg, clientQuestion dns.Question, proxy *net.UDPAddr) {
	LOG.Println("fallback:", clientQuestion, proxy)
	conn, err := net.Dial("udp", proxy.String())
	if err != nil {
		LOG.Fatalln(err)
	}

	conn.Write(raw)

	buffer := make([]byte, 1<<15)
	size, err := conn.Read(buffer)
	if err != nil {
		LOG.Fatalln(err, proxy)
	}

	msg := &dns.Msg{}
	msg.Unpack(buffer[0:size])

	LOG.Println(msg)

	for _, answer := range msg.Answer {
		clientMsg.Answer = append(clientMsg.Answer, answer)
	}

	clientMsg.Rcode = msg.Rcode
	clientMsg.Response = msg.Response
	clientMsg.Authoritative = msg.Authoritative
	clientMsg.Recursion_desired = msg.Recursion_desired
	clientMsg.Recursion_available = msg.Recursion_available
}
Exemplo n.º 2
0
func answerAAAA(msg *dns.Msg, question dns.Question, name []string, value NMCValue) {
	var parsedIp net.IP
	// len == 1 means root domain: check "ip" and "map".""
	if len(name) == 1 {
		vips := value.Ip6

		if len(vips) == 0 {
			// can't answer, make an error here.
			return
		} else {
			parsedIp = net.ParseIP(vips[0])
		}
	}

	ip := parsedIp.To16()
	if ip == nil {
		return
	}

	LOG.Println("AAAA", name, "=>", ip)

	rraaaa := &dns.RR_AAAA{}
	copy(ip, rraaaa.AAAA[:])

	rrh := &dns.RR_Header{
		Name:     question.Name,
		Rrtype:   dns.TypeAAAA,
		Class:    dns.ClassINET,
		Ttl:      60,
		Rdlength: 100,
	}
	rraaaa.Hdr = *rrh

	msg.Rcode = dns.RcodeSuccess
	msg.Answer = append(msg.Answer, rraaaa)
	msg.Response = true
	msg.Authoritative = true
	msg.Recursion_desired = true
	msg.Recursion_available = true
}
Exemplo n.º 3
0
func answerA(msg *dns.Msg, question dns.Question, name []string, value NMCValue) {
	var parsedIp net.IP
	// len == 1 means root domain: check "ip" and "map".""
	if len(name) == 1 {
		vips := value.Ip

		// this is legacy support
		if len(vips) == 0 {
			vmap := value.Map
			if vmap == nil {
				return
			}

			vmip, ok := value.Map[""]
			if !ok && vmip == "" {
				// can't answer, make an error here.
				return
			}

			switch vmip.(type) {
			case nil:
				return
			case map[string]interface{}:
				nsAvailable := vmip.(map[string]interface{})["ns"]

				switch nsAvailable.(type) {
				case []interface{}:
					ns := nsAvailable.([]interface{})[0]

					switch ns.(type) {
					case string:
						h := dns.MsgHdr{
							Id:                uint16(rand.Int()) ^ uint16(time.Nanoseconds()),
							Recursion_desired: true,
						}

						q := &dns.Question{
							Name:   question.Name,
							Qtype:  dns.TypeA,
							Qclass: dns.ClassINET,
						}

						m := &dns.Msg{}
						m.MsgHdr = h
						m.Question = append(m.Question, *q)

						LOG.Println(m)

						out, ok := m.Pack()
						if !ok {
							LOG.Fatalln("Failed to Pack:", msg)
						}

						nsaddr := ns.(string) + ":53"
						conn, err := net.Dial("udp", nsaddr)
						if err != nil {
							LOG.Fatalf("net.DialUDP(\"udp\", nil, %v) => %v", nsaddr, err)
						}
						LOG.Println("out:", out)

						n, err := conn.Write(out)
						if err != nil {
							LOG.Fatalln(err)
						}
						LOG.Println("wrote:", n)

						conn.SetReadTimeout(10e9)
						defer conn.Close()

						b := make([]byte, 1<<15)
						s, err := conn.Read(b)
						if err != nil {
							LOG.Fatalln(err, nsaddr)
						}

						err = conn.Close()
						if err != nil {
							LOG.Fatalln(err)
						}

						a := &dns.Msg{}
						a.Unpack(b[0:s])

						LOG.Println("a:", a)

						msg.Answer = append(msg.Answer, a.Answer[0])
						return
					default:
						LOG.Printf("can't find the type of: %#v", ns)
					}
				default:
					LOG.Printf("can't find the type of: %#v", nsAvailable)
				}
			case string:
				parsedIp = net.ParseIP(vmip.(string))
			default:
				LOG.Printf("can't find the type of: %#v", vmip)
			}

		} else {
			parsedIp = net.ParseIP(vips[0])
		}
	}

	ip := parsedIp.To4()
	if ip == nil {
		return
	}

	LOG.Println("A", name, "=>", ip)

	var a uint32
	rra := &dns.RR_A{}
	rra.A = (a | uint32(ip[0])<<24 | uint32(ip[1])<<16 | uint32(ip[2])<<8 | uint32(ip[3]))

	rrh := &dns.RR_Header{
		Name:     question.Name,
		Rrtype:   dns.TypeA,
		Class:    dns.ClassINET,
		Ttl:      60,
		Rdlength: 100,
	}
	rra.Hdr = *rrh

	msg.Rcode = dns.RcodeSuccess
	msg.Answer = append(msg.Answer, rra)
	msg.Response = true
	msg.Authoritative = true
	msg.Recursion_desired = true
	msg.Recursion_available = true
}