Forwarding Dns request with chan to make DNS Proxy

Hey guys,
I want to do dns proxy package to use in my another app. I will do it by changing dns server address. I will change it to and i will listen localhost when some apps request i will send request by using real wifi then i will transmit the dns respond to app on localhost.
I can send request on wifi and i can respond with dns server that runs on localhost but there are problems.
After i get dns respond packet i want to send it to dns server function with channels(at least i thought it could be like that) then dns server was going to respond app.
These the problems i thought:

  • If a request comes in, another request comes before the app responds, the chan changes and I can’t respond correctly
  • If a request comes, then I forward that request to the server but if there is no response, I cannot listen to other requests.

and there is my code:

func main() {
	server := &dns.Server{Addr: ":53", Net: "udp"}
	go server.ListenAndServe()
	dns.HandleFunc(".", handleRequest)


	select {}

I use miekg/dns package in there.
When request comes in handleRequest func will work
I listen wifi with ListenToWifi() func

func handleRequest(w dns.ResponseWriter, req *dns.Msg) {
	resp := new(dns.Msg)

	SendPacketFromLocalHost(req.Id, req.Question[0].Name)


func SendPacketFromLocalHost(id uint16, domain string) {
	// Open device
	handle, err := pcap.OpenLive(`\Device\NPF_Loopback`, 1024, false, 0)
	if err != nil {
	defer handle.Close()

	SendPacket(handle, id, domain)

func ListenToWifi() {
	// Open device
	handle, err := pcap.OpenLive(`\Device\NPF_{<Device-Hardw-Id>}`, 2048, false, 100*time.Millisecond)
	if err != nil {
	defer handle.Close()

	packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
	for packet := range packetSource.Packets() {
		// UDP Layer
		udpLayer := packet.Layer(layers.LayerTypeUDP)
		if udpLayer == nil {
		_, ok := udpLayer.(*layers.UDP)
		if !ok {

		// DNS Layer
		dnsLayer := packet.Layer(layers.LayerTypeDNS)
		if dnsLayer == nil {
		dns, ok := dnsLayer.(*layers.DNS)
		if !ok {

		domainName := string([]byte(dns.Questions[0].Name))

		log.Printf("%s 0x%x \n", domainName, dns.ID)

func SendPacket(handle *pcap.Handle, dnsID uint16, domainNames ...string) {
	// Used for loopback interface
	lo := layers.Loopback{
		Family: layers.ProtocolFamilyIPv4,

	// Create ip layer
	ip := layers.IPv4{
		Version:  4,
		TTL:      128,
		SrcIP:    net.IP{192, 168, 20, 55}, // router ip
		DstIP:    net.IP{192, 168, 20, 1}, // my ip
		Protocol: layers.IPProtocolUDP,

	// Create udp layer
	udp := layers.UDP{
		SrcPort: 65444,
		DstPort: 53,

	questions := []layers.DNSQuestion{}
	for _, d := range domainNames {
		qst := layers.DNSQuestion{
			Name:  []byte(d),
			Type:  layers.DNSTypeA,
			Class: layers.DNSClassIN,

		questions = append(questions, qst)

	dns := layers.DNS{
		BaseLayer:    layers.BaseLayer{},
		ID:           dnsID,
		QR:           false,
		OpCode:       0,
		AA:           false,
		TC:           false,
		RD:           true,
		RA:           true,
		Z:            0,
		ResponseCode: 0,
		QDCount:      1,
		ANCount:      0,
		NSCount:      0,
		ARCount:      0,
		Questions:    questions,

	buffer := gopacket.NewSerializeBuffer()
	options := gopacket.SerializeOptions{
		ComputeChecksums: true,
		FixLengths:       true,

	if err = gopacket.SerializeLayers(buffer, options,
	); err != nil {
		fmt.Printf("[-] Serialize error: %s\n", err.Error())
	outgoingPacket := buffer.Bytes()

	if err = handle.WritePacketData(outgoingPacket); err != nil {
		fmt.Printf("[-] Error while sending: %s\n", err.Error())

I thought that i was going to use chans and when a request comes in i was going to send domain name with channel in handleRequest() after i get response i was going to send response to app.

Do you know guys how can i achieve it?
thx for helping

It would help if you used a proxy server to export in this format. There are several proxies, including free, anonymous, and elite proxies. If your purpose in using proxies is to prevent your parsers from blocking sites, using is the best choice. You will become like the average user who does not know what a proxy for a site is. Moreover, an additional measure against purging is rotating user agents, in which you send a changing fake header each time, telling you that you are a regular browser.