// recv is used to receive until we get a shutdown func (c *client) recv(l *net.UDPConn, msgCh chan *dns.Msg) { if l == nil { return } buf := make([]byte, 65536) var closed bool for { c.closeLock.RLock() closed = c.closed c.closeLock.RUnlock() if closed { break } n, err := l.Read(buf) if err != nil { Log.Printf("[ERR] mdns: Failed to read packet: %v", err) continue } msg := new(dns.Msg) if err := msg.Unpack(buf[:n]); err != nil { Log.Printf("[ERR] mdns: Failed to unpack packet: %v", err) continue } select { case msgCh <- msg: case <-c.closedCh: return } } }
func ParseDnsFrame(f Frame, req *dns.Msg) (addrs []net.IP, err error) { ft, ok := f.(*FrameDns) if !ok { return nil, ErrDnsMsgIllegal } res := new(dns.Msg) err = res.Unpack(ft.Data) if err != nil || !res.Response || res.Id != req.Id { return nil, ErrDnsMsgIllegal } if DEBUGDNS { DebugDNS(res, req.Question[0].Name) } for _, a := range res.Answer { switch ta := a.(type) { case *dns.A: addrs = append(addrs, ta.A) case *dns.AAAA: addrs = append(addrs, ta.AAAA) } } return }
func TestTCP(t *testing.T) { handle, err := pcap.OpenOffline("tcptest.pcap") if err != nil { panic(err) } packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) defer handle.Close() tcpPack := make(chan gopacket.Packet, 10) nomalPack := make(chan gopacket.Packet, 5) for input_pack := range packetSource.Packets() { // send tcp package for channel tcpLayer := input_pack.Layer(layers.LayerTypeTCP) if tcpLayer != nil { tcpPack <- input_pack // send packet to tcp ASSEMBLER } } streamFactory := &DNSStreamFactory{normal: nomalPack} streamPool := tcpassembly.NewStreamPool(streamFactory) assembler := tcpassembly.NewAssembler(streamPool) go tcpAssemble(tcpPack, assembler) pack := <-nomalPack udpLayer := pack.Layer(layers.LayerTypeUDP) if udpLayer == nil { t.Errorf("can not fine udp Layer in result") } dns_message := new(dns.Msg) err = dns_message.Unpack(udpLayer.LayerPayload()) if err != nil { t.Errorf("can not parse dns message") } fmt.Printf(dns_message.String()) }
// parsePacket is used to parse an incoming packet func (s *Server) parsePacket(packet []byte, from net.Addr) error { var msg dns.Msg if err := msg.Unpack(packet); err != nil { log.Printf("[ERR] bonjour: Failed to unpack packet: %v", err) return err } return s.handleQuery(&msg, from) }
func dnsQueryRaw(r []byte) ([]byte, error) { req := new(dns.Msg) req.Unpack(r) res, err := dnsQuery(req) if nil != err { return nil, err } return res.Pack() }
func safeParse(msg *dns.Msg, data []byte) (err error) { defer func() { if e := recover(); e != nil { fmt.Fprintf(os.Stderr, "Crashed dns: %v\nError: %v\n", hex.EncodeToString(data), e) err = fmt.Errorf("bad packet") } }() return msg.Unpack(data) }
func TestRFC2136ValidUpdatePacket(t *testing.T) { dns.HandleFunc(rfc2136TestZone, serverHandlerPassBackRequest) defer dns.HandleRemove(rfc2136TestZone) server, addrstr, err := runLocalDNSTestServer("127.0.0.1:0", false) if err != nil { t.Fatalf("Failed to start test server: %v", err) } defer server.Shutdown() rr := new(dns.TXT) rr.Hdr = dns.RR_Header{ Name: rfc2136TestFqdn, Rrtype: dns.TypeTXT, Class: dns.ClassINET, Ttl: uint32(rfc2136TestTTL), } rr.Txt = []string{rfc2136TestValue} rrs := make([]dns.RR, 1) rrs[0] = rr m := new(dns.Msg) m.SetUpdate(dns.Fqdn(rfc2136TestZone)) m.Insert(rrs) expectstr := m.String() expect, err := m.Pack() if err != nil { t.Fatalf("Error packing expect msg: %v", err) } provider, err := NewDNSProviderRFC2136(addrstr, rfc2136TestZone, "", "") if err != nil { t.Fatalf("Expected NewDNSProviderRFC2136() to return no error but the error was -> %v", err) } if err := provider.Present(rfc2136TestDomain, "", "1234d=="); err != nil { t.Errorf("Expected Present() to return no error but the error was -> %v", err) } rcvMsg := <-reqChan rcvMsg.Id = m.Id actual, err := rcvMsg.Pack() if err != nil { t.Fatalf("Error packing actual msg: %v", err) } if !bytes.Equal(actual, expect) { tmp := new(dns.Msg) if err := tmp.Unpack(actual); err != nil { t.Fatalf("Error unpacking actual msg: %v", err) } t.Errorf("Expected msg:\n%s", expectstr) t.Errorf("Actual msg:\n%v", tmp) } }
func safeParse(msg *dns.Msg, data []byte) (err error) { defer func() { if e := recover(); e != nil { hexs := hex.EncodeToString(data) fmt.Fprintf(os.Stderr, "Crashed dns: %v\nError: %v\n", hexs, e) panic("Unpacking dns crashed: " + hexs) } }() return msg.Unpack(data) }
// consume an mdns packet from the wire and decode it func (c *connector) readMessage() (*dns.Msg, *net.UDPAddr, error) { buf := make([]byte, 1500) read, addr, err := c.ReadFromUDP(buf) if err != nil { return nil, nil, err } var msg dns.Msg if err := msg.Unpack(buf[:read]); err != nil { return nil, nil, err } return &msg, addr, nil }
func (conn *DNSUDPConn) ReadDNSFromUDP() (*dns.Msg, *net.UDPAddr, error) { buf := make([]byte, DNS_MAX_UDP_SIZE) rdlen, addr, err := conn.ReadFromUDP(buf) if rdlen == 0 || err != nil { return nil, nil, fmt.Errorf("Error reading from UDP: %v", err) } m := new(dns.Msg) if err = m.Unpack(buf[:rdlen]); err != nil { return nil, nil, err } return m, addr, nil }
// A loop that reads incoming mDNS questions from UDP connection // and passes them into the main loop question channel func (m *mdns) readloop(c *net.UDPConn, in chan msg) { buf := make([]byte, 1500) for { if n, addr, err := c.ReadFromUDP(buf); err != nil { return } else { var dnsmsg dns.Msg if err := dnsmsg.Unpack(buf[:n]); err == nil { in <- msg{&dnsmsg, addr, c} } } } }
func (c *Client) readUDP() (*net.UDPAddr, *dns.Msg, error) { in := make([]byte, dns.DefaultMsgSize) read, addr, err := c.conn.ReadFromUDP(in) if err != nil { return nil, nil, err } var readMsg dns.Msg if err := readMsg.Unpack(in[:read]); err != nil { return nil, nil, err } return addr, &readMsg, nil }
func TestRFC2136ValidUpdatePacket(t *testing.T) { acme.ClearFqdnCache() dns.HandleFunc(rfc2136TestZone, serverHandlerPassBackRequest) defer dns.HandleRemove(rfc2136TestZone) server, addrstr, err := runLocalDNSTestServer("127.0.0.1:0", false) if err != nil { t.Fatalf("Failed to start test server: %v", err) } defer server.Shutdown() txtRR, _ := dns.NewRR(fmt.Sprintf("%s %d IN TXT %s", rfc2136TestFqdn, rfc2136TestTTL, rfc2136TestValue)) rrs := []dns.RR{txtRR} m := new(dns.Msg) m.SetUpdate(rfc2136TestZone) m.RemoveRRset(rrs) m.Insert(rrs) expectstr := m.String() expect, err := m.Pack() if err != nil { t.Fatalf("Error packing expect msg: %v", err) } provider, err := NewDNSProvider(addrstr, "", "", "") if err != nil { t.Fatalf("Expected NewDNSProvider() to return no error but the error was -> %v", err) } if err := provider.Present(rfc2136TestDomain, "", "1234d=="); err != nil { t.Errorf("Expected Present() to return no error but the error was -> %v", err) } rcvMsg := <-reqChan rcvMsg.Id = m.Id actual, err := rcvMsg.Pack() if err != nil { t.Fatalf("Error packing actual msg: %v", err) } if !bytes.Equal(actual, expect) { tmp := new(dns.Msg) if err := tmp.Unpack(actual); err != nil { t.Fatalf("Error unpacking actual msg: %v", err) } t.Errorf("Expected msg:\n%s", expectstr) t.Errorf("Actual msg:\n%v", tmp) } }
func (this *cache) Get(message *dns.Msg) (bool, *dns.Msg, error) { cachedMessage := CacheRecord{} err := this.collection.GetObject(message.Question[0].Name, &cachedMessage) if err != nil { return false, nil, err } cachedMessageMsg := dns.Msg{} err = cachedMessageMsg.Unpack(cachedMessage.Record) if err != nil { return false, nil, err } if cachedMessageMsg.Id != 0 && cachedMessage.Expiry.After(time.Now()) { return true, &cachedMessageMsg, nil } else { return false, &dns.Msg{}, nil } }
// @Private func (this *UDPNameServer) HandleResponse(dest v2net.Destination, payload *alloc.Buffer) { msg := new(dns.Msg) err := msg.Unpack(payload.Value) if err != nil { log.Warning("DNS: Failed to parse DNS response: ", err) return } record := &ARecord{ IPs: make([]net.IP, 0, 16), } id := msg.Id ttl := DefaultTTL log.Debug("DNS: Handling response for id ", id, " content: ", msg.String()) this.Lock() request, found := this.requests[id] if !found { this.Unlock() return } delete(this.requests, id) this.Unlock() for _, rr := range msg.Answer { switch rr := rr.(type) { case *dns.A: record.IPs = append(record.IPs, rr.A) if rr.Hdr.Ttl < ttl { ttl = rr.Hdr.Ttl } case *dns.AAAA: record.IPs = append(record.IPs, rr.AAAA) if rr.Hdr.Ttl < ttl { ttl = rr.Hdr.Ttl } } } record.Expire = time.Now().Add(time.Second * time.Duration(ttl)) request.response <- record close(request.response) }
func (c *dnsCache) store(payload []byte) { resp := new(dns.Msg) e := resp.Unpack(payload) if e != nil { return } if resp.Rcode != dns.RcodeSuccess { return } if len(resp.Question) == 0 || len(resp.Answer) == 0 { return } c.mutex.Lock() defer c.mutex.Unlock() c.storage[cacheKey(resp.Question[0])] = &dnsCacheEntry{ msg: resp, exp: time.Now().Add(time.Duration(resp.Answer[0].Header().Ttl) * time.Second), } }
func (s *Session) on_dns(ft *FrameDns) (err error) { req := new(dns.Msg) err = req.Unpack(ft.Data) if err != nil { return ErrDnsMsgIllegal } if req.Response { // ignore send fail, maybe just timeout. // should I log this ? return s.sendFrameInChan(ft) } log.Info("dns query for %s.", req.Question[0].Name) d, ok := sutils.DefaultLookuper.(*sutils.DnsLookup) if !ok { return ErrNoDnsServer } res, err := d.Exchange(req) if err != nil { log.Error("%s", err.Error()) return nil } if DEBUGDNS { DebugDNS(res, req.Question[0].Name) } // send response back from streamid b, err := res.Pack() if err != nil { log.Error("%s", ErrDnsMsgIllegal.Error()) return nil } fr := NewFrameDns(ft.GetStreamid(), b) err = s.SendFrame(fr) return }
// Data receiving routine reads from connection, unpacks packets into dns.Msg // structures and sends them to a given msgCh channel func (c *client) recv(l *net.UDPConn, msgCh chan *dns.Msg) { if l == nil { return } buf := make([]byte, 65536) for !c.closed { n, _, err := l.ReadFrom(buf) if err != nil { continue } msg := new(dns.Msg) if err := msg.Unpack(buf[:n]); err != nil { log.Printf("[ERR] mdns: Failed to unpack packet: %v", err) continue } select { case msgCh <- msg: case <-c.closedCh: return } } }
func (c *dnsCache) query(payload []byte) *dns.Msg { request := new(dns.Msg) e := request.Unpack(payload) if e != nil { return nil } if len(request.Question) == 0 { return nil } c.mutex.Lock() defer c.mutex.Unlock() key := cacheKey(request.Question[0]) entry := c.storage[key] if entry == nil { return nil } if time.Now().After(entry.exp) { delete(c.storage, key) return nil } entry.msg.Id = request.Id return entry.msg }
func (this Server) tryDNSoverHTTP(w http.ResponseWriter, r *http.Request) { TransProString := r.Header.Get("Proxy-DNS-Transport") if TransProString == "" { TransProString = r.Header.Get("X-Proxy-DNS-Transport") } if TransProString == "" { msg := fmt.Sprintf("No transport protocol specified") _D("%s", msg) http.Error(w, msg, 415) return } if TransProString == "TCP" { this.TransPro = TCPcode } else if TransProString == "UDP" { this.TransPro = UDPcode } else { msg := fmt.Sprintf("Transport protocol not UDP or TCP: %s", TransProString) _D("%s", msg) http.Error(w, msg, 415) return } contentTypeStr := r.Header.Get("Content-Type") if contentTypeStr != "application/octet-stream" { msg := fmt.Sprintf("Unsupported content-type: '%s'", contentTypeStr) _D("%s", msg) http.Error(w, msg, 415) return } var requestBody []byte requestBody, err := ioutil.ReadAll(r.Body) if err != nil { msg := fmt.Sprintf("Error reading HTTP request: %s", err) _D("%s", msg) http.Error(w, msg, 400) return } if len(requestBody) < (int)(r.ContentLength) { msg := fmt.Sprintf("Error reading HTTP request: expected %d bytes but only read %d", (int)(r.ContentLength), len(requestBody)) _D("%s", msg) http.Error(w, msg, 400) return } var dnsRequest dns.Msg err = dnsRequest.Unpack(requestBody) if err != nil { msg := fmt.Sprintf("Error unpacking DNS message: %s", err) _D("%s", msg) http.Error(w, msg, 400) return } dnsResponse, err := DoDNSquery(dnsRequest, TransProString, this.SERVERS, this.timeout) if err != nil { msg := fmt.Sprintf("Error querying DNS resolver: %s", err) _D("%s", msg) http.Error(w, msg, 500) return } if dnsResponse == nil { msg := "Error querying DNS resolver: no response" _D("%s", msg) http.Error(w, msg, 500) return } response_bytes, err := dnsResponse.Pack() if err != nil { msg := fmt.Sprintf("Error converting DNS message to bytes: %s", err) _D("%s", msg) http.Error(w, msg, 500) return } _, err = w.Write(response_bytes) if err != nil { msg := fmt.Sprintf("Error writing HTTP response: %s", err) _D("%s", msg) return } }
func (w *Writer) Write(b []byte) (i int, err error) { r := new(dns.Msg) err = r.Unpack(b) w.ReplyCh <- r return }
func proxyServe(w dns.ResponseWriter, req *dns.Msg) { var ( key string m *dns.Msg err error tried bool data []byte id uint16 query []string questions []dns.Question used string ) defer func() { if err := recover(); err != nil { fmt.Println(err) } }() if req.MsgHdr.Response == true { // supposed responses sent to us are bogus return } query = make([]string, len(req.Question)) for i, q := range req.Question { if q.Qtype != dns.TypeAAAA || *ipv6 { questions = append(questions, q) } query[i] = fmt.Sprintf("(%s %s %s)", q.Name, dns.ClassToString[q.Qclass], dns.TypeToString[q.Qtype]) } if len(questions) == 0 { return } req.Question = questions id = req.Id req.Id = 0 key = toMd5(req.String()) req.Id = id if ENCACHE { if reply, ok := conn.Get(key); ok { data, _ = reply.([]byte) } if data != nil && len(data) > 0 { m = &dns.Msg{} m.Unpack(data) m.Id = id err = w.WriteMsg(m) if DEBUG > 0 { log.Printf("id: %5d cache: HIT %v\n", id, query) } goto end } else { if DEBUG > 0 { log.Printf("id: %5d cache: MISS %v\n", id, query) } } } for i, parts := range DNS { dns := parts[0] proto := parts[1] tried = i > 0 if DEBUG > 0 { if tried { log.Printf("id: %5d try: %v %s %s\n", id, query, dns, proto) } else { log.Printf("id: %5d resolve: %v %s %s\n", id, query, dns, proto) } } client := clientUDP if proto == "tcp" { client = clientTCP } m, _, err = client.Exchange(req, dns) if err == nil && len(m.Answer) > 0 { used = dns break } } if err == nil { if DEBUG > 0 { if tried { if len(m.Answer) == 0 { log.Printf("id: %5d failed: %v\n", id, query) } else { log.Printf("id: %5d bingo: %v %s\n", id, query, used) } } } data, err = m.Pack() if err == nil { _, err = w.Write(data) if err == nil { if ENCACHE { m.Id = 0 data, _ = m.Pack() ttl := 0 if len(m.Answer) > 0 { ttl = int(m.Answer[0].Header().Ttl) if ttl < 0 { ttl = 0 } } conn.Set(key, data, time.Second*time.Duration(ttl)) m.Id = id if DEBUG > 0 { log.Printf("id: %5d cache: CACHED %v TTL %v\n", id, query, ttl) } } } } } end: if DEBUG > 1 { fmt.Println(req) if m != nil { fmt.Println(m) } } if err != nil { log.Printf("id: %5d error: %v %s\n", id, query, err) } if DEBUG > 1 { fmt.Println("====================================================") } }
func dnschanDnsQuery(servers map[net.UDPAddr]*dnsServer, domain string, RecordChan chan *DnsRecord, ExitChan chan int) { select { case <-ExitChan: return default: } myexitChan := make(chan int) defer func() { close(myexitChan) }() // 打开端口 conn, err := net.ListenUDP("udp", nil) if err != nil { log.Printf("为dns请求打开udp失败,%v", err) return } defer conn.Close() conn.SetDeadline(time.Now().Add(5 * time.Second)) // dns 请求 m := new(dns.Msg) m.SetQuestion(dns.Fqdn(domain), dns.TypeA) m.RecursionDesired = true mData, err := m.Pack() if err != nil { log.Printf("生成dns请求包失败,%v", err) return } // 另开一个线程发出查询 go func() { for k, _ := range servers { if _, err := conn.WriteToUDP(mData, k); err != nil { log.Printf("向%v发送dns请求失败,%v", k, err) } } }() // 等待关闭 go func() { select { case <-ExitChan: case <-myexitChan: } conn.Close() }() // 接收查询结果并输入到信道 buf := make([]byte, 1500) for { n, addr, err := conn.ReadFromUDP(buf) if err != nil { return } nbuf := buf[:n] r := new(dns.Msg) if err := r.Unpack(nbuf); err != nil { log.Printf("解 DNS 包失败,%v", err) continue } if r.Id != m.Id { log.Printf("错误的dns id。") continue } v := servers[*addr] if v == nil { log.Printf("未知的服务器 %v 回应,忽略。", *addr) continue } for _, a := range r.Answer { dnsA, err := a.(*dns.A) if err != nil || dnsA == nil { log.Printf("内部错误,a=%v,err=%v", dnsA, err) } select { case RecordChan <- &DnsRecord{ Ip: dnsA.A.String(), Credit: v.Credit, }: case <-ExitChan: return } } } }
/* func (this ClientProxy) CreateHTTPClient() { if this.start_TLS == false { this.client = &http.Client{} } else { if this.TLS_Path == "" { tr := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, DisableCompression: true} this.client = &http.Client{Transport: tr} } else { pool := x509.NewCertPool() caCrt, err := ioutil.ReadFile(this.TLS_Path) if err != nil { _D("invalid cetificate path: %s", this.TLS_Path) return } pool.AppendCertsFromPEM(caCrt) tr := &http.Transport{ TLSClientConfig: &tls.Config{RootCAs: pool}, } this.client = &http.Client{Transport: tr} } } } */ func (this ClientProxy) ServeDNS(w dns.ResponseWriter, request *dns.Msg) { _LOG("get %s query from %s", request.Question[0].Name, w.RemoteAddr()) request_bytes, err := request.Pack() //I am not sure it is better to pack directly or using a pointer if err != nil { SRVFAIL(w, request) _D("error in packing request from %s for '%s', error message: %s", dns.ResponseWriter.RemoteAddr(w), request.Question[0].Name, err) return } ServerInput := this.SERVERS[rand.Intn(len(this.SERVERS))] ipaddress := net.ParseIP(ServerInput) var ServerInputurl string if this.start_TLS { //if it is TLS, use HTTPS if ipaddress.To4() != nil { ServerInputurl = "https://" + ServerInput } else { ServerInputurl = "https://[" + ServerInput + "]" } } else { if ipaddress.To4() != nil { ServerInputurl = "http://" + ServerInput } else { ServerInputurl = "http://[" + ServerInput + "]" } } postBytesReader := bytes.NewReader(request_bytes) ServerInputurl = ServerInputurl + "/proxy_dns" req, err := http.NewRequest("POST", ServerInputurl, postBytesReader) //need add random here in future if err != nil { SRVFAIL(w, request) _D("error in creating HTTP request from %s for '%s', error message: %s", dns.ResponseWriter.RemoteAddr(w), request.Question[0].Name, err) return } req.Header.Add("Host", ServerInput) req.Header.Add("Accept", "application/octet-stream") req.Header.Add("Content-Type", "application/octet-stream") if this.TransPro == UDPcode { req.Header.Add("Proxy-DNS-Transport", "UDP") } else if this.TransPro == TCPcode { req.Header.Add("Proxy-DNS-Transport", "TCP") } if this.start_TLS == false { //HTTP version tr := &http.Transport{ DisableKeepAlives: true, TLSNextProto: nil} this.client = &http.Client{Transport: tr} } else { //HTTPS version disabled certificate verification if this.TLS_Path == "" { tr := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, DisableCompression: true} this.client = &http.Client{Transport: tr} } else { //HTTPS version allow the certificate manually pool := x509.NewCertPool() caCrt, err := ioutil.ReadFile(this.TLS_Path) if err != nil { _D("invalid cetificate path: %s", this.TLS_Path) return } pool.AppendCertsFromPEM(caCrt) tr := &http.Transport{ TLSClientConfig: &tls.Config{RootCAs: pool}, } this.client = &http.Client{Transport: tr} } } resp, err := this.client.Do(req) if err != nil { SRVFAIL(w, request) _D("error in HTTP post request for query from %s for '%s', error message: %s", dns.ResponseWriter.RemoteAddr(w), request.Question[0].Name, err) return } if resp.StatusCode >= 500 { SRVFAIL(w, request) _D("HTTP ERROR: %s", http.StatusText(resp.StatusCode)) } var requestBody []byte requestBody, err = ioutil.ReadAll(resp.Body) // nRead, err := resp.Body.Read(requestBody) if err != nil { // these need to be separate checks, otherwise you will get a nil-reference // when you print the error message below! SRVFAIL(w, request) _D("error in reading HTTP response for query from %s for '%s', error message: %s", dns.ResponseWriter.RemoteAddr(w), request.Question[0].Name, err) return } //I not sure whether I should return server fail directly //I just found there is a bug here. Body.Read can not read all the contents out, I don't know how to solve it. if len(requestBody) < (int)(resp.ContentLength) { SRVFAIL(w, request) _D("failure reading all HTTP content for query from %s for '%s' (%d of %d bytes read)", dns.ResponseWriter.RemoteAddr(w), request.Question[0].Name, len(requestBody), (int)(resp.ContentLength)) return } var DNSreponse dns.Msg err = DNSreponse.Unpack(requestBody) if err != nil { SRVFAIL(w, request) _D("error in packing HTTP response for query from %s for '%s', error message: %s", dns.ResponseWriter.RemoteAddr(w), request.Question[0].Name, err) return } err = w.WriteMsg(&DNSreponse) if err != nil { _D("error in sending DNS response back for query from %s for '%s', error message: %s", dns.ResponseWriter.RemoteAddr(w), request.Question[0].Name, err) return } }
func yamlConvertMessage(m *Message, s *bytes.Buffer) { s.WriteString(fmt.Sprint(" type: ", m.Type, "\n")) if m.QueryTimeSec != nil && m.QueryTimeNsec != nil { t := time.Unix(int64(*m.QueryTimeSec), int64(*m.QueryTimeNsec)).UTC() s.WriteString(fmt.Sprint(" query_time: !!timestamp ", t.Format(yamlTimeFormat), "\n")) } if m.ResponseTimeSec != nil && m.ResponseTimeNsec != nil { t := time.Unix(int64(*m.ResponseTimeSec), int64(*m.ResponseTimeNsec)).UTC() s.WriteString(fmt.Sprint(" response_time: !!timestamp ", t.Format(yamlTimeFormat), "\n")) } if m.SocketFamily != nil { s.WriteString(fmt.Sprint(" socket_family: ", m.SocketFamily, "\n")) } if m.SocketProtocol != nil { s.WriteString(fmt.Sprint(" socket_protocol: ", m.SocketProtocol, "\n")) } if m.QueryAddress != nil { s.WriteString(fmt.Sprint(" query_address: ", net.IP(m.QueryAddress), "\n")) } if m.ResponseAddress != nil { s.WriteString(fmt.Sprint(" response_address: ", net.IP(m.ResponseAddress), "\n")) } if m.QueryPort != nil { s.WriteString(fmt.Sprint(" query_port: ", *m.QueryPort, "\n")) } if m.ResponsePort != nil { s.WriteString(fmt.Sprint(" response_port: ", *m.ResponsePort, "\n")) } if m.QueryZone != nil { name, _, err := dns.UnpackDomainName(m.QueryZone, 0) if err != nil { s.WriteString(" # query_zone: parse failed\n") } else { s.WriteString(fmt.Sprint(" query_zone: ", strconv.Quote(name), "\n")) } } if m.QueryMessage != nil { msg := new(dns.Msg) err := msg.Unpack(m.QueryMessage) if err != nil { s.WriteString(" # query_message: parse failed\n") } else { s.WriteString(" query_message: |\n") s.WriteString(" " + strings.Replace(strings.TrimSpace(msg.String()), "\n", "\n ", -1) + "\n") } } if m.ResponseMessage != nil { msg := new(dns.Msg) err := msg.Unpack(m.ResponseMessage) if err != nil { s.WriteString(fmt.Sprint(" # response_message: parse failed: ", err, "\n")) } else { s.WriteString(" response_message: |\n") s.WriteString(" " + strings.Replace(strings.TrimSpace(msg.String()), "\n", "\n ", -1) + "\n") } } s.WriteString("---\n") }
//not sure how to make a server fail, error 501? func (this Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { TransProString := r.Header.Get("Proxy-DNS-Transport") if TransProString == "TCP" { this.TransPro = TCPcode } else if TransProString == "UDP" { this.TransPro = UDPcode } else { _D("Transport protol not udp or tcp") http.Error(w, "Server Error: unknown transport protocol", 415) return } contentTypeStr := r.Header.Get("Content-Type") if contentTypeStr != "application/octet-stream" { _D("Content-Type illegal") http.Error(w, "Server Error: unknown content type", 415) return } var requestBody []byte requestBody, err := ioutil.ReadAll(r.Body) if err != nil { http.Error(w, "Server Error: error in reading request", 400) _D("error in reading HTTP request, error message: %s", err) return } if len(requestBody) < (int)(r.ContentLength) { http.Error(w, "Server Error: error in reading request", 400) _D("fail to read all HTTP content") return } var dnsRequest dns.Msg err = dnsRequest.Unpack(requestBody) if err != nil { http.Error(w, "Server Error: bad DNS request", 400) _D("error in packing HTTP response to DNS, error message: %s", err) return } /* dnsClient := new(dns.Client) if dnsClient == nil { http.Error(w, "Server Error", 500) _D("cannot create DNS client") return } dnsClient.ReadTimeout = this.timeout dnsClient.WriteTimeout = this.timeout dnsClient.Net = TransProString //will use a parameter to let user address resolver in future dnsResponse, RTT, err := dnsClient.Exchange(&dnsRequest, this.SERVERS[rand.Intn(len(this.SERVERS))]) //dnsResponse, RTT, err := dnsClient.Exchange(&dnsRequest, this.SERVERS[0]) if err != nil { _D("error in communicate with resolver, error message: %s", err) http.Error(w, "Server Error", 500) return } else { _D("request took %s", RTT) } if dnsResponse == nil { _D("no response back") http.Error(w, "Server Error:No Recursive response", 500) return }*/ dnsResponse, err := this.DoDNSquery(dnsRequest, TransProString, this.SERVERS, this.timeout) if err != nil { _D("error in communicate with resolver, error message: %s", err) http.Error(w, err.Error(), 500) return } if dnsResponse == nil { _D("no response back") http.Error(w, "Server Error:No Recursive response", 500) return } response_bytes, err := dnsResponse.Pack() if err != nil { http.Error(w, "Server Error: error packing reply", 500) _D("error in packing request, error message: %s", err) return } _, err = w.Write(response_bytes) if err != nil { _D("Can not write response rightly, error message: %s", err) return } //don't know how to creat a response here }
func textConvertMessage(m *Message, s *bytes.Buffer) { isQuery := false printQueryAddress := false switch *m.Type { case Message_CLIENT_QUERY, Message_RESOLVER_QUERY, Message_AUTH_QUERY, Message_FORWARDER_QUERY, Message_TOOL_QUERY: isQuery = true case Message_CLIENT_RESPONSE, Message_RESOLVER_RESPONSE, Message_AUTH_RESPONSE, Message_FORWARDER_RESPONSE, Message_TOOL_RESPONSE: isQuery = false default: s.WriteString("[unhandled Message.Type]\n") return } if isQuery { textConvertTime(s, m.QueryTimeSec, m.QueryTimeNsec) } else { textConvertTime(s, m.ResponseTimeSec, m.ResponseTimeNsec) } s.WriteString(" ") switch *m.Type { case Message_CLIENT_QUERY, Message_CLIENT_RESPONSE: { s.WriteString("C") } case Message_RESOLVER_QUERY, Message_RESOLVER_RESPONSE: { s.WriteString("R") } case Message_AUTH_QUERY, Message_AUTH_RESPONSE: { s.WriteString("A") } case Message_FORWARDER_QUERY, Message_FORWARDER_RESPONSE: { s.WriteString("F") } case Message_STUB_QUERY, Message_STUB_RESPONSE: { s.WriteString("S") } case Message_TOOL_QUERY, Message_TOOL_RESPONSE: { s.WriteString("T") } } if isQuery { s.WriteString("Q ") } else { s.WriteString("R ") } switch *m.Type { case Message_CLIENT_QUERY, Message_CLIENT_RESPONSE, Message_AUTH_QUERY, Message_AUTH_RESPONSE: printQueryAddress = true } if printQueryAddress { textConvertIP(s, m.QueryAddress) } else { textConvertIP(s, m.ResponseAddress) } s.WriteString(" ") if m.SocketProtocol != nil { s.WriteString(m.SocketProtocol.String()) } s.WriteString(" ") var err error msg := new(dns.Msg) if isQuery { s.WriteString(strconv.Itoa(len(m.QueryMessage))) s.WriteString("b ") err = msg.Unpack(m.QueryMessage) } else { s.WriteString(strconv.Itoa(len(m.ResponseMessage))) s.WriteString("b ") err = msg.Unpack(m.ResponseMessage) } if err != nil { s.WriteString("X ") } else { s.WriteString("\"" + msg.Question[0].Name + "\" ") s.WriteString(dns.Class(msg.Question[0].Qclass).String() + " ") s.WriteString(dns.Type(msg.Question[0].Qtype).String()) } s.WriteString("\n") }