Skip to content
This repository has been archived by the owner on Aug 22, 2021. It is now read-only.

How does the UdpGw daemon work? #121

Open
iMrDJAi opened this issue Apr 19, 2021 · 2 comments
Open

How does the UdpGw daemon work? #121

iMrDJAi opened this issue Apr 19, 2021 · 2 comments

Comments

@iMrDJAi
Copy link

iMrDJAi commented Apr 19, 2021

Hello, I'm trying to simulate the UdpGw layer with JavaScript, I'm stuck trying to figure out how to parse the received buffer and how to structure a response to the client, I need to do that in order to resolve the DNS requests.
I'm not sure how does it work. Is it forwarding all the UDP traffic? or just the DNS requests? Is it forwarding the DNS requests as it is? or just a raw DNS queries meant to be sent to a DNS server? Is the UdpGw daemon a UDP requests forwarder or a local DNS resolver?
I already tried creating a simple UDP server in order to listen to the UDP requests, and that's what I got:

var udp = require('dgram')
var server = udp.createSocket('udp6')

server.on('error', err => {
  error('Error: ' + err)
  server.close()
})
server.on('message', (msg, info) => {
  log('UDP: ' + msg.toString('hex') + '\n(' + msg.toString() + ')')
})
server.bind(1080, () => {
  log(`UDP server started on port 1080!`)
})

/** output:
UDP: 0000000108080808003517b8010000010000000000000377777706676f6f676c6503636f6d0000010001
(�����5�����www�google�com��)
**/

We can clearly see the domain "www.google.com" there, but I still not sure how to handle that correctly.

@iMrDJAi iMrDJAi changed the title How does UdpGw daemon work? How does the UdpGw daemon work? Apr 19, 2021
@iMrDJAi
Copy link
Author

iMrDJAi commented Apr 21, 2021

I found out that the received buffer actually contains a real DNS packet, but I noticed that the first 10 bytes are not a part of it:

console.log(Buffer.from('00000001080808080035', 'hex').toString())
// output => "\u0000\u0000\u0000\u0001\b\b\b\b\u00005"

It seems to be kind of a header, so I just cut it off, then I decoded it with a library called dns-packet:

console.log(dnsPacket.decode(Buffer.from("17b8010000010000000000000377777706676f6f676c6503636f6d0000010001", "hex")))
// output => {"id":6072,"type":"query","flags":256,"flag_qr":false,"opcode":"QUERY","flag_aa":false,"flag_tc":false,"flag_rd":true,"flag_ra":false,"flag_z":false,"flag_ad":false,"flag_cd":false,"rcode":"NOERROR","questions":[{"name":"www.google.com","type":"A","class":"IN"}],"answers":[],"authorities":[],"additionals":[]}

So I used the public Google DNS to resolve the DNS request, using the DNS-over-HTTPS API, then I forwarded the response buffer back to the client:

server.on('message', async (msg, info) => {
    var dnsMessage = msg.slice(10)
    fetch('https://8.8.8.8/dns-query', {
        method: 'POST',
        headers: {
            'content-type': 'application/dns-message',
        },
        body: dnsMessage
    }).then(res => res.buffer().then(buf => {
        server.send(buf, 0, buf.length, info.port, info.address)
    })).catch(err => {
        console.error(err)
    })
})

Now I'm getting an error on the client side:

udp_fd_handler: no address for DNS request id 0

And I'm stuck at this point, not sure what changes should I make to the response buffer before sending it back, @ambrop72 I need you to provide me more info on how to structure the response please.

@iMrDJAi
Copy link
Author

iMrDJAi commented Jun 9, 2021

I ended up using the actual UDP associate feature of SOCKS v5 (#71) to forward the DNS traffic. While this has worked fine, I couldn't find out how to re-implement the UdpGw daemon in JavaScript.

I'll keep this issue open for now, maybe someone in the future will provide an answer, in my opinion this remains an interesting topic for the community.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant